From 9af7e27dd76894d7fbf88c79ac8e1676cf93052f Mon Sep 17 00:00:00 2001 From: Andrew Miller Date: Fri, 16 Mar 2012 18:47:36 -0400 Subject: Staging: rtl8187se: r8185b_init.c: Fixed spacing Removed unnecessary tabs, spaces, and blank lines. Signed-off-by: Andrew Miller Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c index 4b0b830..3c1ca69 100644 --- a/drivers/staging/rtl8187se/r8185b_init.c +++ b/drivers/staging/rtl8187se/r8185b_init.c @@ -10,7 +10,7 @@ Abstract: Major Change History: When Who What ---------- --------------- ------------------------------- - 2006-11-15 Xiong Created + 2006-11-15 Xiong Created Notes: This file is ported from RTL8185B Windows driver. @@ -33,87 +33,86 @@ Notes: #define TC_3W_POLL_MAX_TRY_CNT 5 static u8 MAC_REG_TABLE[][2] = { - /*PAGA 0: */ - /* 0x34(BRSR), 0xBE(RATE_FALLBACK_CTL), 0x1E0(ARFR) would set in HwConfigureRTL8185() */ - /* 0x272(RFSW_CTRL), 0x1CE(AESMSK_QC) set in InitializeAdapter8185(). */ - /* 0x1F0~0x1F8 set in MacConfig_85BASIC() */ - {0x08, 0xae}, {0x0a, 0x72}, {0x5b, 0x42}, - {0x84, 0x88}, {0x85, 0x24}, {0x88, 0x54}, {0x8b, 0xb8}, {0x8c, 0x03}, - {0x8d, 0x40}, {0x8e, 0x00}, {0x8f, 0x00}, {0x5b, 0x18}, {0x91, 0x03}, - {0x94, 0x0F}, {0x95, 0x32}, - {0x96, 0x00}, {0x97, 0x07}, {0xb4, 0x22}, {0xdb, 0x00}, - {0xf0, 0x32}, {0xf1, 0x32}, {0xf2, 0x00}, {0xf3, 0x00}, {0xf4, 0x32}, - {0xf5, 0x43}, {0xf6, 0x00}, {0xf7, 0x00}, {0xf8, 0x46}, {0xf9, 0xa4}, - {0xfa, 0x00}, {0xfb, 0x00}, {0xfc, 0x96}, {0xfd, 0xa4}, {0xfe, 0x00}, - {0xff, 0x00}, - - /*PAGE 1: */ - /* For Flextronics system Logo PCIHCT failure: */ - /* 0x1C4~0x1CD set no-zero value to avoid PCI configuration space 0x45[7]=1 */ - {0x5e, 0x01}, - {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x04}, {0x5b, 0x00}, {0x60, 0x24}, - {0x61, 0x97}, {0x62, 0xF0}, {0x63, 0x09}, {0x80, 0x0F}, {0x81, 0xFF}, - {0x82, 0xFF}, {0x83, 0x03}, - {0xC4, 0x22}, {0xC5, 0x22}, {0xC6, 0x22}, {0xC7, 0x22}, {0xC8, 0x22}, /* lzm add 080826 */ - {0xC9, 0x22}, {0xCA, 0x22}, {0xCB, 0x22}, {0xCC, 0x22}, {0xCD, 0x22},/* lzm add 080826 */ - {0xe2, 0x00}, - - - /* PAGE 2: */ - {0x5e, 0x02}, - {0x0c, 0x04}, {0x4c, 0x30}, {0x4d, 0x08}, {0x50, 0x05}, {0x51, 0xf5}, - {0x52, 0x04}, {0x53, 0xa0}, {0x54, 0xff}, {0x55, 0xff}, {0x56, 0xff}, - {0x57, 0xff}, {0x58, 0x08}, {0x59, 0x08}, {0x5a, 0x08}, {0x5b, 0x08}, - {0x60, 0x08}, {0x61, 0x08}, {0x62, 0x08}, {0x63, 0x08}, {0x64, 0x2f}, - {0x8c, 0x3f}, {0x8d, 0x3f}, {0x8e, 0x3f}, - {0x8f, 0x3f}, {0xc4, 0xff}, {0xc5, 0xff}, {0xc6, 0xff}, {0xc7, 0xff}, - {0xc8, 0x00}, {0xc9, 0x00}, {0xca, 0x80}, {0xcb, 0x00}, - - /* PAGA 0: */ - {0x5e, 0x00}, {0x9f, 0x03} + /*PAGA 0: */ + /* 0x34(BRSR), 0xBE(RATE_FALLBACK_CTL), 0x1E0(ARFR) would set in HwConfigureRTL8185() */ + /* 0x272(RFSW_CTRL), 0x1CE(AESMSK_QC) set in InitializeAdapter8185(). */ + /* 0x1F0~0x1F8 set in MacConfig_85BASIC() */ + {0x08, 0xae}, {0x0a, 0x72}, {0x5b, 0x42}, + {0x84, 0x88}, {0x85, 0x24}, {0x88, 0x54}, {0x8b, 0xb8}, {0x8c, 0x03}, + {0x8d, 0x40}, {0x8e, 0x00}, {0x8f, 0x00}, {0x5b, 0x18}, {0x91, 0x03}, + {0x94, 0x0F}, {0x95, 0x32}, + {0x96, 0x00}, {0x97, 0x07}, {0xb4, 0x22}, {0xdb, 0x00}, + {0xf0, 0x32}, {0xf1, 0x32}, {0xf2, 0x00}, {0xf3, 0x00}, {0xf4, 0x32}, + {0xf5, 0x43}, {0xf6, 0x00}, {0xf7, 0x00}, {0xf8, 0x46}, {0xf9, 0xa4}, + {0xfa, 0x00}, {0xfb, 0x00}, {0xfc, 0x96}, {0xfd, 0xa4}, {0xfe, 0x00}, + {0xff, 0x00}, + + /*PAGE 1: */ + /* For Flextronics system Logo PCIHCT failure: */ + /* 0x1C4~0x1CD set no-zero value to avoid PCI configuration space 0x45[7]=1 */ + {0x5e, 0x01}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x04}, {0x5b, 0x00}, {0x60, 0x24}, + {0x61, 0x97}, {0x62, 0xF0}, {0x63, 0x09}, {0x80, 0x0F}, {0x81, 0xFF}, + {0x82, 0xFF}, {0x83, 0x03}, + {0xC4, 0x22}, {0xC5, 0x22}, {0xC6, 0x22}, {0xC7, 0x22}, {0xC8, 0x22}, /* lzm add 080826 */ + {0xC9, 0x22}, {0xCA, 0x22}, {0xCB, 0x22}, {0xCC, 0x22}, {0xCD, 0x22}, /* lzm add 080826 */ + {0xe2, 0x00}, + + + /* PAGE 2: */ + {0x5e, 0x02}, + {0x0c, 0x04}, {0x4c, 0x30}, {0x4d, 0x08}, {0x50, 0x05}, {0x51, 0xf5}, + {0x52, 0x04}, {0x53, 0xa0}, {0x54, 0xff}, {0x55, 0xff}, {0x56, 0xff}, + {0x57, 0xff}, {0x58, 0x08}, {0x59, 0x08}, {0x5a, 0x08}, {0x5b, 0x08}, + {0x60, 0x08}, {0x61, 0x08}, {0x62, 0x08}, {0x63, 0x08}, {0x64, 0x2f}, + {0x8c, 0x3f}, {0x8d, 0x3f}, {0x8e, 0x3f}, + {0x8f, 0x3f}, {0xc4, 0xff}, {0xc5, 0xff}, {0xc6, 0xff}, {0xc7, 0xff}, + {0xc8, 0x00}, {0xc9, 0x00}, {0xca, 0x80}, {0xcb, 0x00}, + + /* PAGA 0: */ + {0x5e, 0x00}, {0x9f, 0x03} }; static u8 ZEBRA_AGC[] = { - 0, - 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, - 0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, - 0x48, 0x47, 0x46, 0x45, 0x44, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x08, 0x07, - 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x15, 0x16, - 0x17, 0x17, 0x18, 0x18, 0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e, - 0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x24, - 0x24, 0x25, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F - }; + 0, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, + 0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, + 0x48, 0x47, 0x46, 0x45, 0x44, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x08, 0x07, + 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x15, 0x16, + 0x17, 0x17, 0x18, 0x18, 0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e, + 0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x24, + 0x24, 0x25, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F + }; -static u32 ZEBRA_RF_RX_GAIN_TABLE[] = { - 0x0096, 0x0076, 0x0056, 0x0036, 0x0016, 0x01f6, 0x01d6, 0x01b6, - 0x0196, 0x0176, 0x00F7, 0x00D7, 0x00B7, 0x0097, 0x0077, 0x0057, - 0x0037, 0x00FB, 0x00DB, 0x00BB, 0x00FF, 0x00E3, 0x00C3, 0x00A3, - 0x0083, 0x0063, 0x0043, 0x0023, 0x0003, 0x01E3, 0x01C3, 0x01A3, - 0x0183, 0x0163, 0x0143, 0x0123, 0x0103 +static u32 ZEBRA_RF_RX_GAIN_TABLE[] = { + 0x0096, 0x0076, 0x0056, 0x0036, 0x0016, 0x01f6, 0x01d6, 0x01b6, + 0x0196, 0x0176, 0x00F7, 0x00D7, 0x00B7, 0x0097, 0x0077, 0x0057, + 0x0037, 0x00FB, 0x00DB, 0x00BB, 0x00FF, 0x00E3, 0x00C3, 0x00A3, + 0x0083, 0x0063, 0x0043, 0x0023, 0x0003, 0x01E3, 0x01C3, 0x01A3, + 0x0183, 0x0163, 0x0143, 0x0123, 0x0103 }; static u8 OFDM_CONFIG[] = { - /* OFDM reg0x06[7:0]=0xFF: Enable power saving mode in RX */ - /* OFDM reg0x3C[4]=1'b1: Enable RX power saving mode */ - /* ofdm 0x3a = 0x7b ,(original : 0xfb) For ECS shielding room TP test */ - - /* 0x00 */ - 0x10, 0x0F, 0x0A, 0x0C, 0x14, 0xFA, 0xFF, 0x50, - 0x00, 0x50, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00, - /* 0x10 */ - 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xA8, 0x26, - 0x32, 0x33, 0x06, 0xA5, 0x6F, 0x55, 0xC8, 0xBB, - /* 0x20 */ - 0x0A, 0xE1, 0x2C, 0x4A, 0x86, 0x83, 0x34, 0x00, - 0x4F, 0x24, 0x6F, 0xC2, 0x03, 0x40, 0x80, 0x00, - /* 0x30 */ - 0xC0, 0xC1, 0x58, 0xF1, 0x00, 0xC4, 0x90, 0x3e, - 0xD8, 0x3C, 0x7B, 0x10, 0x10 - }; - -/* --------------------------------------------------------------- + /* OFDM reg0x06[7:0]=0xFF: Enable power saving mode in RX */ + /* OFDM reg0x3C[4]=1'b1: Enable RX power saving mode */ + /* ofdm 0x3a = 0x7b ,(original : 0xfb) For ECS shielding room TP test */ + /* 0x00 */ + 0x10, 0x0F, 0x0A, 0x0C, 0x14, 0xFA, 0xFF, 0x50, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00, + /* 0x10 */ + 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xA8, 0x26, + 0x32, 0x33, 0x06, 0xA5, 0x6F, 0x55, 0xC8, 0xBB, + /* 0x20 */ + 0x0A, 0xE1, 0x2C, 0x4A, 0x86, 0x83, 0x34, 0x00, + 0x4F, 0x24, 0x6F, 0xC2, 0x03, 0x40, 0x80, 0x00, + /* 0x30 */ + 0xC0, 0xC1, 0x58, 0xF1, 0x00, 0xC4, 0x90, 0x3e, + 0xD8, 0x3C, 0x7B, 0x10, 0x10 + }; + + /*--------------------------------------------------------------- * Hardware IO * the code is ported from Windows source code ----------------------------------------------------------------*/ @@ -126,7 +125,7 @@ PlatformIOWrite1Byte( ) { write_nic_byte(dev, offset, data); - read_nic_byte(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */ + read_nic_byte(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */ } @@ -152,12 +151,12 @@ PlatformIOWrite4Byte( ) { /* {by amy 080312 */ -if (offset == PhyAddr) { -/* For Base Band configuration. */ + if (offset == PhyAddr) { + /* For Base Band configuration. */ unsigned char cmdByte; unsigned long dataBytes; unsigned char idx; - u8 u1bTmp; + u8 u1bTmp; cmdByte = (u8)(data & 0x000000ff); dataBytes = data>>8; @@ -170,10 +169,10 @@ if (offset == PhyAddr) { acquiring the spinlock in such context. 2. PlatformIOWrite4Byte() MUST NOT be recursive. */ -/* NdisAcquireSpinLock( &(pDevice->IoSpinLock) ); */ + /* NdisAcquireSpinLock( &(pDevice->IoSpinLock) ); */ for (idx = 0; idx < 30; idx++) { - /* Make sure command bit is clear before access it. */ + /* Make sure command bit is clear before access it. */ u1bTmp = PlatformIORead1Byte(dev, PhyAddr); if ((u1bTmp & BIT7) == 0) break; @@ -186,7 +185,7 @@ if (offset == PhyAddr) { write_nic_byte(dev, offset, cmdByte); -/* NdisReleaseSpinLock( &(pDevice->IoSpinLock) ); */ + /* NdisReleaseSpinLock( &(pDevice->IoSpinLock) ); */ } /* by amy 080312} */ else { @@ -275,10 +274,10 @@ HwHSSIThreeWire( u1bTmp = read_nic_byte(dev, RF_SW_CONFIG); if (bSI) - u1bTmp |= RF_SW_CFG_SI; /* reg08[1]=1 Serial Interface(SI) */ + u1bTmp |= RF_SW_CFG_SI; /* reg08[1]=1 Serial Interface(SI) */ else - u1bTmp &= ~RF_SW_CFG_SI; /* reg08[1]=0 Parallel Interface(PI) */ + u1bTmp &= ~RF_SW_CFG_SI; /* reg08[1]=0 Parallel Interface(PI) */ write_nic_byte(dev, RF_SW_CONFIG, u1bTmp); @@ -326,7 +325,7 @@ HwHSSIThreeWire( } } else { /* read */ if (bSI) { - /* SI - reg274[3:0] : RF register's Address */ + /* SI - reg274[3:0] : RF register's Address */ write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf)); } else { /* PI - reg274[15:12] : RF register's Address */ @@ -343,7 +342,7 @@ HwHSSIThreeWire( /* Check if DONE is set. */ - for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) { + for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) { u1bTmp = read_nic_byte(dev, SW_3W_CMD1); if ((u1bTmp & SW_3W_CMD1_DONE) != 0) break; @@ -353,7 +352,7 @@ HwHSSIThreeWire( write_nic_byte(dev, SW_3W_CMD1, 0); - /* Read back data for read operation. */ + /* Read back data for read operation. */ if (bWrite == 0) { if (bSI) { /* Serial Interface : reg363_362[11:0] */ @@ -443,9 +442,9 @@ ReadBBPortUchar( */ bool SetAntennaConfig87SE( - struct net_device *dev, - u8 DefaultAnt, /* 0: Main, 1: Aux. */ - bool bAntDiversity /* 1:Enable, 0: Disable. */ + struct net_device *dev, + u8 DefaultAnt, /* 0: Main, 1: Aux. */ + bool bAntDiversity /* 1:Enable, 0: Disable. */ ) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); @@ -453,48 +452,48 @@ SetAntennaConfig87SE( /* printk("SetAntennaConfig87SE(): DefaultAnt(%d), bAntDiversity(%d)\n", DefaultAnt, bAntDiversity); */ - /* Threshold for antenna diversity. */ + /* Threshold for antenna diversity. */ write_phy_cck(dev, 0x0c, 0x09); /* Reg0c : 09 */ - if (bAntDiversity) { /* Enable Antenna Diversity. */ - if (DefaultAnt == 1) { /* aux antenna */ + if (bAntDiversity) { /* Enable Antenna Diversity. */ + if (DefaultAnt == 1) { /* aux antenna */ - /* Mac register, aux antenna */ + /* Mac register, aux antenna */ write_nic_byte(dev, ANTSEL, 0x00); - /* Config CCK RX antenna. */ + /* Config CCK RX antenna. */ write_phy_cck(dev, 0x11, 0xbb); /* Reg11 : bb */ write_phy_cck(dev, 0x01, 0xc7); /* Reg01 : c7 */ - /* Config OFDM RX antenna. */ - write_phy_ofdm(dev, 0x0D, 0x54); /* Reg0d : 54 */ - write_phy_ofdm(dev, 0x18, 0xb2); /* Reg18 : b2 */ - } else { /* use main antenna */ - /* Mac register, main antenna */ + /* Config OFDM RX antenna. */ + write_phy_ofdm(dev, 0x0D, 0x54); /* Reg0d : 54 */ + write_phy_ofdm(dev, 0x18, 0xb2); /* Reg18 : b2 */ + } else { /* use main antenna */ + /* Mac register, main antenna */ write_nic_byte(dev, ANTSEL, 0x03); - /* base band */ - /* Config CCK RX antenna. */ - write_phy_cck(dev, 0x11, 0x9b); /* Reg11 : 9b */ - write_phy_cck(dev, 0x01, 0xc7); /* Reg01 : c7 */ + /* base band */ + /* Config CCK RX antenna. */ + write_phy_cck(dev, 0x11, 0x9b); /* Reg11 : 9b */ + write_phy_cck(dev, 0x01, 0xc7); /* Reg01 : c7 */ /* Config OFDM RX antenna. */ write_phy_ofdm(dev, 0x0d, 0x5c); /* Reg0d : 5c */ write_phy_ofdm(dev, 0x18, 0xb2); /* Reg18 : b2 */ } - } else { + } else { /* Disable Antenna Diversity. */ - if (DefaultAnt == 1) { /* aux Antenna */ + if (DefaultAnt == 1) { /* aux Antenna */ /* Mac register, aux antenna */ write_nic_byte(dev, ANTSEL, 0x00); /* Config CCK RX antenna. */ - write_phy_cck(dev, 0x11, 0xbb); /* Reg11 : bb */ - write_phy_cck(dev, 0x01, 0x47); /* Reg01 : 47 */ + write_phy_cck(dev, 0x11, 0xbb); /* Reg11 : bb */ + write_phy_cck(dev, 0x01, 0x47); /* Reg01 : 47 */ /* Config OFDM RX antenna. */ - write_phy_ofdm(dev, 0x0D, 0x54); /* Reg0d : 54 */ - write_phy_ofdm(dev, 0x18, 0x32); /* Reg18 : 32 */ - } else { /* main Antenna */ + write_phy_ofdm(dev, 0x0D, 0x54); /* Reg0d : 54 */ + write_phy_ofdm(dev, 0x18, 0x32); /* Reg18 : 32 */ + } else { /* main Antenna */ /* Mac register, main antenna */ write_nic_byte(dev, ANTSEL, 0x03); @@ -502,9 +501,9 @@ SetAntennaConfig87SE( write_phy_cck(dev, 0x11, 0x9b); /* Reg11 : 9b */ write_phy_cck(dev, 0x01, 0x47); /* Reg01 : 47 */ - /* Config OFDM RX antenna. */ - write_phy_ofdm(dev, 0x0D, 0x5c); /* Reg0d : 5c */ - write_phy_ofdm(dev, 0x18, 0x32); /*Reg18 : 32 */ + /* Config OFDM RX antenna. */ + write_phy_ofdm(dev, 0x0D, 0x5c); /* Reg0d : 5c */ + write_phy_ofdm(dev, 0x18, 0x32); /*Reg18 : 32 */ } } priv->CurrAntennaIndex = DefaultAnt; /* Update default settings. */ @@ -539,140 +538,128 @@ ZEBRA_Config_85BASIC_HardCode( /* Page1 : reg16-reg30 */ - RF_WriteReg(dev, 0x00, 0x013f); mdelay(1); /* switch to page1 */ - u4bRF23 = RF_ReadReg(dev, 0x08); mdelay(1); - u4bRF24 = RF_ReadReg(dev, 0x09); mdelay(1); + RF_WriteReg(dev, 0x00, 0x013f); mdelay(1); /* switch to page1 */ + u4bRF23 = RF_ReadReg(dev, 0x08); mdelay(1); + u4bRF24 = RF_ReadReg(dev, 0x09); mdelay(1); if (u4bRF23 == 0x818 && u4bRF24 == 0x70C) { d_cut = 1; printk(KERN_INFO "rtl8187se: card type changed from C- to D-cut\n"); } - /* Page0 : reg0-reg15 */ - - RF_WriteReg(dev, 0x00, 0x009f); mdelay(1);/* 1 */ - - RF_WriteReg(dev, 0x01, 0x06e0); mdelay(1); - - RF_WriteReg(dev, 0x02, 0x004d); mdelay(1);/* 2 */ - - RF_WriteReg(dev, 0x03, 0x07f1); mdelay(1);/* 3 */ - - RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); - RF_WriteReg(dev, 0x05, 0x0c72); mdelay(1); - RF_WriteReg(dev, 0x06, 0x0ae6); mdelay(1); - RF_WriteReg(dev, 0x07, 0x00ca); mdelay(1); - RF_WriteReg(dev, 0x08, 0x0e1c); mdelay(1); - RF_WriteReg(dev, 0x09, 0x02f0); mdelay(1); - RF_WriteReg(dev, 0x0a, 0x09d0); mdelay(1); - RF_WriteReg(dev, 0x0b, 0x01ba); mdelay(1); - RF_WriteReg(dev, 0x0c, 0x0640); mdelay(1); - RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1); - RF_WriteReg(dev, 0x0e, 0x0020); mdelay(1); - RF_WriteReg(dev, 0x0f, 0x0990); mdelay(1); - + /* Page0 : reg0-reg15 */ + + RF_WriteReg(dev, 0x00, 0x009f); mdelay(1);/* 1 */ + RF_WriteReg(dev, 0x01, 0x06e0); mdelay(1); + RF_WriteReg(dev, 0x02, 0x004d); mdelay(1);/* 2 */ + RF_WriteReg(dev, 0x03, 0x07f1); mdelay(1);/* 3 */ + RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); + RF_WriteReg(dev, 0x05, 0x0c72); mdelay(1); + RF_WriteReg(dev, 0x06, 0x0ae6); mdelay(1); + RF_WriteReg(dev, 0x07, 0x00ca); mdelay(1); + RF_WriteReg(dev, 0x08, 0x0e1c); mdelay(1); + RF_WriteReg(dev, 0x09, 0x02f0); mdelay(1); + RF_WriteReg(dev, 0x0a, 0x09d0); mdelay(1); + RF_WriteReg(dev, 0x0b, 0x01ba); mdelay(1); + RF_WriteReg(dev, 0x0c, 0x0640); mdelay(1); + RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1); + RF_WriteReg(dev, 0x0e, 0x0020); mdelay(1); + RF_WriteReg(dev, 0x0f, 0x0990); mdelay(1); /* Page1 : reg16-reg30 */ - RF_WriteReg(dev, 0x00, 0x013f); mdelay(1); - - RF_WriteReg(dev, 0x03, 0x0806); mdelay(1); - - RF_WriteReg(dev, 0x04, 0x03a7); mdelay(1); - RF_WriteReg(dev, 0x05, 0x059b); mdelay(1); - RF_WriteReg(dev, 0x06, 0x0081); mdelay(1); - - - RF_WriteReg(dev, 0x07, 0x01A0); mdelay(1); + RF_WriteReg(dev, 0x00, 0x013f); mdelay(1); + RF_WriteReg(dev, 0x03, 0x0806); mdelay(1); + RF_WriteReg(dev, 0x04, 0x03a7); mdelay(1); + RF_WriteReg(dev, 0x05, 0x059b); mdelay(1); + RF_WriteReg(dev, 0x06, 0x0081); mdelay(1); + RF_WriteReg(dev, 0x07, 0x01A0); mdelay(1); /* Don't write RF23/RF24 to make a difference between 87S C cut and D cut. asked by SD3 stevenl. */ - RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1); - RF_WriteReg(dev, 0x0b, 0x0418); mdelay(1); + RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1); + RF_WriteReg(dev, 0x0b, 0x0418); mdelay(1); if (d_cut) { - RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1); - RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); - RF_WriteReg(dev, 0x0e, 0x0807); mdelay(1); /* RX LO buffer */ - } else { - RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1); - RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); - RF_WriteReg(dev, 0x0e, 0x0806); mdelay(1); /* RX LO buffer */ + RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1); + RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); + RF_WriteReg(dev, 0x0e, 0x0807); mdelay(1); /* RX LO buffer */ + } else { + RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1); + RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); + RF_WriteReg(dev, 0x0e, 0x0806); mdelay(1); /* RX LO buffer */ } - RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1); - - RF_WriteReg(dev, 0x00, 0x01d7); mdelay(1); /* 6 */ + RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1); + RF_WriteReg(dev, 0x00, 0x01d7); mdelay(1); /* 6 */ + RF_WriteReg(dev, 0x03, 0x0e00); mdelay(1); + RF_WriteReg(dev, 0x04, 0x0e50); mdelay(1); - RF_WriteReg(dev, 0x03, 0x0e00); mdelay(1); - RF_WriteReg(dev, 0x04, 0x0e50); mdelay(1); - for (i = 0; i <= 36; i++) { - RF_WriteReg(dev, 0x01, i); mdelay(1); + for (i = 0; i <= 36; i++) { + RF_WriteReg(dev, 0x01, i); mdelay(1); RF_WriteReg(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1); } - RF_WriteReg(dev, 0x05, 0x0203); mdelay(1); /* 203, 343 */ - RF_WriteReg(dev, 0x06, 0x0200); mdelay(1); /* 400 */ + RF_WriteReg(dev, 0x05, 0x0203); mdelay(1); /* 203, 343 */ + RF_WriteReg(dev, 0x06, 0x0200); mdelay(1); /* 400 */ + RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); /* switch to reg16-reg30, and HSSI disable 137 */ + mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); /* switch to reg16-reg30, and HSSI disable 137 */ - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ + RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); /* Z4 synthesizer loop filter setting, 392 */ + mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); /* Z4 synthesizer loop filter setting, 392 */ - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ + RF_WriteReg(dev, 0x00, 0x0037); mdelay(1); /* switch to reg0-reg15, and HSSI disable */ + mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - RF_WriteReg(dev, 0x00, 0x0037); mdelay(1); /* switch to reg0-reg15, and HSSI disable */ - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ + RF_WriteReg(dev, 0x04, 0x0160); mdelay(1); /* CBC on, Tx Rx disable, High gain */ + mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - RF_WriteReg(dev, 0x04, 0x0160); mdelay(1); /* CBC on, Tx Rx disable, High gain */ - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ + RF_WriteReg(dev, 0x07, 0x0080); mdelay(1); /* Z4 setted channel 1 */ + mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - RF_WriteReg(dev, 0x07, 0x0080); mdelay(1); /* Z4 setted channel 1 */ - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ + RF_WriteReg(dev, 0x02, 0x088D); mdelay(1); /* LC calibration */ + mdelay(200); /* Deay 200 ms. */ /* 0xfd */ + mdelay(10); /* Deay 10 ms. */ /* 0xfd */ + mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - RF_WriteReg(dev, 0x02, 0x088D); mdelay(1); /* LC calibration */ - mdelay(200); /* Deay 200 ms. */ /* 0xfd */ - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ + RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); /* switch to reg16-reg30 137, and HSSI disable 137 */ + mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); /* switch to reg16-reg30 137, and HSSI disable 137 */ - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - - RF_WriteReg(dev, 0x07, 0x0000); mdelay(1); - RF_WriteReg(dev, 0x07, 0x0180); mdelay(1); - RF_WriteReg(dev, 0x07, 0x0220); mdelay(1); - RF_WriteReg(dev, 0x07, 0x03E0); mdelay(1); + RF_WriteReg(dev, 0x07, 0x0000); mdelay(1); + RF_WriteReg(dev, 0x07, 0x0180); mdelay(1); + RF_WriteReg(dev, 0x07, 0x0220); mdelay(1); + RF_WriteReg(dev, 0x07, 0x03E0); mdelay(1); /* DAC calibration off 20070702 */ - RF_WriteReg(dev, 0x06, 0x00c1); mdelay(1); - RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1); + RF_WriteReg(dev, 0x06, 0x00c1); mdelay(1); + RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1); /* {by amy 080312 */ /* For crystal calibration, added by Roger, 2007.12.11. */ - if (priv->bXtalCalibration) { /* reg 30. */ + if (priv->bXtalCalibration) { /* reg 30. */ /* enable crystal calibration. RF Reg[30], (1)Xin:[12:9], Xout:[8:5], addr[4:0]. (2)PA Pwr delay timer[15:14], default: 2.4us, set BIT15=0 (3)RF signal on/off when calibration[13], default: on, set BIT13=0. - So we should minus 4 BITs offset. */ - RF_WriteReg(dev, 0x0f, (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | BIT11 | BIT9); mdelay(1); + So we should minus 4 BITs offset. */ + RF_WriteReg(dev, 0x0f, (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | BIT11 | BIT9); mdelay(1); printk("ZEBRA_Config_85BASIC_HardCode(): (%02x)\n", - (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | BIT11 | BIT9); - } else { + (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | BIT11 | BIT9); + } else { /* using default value. Xin=6, Xout=6. */ - RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1); + RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1); } /* by amy 080312 */ - RF_WriteReg(dev, 0x00, 0x00bf); mdelay(1); /* switch to reg0-reg15, and HSSI enable */ - RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1); /* Rx BB start calibration, 00c//+edward */ - RF_WriteReg(dev, 0x02, 0x004d); mdelay(1); /* temperature meter off */ - RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); /* Rx mode */ + RF_WriteReg(dev, 0x00, 0x00bf); mdelay(1); /* switch to reg0-reg15, and HSSI enable */ + RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1); /* Rx BB start calibration, 00c//+edward */ + RF_WriteReg(dev, 0x02, 0x004d); mdelay(1); /* temperature meter off */ + RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); /* Rx mode */ mdelay(10); /* Deay 10 ms.*/ /* 0xfe */ mdelay(10); /* Deay 10 ms.*/ /* 0xfe */ mdelay(10); /* Deay 10 ms.*/ /* 0xfe */ - RF_WriteReg(dev, 0x00, 0x0197); mdelay(1); /* Rx mode*/ /*+edward */ - RF_WriteReg(dev, 0x05, 0x05ab); mdelay(1); /* Rx mode*/ /*+edward */ - RF_WriteReg(dev, 0x00, 0x009f); mdelay(1); /* Rx mode*/ /*+edward */ - - RF_WriteReg(dev, 0x01, 0x0000); mdelay(1); /* Rx mode*/ /*+edward */ - RF_WriteReg(dev, 0x02, 0x0000); mdelay(1); /* Rx mode*/ /*+edward */ - /* power save parameters. */ + RF_WriteReg(dev, 0x00, 0x0197); mdelay(1); /* Rx mode*/ /*+edward */ + RF_WriteReg(dev, 0x05, 0x05ab); mdelay(1); /* Rx mode*/ /*+edward */ + RF_WriteReg(dev, 0x00, 0x009f); mdelay(1); /* Rx mode*/ /*+edward */ + RF_WriteReg(dev, 0x01, 0x0000); mdelay(1); /* Rx mode*/ /*+edward */ + RF_WriteReg(dev, 0x02, 0x0000); mdelay(1); /* Rx mode*/ /*+edward */ + /* power save parameters. */ u1b24E = read_nic_byte(dev, 0x24E); write_nic_byte(dev, 0x24E, (u1b24E & (~(BIT5|BIT6)))); @@ -697,7 +684,7 @@ ZEBRA_Config_85BASIC_HardCode( write_phy_cck(dev, 0x2f, 0x06); write_phy_cck(dev, 0x01, 0x46); - /* power control */ + /* power control */ write_nic_byte(dev, CCK_TXAGC, 0x10); write_nic_byte(dev, OFDM_TXAGC, 0x1B); write_nic_byte(dev, ANTSEL, 0x03); @@ -712,7 +699,7 @@ ZEBRA_Config_85BASIC_HardCode( write_phy_ofdm(dev, 0x00, 0x12); - for (i = 0; i < 128; i++) { + for (i = 0; i < 128; i++) { data = ZEBRA_AGC[i+1]; data = data << 8; @@ -737,14 +724,14 @@ ZEBRA_Config_85BASIC_HardCode( ============================================================================= */ - for (i = 0; i < 60; i++) { + for (i = 0; i < 60; i++) { u4bRegOffset = i; u4bRegValue = OFDM_CONFIG[i]; WriteBBPortUchar(dev, - (0x00000080 | - (u4bRegOffset & 0x7f) | - ((u4bRegValue & 0xff) << 8))); + (0x00000080 | + (u4bRegOffset & 0x7f) | + ((u4bRegValue & 0xff) << 8))); } /* @@ -768,7 +755,7 @@ UpdateInitialGain( struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); /* lzm add 080826 */ - if (priv->eRFPowerState != eRfOn) { + if (priv->eRFPowerState != eRfOn) { /* Don't access BB/RF under disable PLL situation. RT_TRACE(COMP_DIG, DBG_LOUD, ("UpdateInitialGain - pHalData->eRFPowerState!=eRfOn\n")); Back to the original state @@ -826,7 +813,7 @@ UpdateInitialGain( write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1); break; - default: /* MP */ + default: /* MP */ write_phy_ofdm(dev, 0x17, 0x26); mdelay(1); write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1); @@ -863,7 +850,7 @@ PhyConfig8185( ZEBRA_Config_85BASIC_HardCode(dev); /* {by amy 080312 */ /* Set default initial gain state to 4, approved by SD3 DZ, by Bruce, 2007-06-06. */ - if (priv->bDigMechanism) { + if (priv->bDigMechanism) { if (priv->InitialGain == 0) priv->InitialGain = 4; } @@ -889,11 +876,11 @@ HwConfigureRTL8185( ) { /* RTL8185_TODO: Determine Retrylimit, TxAGC, AutoRateFallback control. */ - u8 bUNIVERSAL_CONTROL_RL = 0; - u8 bUNIVERSAL_CONTROL_AGC = 1; - u8 bUNIVERSAL_CONTROL_ANT = 1; - u8 bAUTO_RATE_FALLBACK_CTL = 1; - u8 val8; + u8 bUNIVERSAL_CONTROL_RL = 0; + u8 bUNIVERSAL_CONTROL_AGC = 1; + u8 bUNIVERSAL_CONTROL_ANT = 1; + u8 bAUTO_RATE_FALLBACK_CTL = 1; + u8 val8; write_nic_word(dev, BRSR, 0x0fff); /* Retry limit */ val8 = read_nic_byte(dev, CW_CONF); @@ -907,24 +894,24 @@ HwConfigureRTL8185( /* Tx AGC */ val8 = read_nic_byte(dev, TXAGC_CTL); - if (bUNIVERSAL_CONTROL_AGC) { + if (bUNIVERSAL_CONTROL_AGC) { write_nic_byte(dev, CCK_TXAGC, 128); write_nic_byte(dev, OFDM_TXAGC, 128); val8 = val8 & 0xfe; - } else { + } else { val8 = val8 | 0x01 ; } write_nic_byte(dev, TXAGC_CTL, val8); - /* Tx Antenna including Feedback control */ + /* Tx Antenna including Feedback control */ val8 = read_nic_byte(dev, TXAGC_CTL); - if (bUNIVERSAL_CONTROL_ANT) { + if (bUNIVERSAL_CONTROL_ANT) { write_nic_byte(dev, ANTSEL, 0x00); val8 = val8 & 0xfd; - } else { + } else { val8 = val8 & (val8|0x02); /* xiong-2006-11-15 */ } @@ -933,7 +920,7 @@ HwConfigureRTL8185( /* Auto Rate fallback control */ val8 = read_nic_byte(dev, RATE_FALLBACK); val8 &= 0x7c; - if (bAUTO_RATE_FALLBACK_CTL) { + if (bAUTO_RATE_FALLBACK_CTL) { val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP1; /* We shall set up the ARFR according to user's setting. */ @@ -951,22 +938,20 @@ MacConfig_85BASIC_HardCode( MACREG.TXT ============================================================================ */ - int nLinesRead = 0; - - u32 u4bRegOffset, u4bRegValue, u4bPageIndex = 0; - int i; + int nLinesRead = 0; + u32 u4bRegOffset, u4bRegValue, u4bPageIndex = 0; + int i; nLinesRead = sizeof(MAC_REG_TABLE)/2; - for (i = 0; i < nLinesRead; i++) { /* nLinesRead=101 */ + for (i = 0; i < nLinesRead; i++) { /* nLinesRead=101 */ u4bRegOffset = MAC_REG_TABLE[i][0]; u4bRegValue = MAC_REG_TABLE[i][1]; if (u4bRegOffset == 0x5e) u4bPageIndex = u4bRegValue; - else - u4bRegOffset |= (u4bPageIndex << 8); + u4bRegOffset |= (u4bPageIndex << 8); write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue); } @@ -994,18 +979,18 @@ MacConfig_85BASIC( PlatformIOWrite4Byte(dev, 0x1F4, 0x00000000); PlatformIOWrite1Byte(dev, 0x1F8, 0x00); - /* Asked for by SD3 CM Lin, 2006.06.27, by rcnjko. */ - /* power save parameter based on "87SE power save parameters 20071127.doc", as follow. */ + /* Asked for by SD3 CM Lin, 2006.06.27, by rcnjko. */ + /* power save parameter based on "87SE power save parameters 20071127.doc", as follow. */ /* Enable DA10 TX power saving */ u1DA = read_nic_byte(dev, PHYPR); write_nic_byte(dev, PHYPR, (u1DA | BIT2)); - /* POWER: */ + /* POWER: */ write_nic_word(dev, 0x360, 0x1000); write_nic_word(dev, 0x362, 0x1000); - /* AFE. */ + /* AFE. */ write_nic_word(dev, 0x370, 0x0560); write_nic_word(dev, 0x372, 0x0560); write_nic_word(dev, 0x374, 0x0DA4); @@ -1013,7 +998,7 @@ MacConfig_85BASIC( write_nic_word(dev, 0x378, 0x0560); write_nic_word(dev, 0x37A, 0x0560); write_nic_word(dev, 0x37C, 0x00EC); - write_nic_word(dev, 0x37E, 0x00EC); /*+edward */ + write_nic_word(dev, 0x37E, 0x00EC); /* +edward */ write_nic_byte(dev, 0x24E, 0x01); } @@ -1022,7 +1007,7 @@ GetSupportedWirelessMode8185( struct net_device *dev ) { - u8 btSupportedWirelessMode = 0; + u8 btSupportedWirelessMode = 0; btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G); return btSupportedWirelessMode; @@ -1035,12 +1020,12 @@ ActUpdateChannelAccessSetting( PCHANNEL_ACCESS_SETTING ChnlAccessSetting ) { - struct r8180_priv *priv = ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee80211; + struct r8180_priv *priv = ieee80211_priv(dev); + struct ieee80211_device *ieee = priv->ieee80211; AC_CODING eACI; AC_PARAM AcParam; - u8 bFollowLegacySetting = 0; - u8 u1bAIFS; + u8 bFollowLegacySetting = 0; + u8 u1bAIFS; /* @@ -1053,14 +1038,14 @@ ActUpdateChannelAccessSetting( even in nQBss. */ ChnlAccessSetting->SIFS_Timer = 0x22; /* Suggested by Jong, 2005.12.08. */ - ChnlAccessSetting->DIFS_Timer = 0x1C; /* 2006.06.02, by rcnjko. */ - ChnlAccessSetting->SlotTimeTimer = 9; /* 2006.06.02, by rcnjko. */ - ChnlAccessSetting->EIFS_Timer = 0x5B; /* Suggested by wcchu, it is the default value of EIFS register, 2005.12.08. */ - ChnlAccessSetting->CWminIndex = 3; /* 2006.06.02, by rcnjko. */ - ChnlAccessSetting->CWmaxIndex = 7; /* 2006.06.02, by rcnjko. */ + ChnlAccessSetting->DIFS_Timer = 0x1C; /* 2006.06.02, by rcnjko. */ + ChnlAccessSetting->SlotTimeTimer = 9; /* 2006.06.02, by rcnjko. */ + ChnlAccessSetting->EIFS_Timer = 0x5B; /* Suggested by wcchu, it is the default value of EIFS register, 2005.12.08. */ + ChnlAccessSetting->CWminIndex = 3; /* 2006.06.02, by rcnjko. */ + ChnlAccessSetting->CWmaxIndex = 7; /* 2006.06.02, by rcnjko. */ write_nic_byte(dev, SIFS, ChnlAccessSetting->SIFS_Timer); - write_nic_byte(dev, SLOT, ChnlAccessSetting->SlotTimeTimer); /* Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29. */ + write_nic_byte(dev, SLOT, ChnlAccessSetting->SlotTimeTimer); /* Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29. */ u1bAIFS = aSifsTime + (2 * ChnlAccessSetting->SlotTimeTimer); @@ -1074,7 +1059,7 @@ ActUpdateChannelAccessSetting( } /* this setting is copied from rtl8187B. xiong-2006-11-13 */ - if (bFollowLegacySetting) { + if (bFollowLegacySetting) { /* Follow 802.11 seeting to AC parameter, all AC shall use the same parameter. @@ -1083,8 +1068,8 @@ ActUpdateChannelAccessSetting( AcParam.longData = 0; AcParam.f.AciAifsn.f.AIFSN = 2; /* Follow 802.11 DIFS. */ AcParam.f.AciAifsn.f.ACM = 0; - AcParam.f.Ecw.f.ECWmin = ChnlAccessSetting->CWminIndex; /* Follow 802.11 CWmin. */ - AcParam.f.Ecw.f.ECWmax = ChnlAccessSetting->CWmaxIndex; /* Follow 802.11 CWmax. */ + AcParam.f.Ecw.f.ECWmin = ChnlAccessSetting->CWminIndex; /* Follow 802.11 CWmin. */ + AcParam.f.Ecw.f.ECWmax = ChnlAccessSetting->CWmaxIndex; /* Follow 802.11 CWmax. */ AcParam.f.TXOPLimit = 0; /* lzm reserved 080826 */ @@ -1095,7 +1080,7 @@ ActUpdateChannelAccessSetting( if (ieee->iw_mode == IW_MODE_ADHOC) AcParam.f.TXOPLimit = 0x0020; - for (eACI = 0; eACI < AC_MAX; eACI++) { + for (eACI = 0; eACI < AC_MAX; eACI++) { AcParam.f.AciAifsn.f.ACI = (u8)eACI; { PAC_PARAM pAcParam = (PAC_PARAM)(&AcParam); @@ -1111,7 +1096,7 @@ ActUpdateChannelAccessSetting( (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) | (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET)); - switch (eACI) { + switch (eACI) { case AC1_BK: /* write_nic_dword(dev, AC_BK_PARAM, u4bAcParam); */ break; @@ -1133,47 +1118,47 @@ ActUpdateChannelAccessSetting( break; } - /* Cehck ACM bit. */ + /* Cehck ACM bit. */ /* If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13. */ { PACI_AIFSN pAciAifsn = (PACI_AIFSN)(&pAcParam->f.AciAifsn); AC_CODING eACI = pAciAifsn->f.ACI; - /*modified Joseph */ - /*for 8187B AsynIORead issue */ + /*modified Joseph */ + /*for 8187B AsynIORead issue */ u8 AcmCtrl = 0; - if (pAciAifsn->f.ACM) { + if (pAciAifsn->f.ACM) { /* ACM bit is 1. */ - switch (eACI) { + switch (eACI) { case AC0_BE: - AcmCtrl |= (BEQ_ACM_EN|BEQ_ACM_CTL|ACM_HW_EN); /* or 0x21 */ + AcmCtrl |= (BEQ_ACM_EN|BEQ_ACM_CTL|ACM_HW_EN); /* or 0x21 */ break; case AC2_VI: - AcmCtrl |= (VIQ_ACM_EN|VIQ_ACM_CTL|ACM_HW_EN); /* or 0x42 */ + AcmCtrl |= (VIQ_ACM_EN|VIQ_ACM_CTL|ACM_HW_EN); /* or 0x42 */ break; case AC3_VO: - AcmCtrl |= (VOQ_ACM_EN|VOQ_ACM_CTL|ACM_HW_EN); /* or 0x84 */ + AcmCtrl |= (VOQ_ACM_EN|VOQ_ACM_CTL|ACM_HW_EN); /* or 0x84 */ break; default: DMESGW("SetHwReg8185(): [HW_VAR_ACM_CTRL] ACM set failed: eACI is %d\n", eACI); break; } - } else { + } else { /* ACM bit is 0. */ - switch (eACI) { + switch (eACI) { case AC0_BE: - AcmCtrl &= ((~BEQ_ACM_EN) & (~BEQ_ACM_CTL) & (~ACM_HW_EN)); /* and 0xDE */ + AcmCtrl &= ((~BEQ_ACM_EN) & (~BEQ_ACM_CTL) & (~ACM_HW_EN)); /* and 0xDE */ break; case AC2_VI: - AcmCtrl &= ((~VIQ_ACM_EN) & (~VIQ_ACM_CTL) & (~ACM_HW_EN)); /* and 0xBD */ + AcmCtrl &= ((~VIQ_ACM_EN) & (~VIQ_ACM_CTL) & (~ACM_HW_EN)); /* and 0xBD */ break; case AC3_VO: - AcmCtrl &= ((~VOQ_ACM_EN) & (~VOQ_ACM_CTL) & (~ACM_HW_EN)); /* and 0x7B */ + AcmCtrl &= ((~VOQ_ACM_EN) & (~VOQ_ACM_CTL) & (~ACM_HW_EN)); /* and 0x7B */ break; default: @@ -1193,30 +1178,30 @@ ActSetWirelessMode8185( u8 btWirelessMode ) { - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee80211; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct ieee80211_device *ieee = priv->ieee80211; u8 btSupportedWirelessMode = GetSupportedWirelessMode8185(dev); if ((btWirelessMode & btSupportedWirelessMode) == 0) { - /* Don't switch to unsupported wireless mode, 2006.02.15, by rcnjko. */ + /* Don't switch to unsupported wireless mode, 2006.02.15, by rcnjko. */ DMESGW("ActSetWirelessMode8185(): WirelessMode(%d) is not supported (%d)!\n", btWirelessMode, btSupportedWirelessMode); return; } - /* 1. Assign wireless mode to swtich if necessary. */ - if (btWirelessMode == WIRELESS_MODE_AUTO) { - if ((btSupportedWirelessMode & WIRELESS_MODE_A)) { + /* 1. Assign wireless mode to swtich if necessary. */ + if (btWirelessMode == WIRELESS_MODE_AUTO) { + if ((btSupportedWirelessMode & WIRELESS_MODE_A)) { btWirelessMode = WIRELESS_MODE_A; - } else if (btSupportedWirelessMode & WIRELESS_MODE_G) { + } else if (btSupportedWirelessMode & WIRELESS_MODE_G) { btWirelessMode = WIRELESS_MODE_G; - } else if ((btSupportedWirelessMode & WIRELESS_MODE_B)) { - btWirelessMode = WIRELESS_MODE_B; - } else { - DMESGW("ActSetWirelessMode8185(): No valid wireless mode supported, btSupportedWirelessMode(%x)!!!\n", - btSupportedWirelessMode); + } else if ((btSupportedWirelessMode & WIRELESS_MODE_B)) { btWirelessMode = WIRELESS_MODE_B; + } else { + DMESGW("ActSetWirelessMode8185(): No valid wireless mode supported, btSupportedWirelessMode(%x)!!!\n", + btSupportedWirelessMode); + btWirelessMode = WIRELESS_MODE_B; } } @@ -1227,13 +1212,13 @@ ActSetWirelessMode8185( ieee->mode = (WIRELESS_MODE)btWirelessMode; - /* 3. Change related setting. */ - if( ieee->mode == WIRELESS_MODE_A ) { + /* 3. Change related setting. */ + if( ieee->mode == WIRELESS_MODE_A ) { DMESG("WIRELESS_MODE_A\n"); - } else if( ieee->mode == WIRELESS_MODE_B ) { - DMESG("WIRELESS_MODE_B\n"); - } else if( ieee->mode == WIRELESS_MODE_G ) { - DMESG("WIRELESS_MODE_G\n"); + } else if( ieee->mode == WIRELESS_MODE_B ) { + DMESG("WIRELESS_MODE_B\n"); + } else if( ieee->mode == WIRELESS_MODE_G ) { + DMESG("WIRELESS_MODE_G\n"); } ActUpdateChannelAccessSetting( dev, ieee->mode, &priv->ChannelAccessSetting); } @@ -1260,7 +1245,7 @@ MgntDisconnectIBSS( ) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - u8 i; + u8 i; DrvIFIndicateDisassociation(dev, unspec_reason); @@ -1295,19 +1280,16 @@ MlmeDisassociateRequest( SendDisassociation(priv->ieee80211, asSta, asRsn); - if (memcmp(priv->ieee80211->current_network.bssid, asSta, 6) == 0) { - /*ShuChen TODO: change media status. */ - /*ShuChen TODO: What to do when disassociate. */ + if (memcmp(priv->ieee80211->current_network.bssid, asSta, 6) == 0) { + /* ShuChen TODO: change media status. */ + /* ShuChen TODO: What to do when disassociate. */ DrvIFIndicateDisassociation(dev, unspec_reason); - - for (i = 0; i < 6; i++) priv->ieee80211->current_network.bssid[i] = 0x22; ieee80211_disassociate(priv->ieee80211); } - } void @@ -1343,17 +1325,17 @@ MgntDisconnect( if (IS_DOT11D_ENABLE(priv->ieee80211)) Dot11d_Reset(priv->ieee80211); - /* In adhoc mode, update beacon frame. */ + /* In adhoc mode, update beacon frame. */ if (priv->ieee80211->state == IEEE80211_LINKED) { if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) MgntDisconnectIBSS(dev); - if (priv->ieee80211->iw_mode == IW_MODE_INFRA) { + if (priv->ieee80211->iw_mode == IW_MODE_INFRA) { /* We clear key here instead of MgntDisconnectAP() because that MgntActSet_802_11_DISASSOCIATE() is an interface called by OS, e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is used to handle disassociation related things to AP, e.g. send Disassoc - frame to AP. 2005.01.27, by rcnjko. */ + frame to AP. 2005.01.27, by rcnjko. */ MgntDisconnectAP(dev, asRsn); } /* Inidicate Disconnect, 2005.02.23, by rcnjko. */ @@ -1374,13 +1356,13 @@ SetRFPowerState( RT_RF_POWER_STATE eRFPowerState ) { - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - bool bResult = false; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + bool bResult = false; if (eRFPowerState == priv->eRFPowerState) return bResult; - bResult = SetZebraRFPowerState8185(dev, eRFPowerState); + bResult = SetZebraRFPowerState8185(dev, eRFPowerState); return bResult; } @@ -1404,11 +1386,11 @@ MgntActSet_RF_State( u32 ChangeSource ) { - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - bool bActionAllowed = false; - bool bConnectBySSID = false; - RT_RF_POWER_STATE rtState; - u16 RFWaitCounter = 0; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + bool bActionAllowed = false; + bool bConnectBySSID = false; + RT_RF_POWER_STATE rtState; + u16 RFWaitCounter = 0; unsigned long flag; /* Prevent the race condition of RF state change. By Bruce, 2007-11-28. @@ -1416,21 +1398,21 @@ MgntActSet_RF_State( */ while (true) { spin_lock_irqsave(&priv->rf_ps_lock, flag); - if (priv->RFChangeInProgress) { + if (priv->RFChangeInProgress) { spin_unlock_irqrestore(&priv->rf_ps_lock, flag); /* Set RF after the previous action is done. */ - while (priv->RFChangeInProgress) { + while (priv->RFChangeInProgress) { RFWaitCounter++; udelay(1000); /* 1 ms */ - /* Wait too long, return FALSE to avoid to be stuck here. */ - if (RFWaitCounter > 1000) { /* 1sec */ + /* Wait too long, return FALSE to avoid to be stuck here. */ + if (RFWaitCounter > 1000) { /* 1sec */ printk("MgntActSet_RF_State(): Wait too long to set RF\n"); - /* TODO: Reset RF state? */ + /* TODO: Reset RF state? */ return false; } } - } else { + } else { priv->RFChangeInProgress = true; spin_unlock_irqrestore(&priv->rf_ps_lock, flag); break; @@ -1438,7 +1420,7 @@ MgntActSet_RF_State( } rtState = priv->eRFPowerState; - switch (StateToSet) { + switch (StateToSet) { case eRfOn: /* Turn On RF no matter the IPS setting because we need to update the RF state to Ndis under Vista, or @@ -1453,25 +1435,24 @@ MgntActSet_RF_State( if (rtState == eRfOff && ChangeSource >= RF_CHANGE_BY_HW && !priv->bInHctTest) bConnectBySSID = true; - } else - ; + } else + ; break; case eRfOff: - /* 070125, rcnjko: we always keep connected in AP mode. */ - - if (priv->RfOffReason > RF_CHANGE_BY_IPS) { - /* - 060808, Annie: - Disconnect to current BSS when radio off. Asked by QuanTa. - - Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(), - because we do NOT need to set ssid to dummy ones. - */ - MgntDisconnect(dev, disas_lv_ss); - - /* Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI. */ - } + /* 070125, rcnjko: we always keep connected in AP mode. */ + + if (priv->RfOffReason > RF_CHANGE_BY_IPS) { + /* + 060808, Annie: + Disconnect to current BSS when radio off. Asked by QuanTa. + + Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(), + because we do NOT need to set ssid to dummy ones. + */ + MgntDisconnect(dev, disas_lv_ss); + /* Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI. */ + } priv->RfOffReason |= ChangeSource; bActionAllowed = true; @@ -1484,14 +1465,14 @@ MgntActSet_RF_State( break; } - if (bActionAllowed) { - /* Config HW to the specified mode. */ + if (bActionAllowed) { + /* Config HW to the specified mode. */ SetRFPowerState(dev, StateToSet); /* Turn on RF. */ - if (StateToSet == eRfOn) { + if (StateToSet == eRfOn) { HalEnableRx8185Dummy(dev); - if (bConnectBySSID) { + if (bConnectBySSID) { /* by amy not supported */ } } @@ -1542,7 +1523,7 @@ IPSEnter( { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); RT_RF_POWER_STATE rtState; - if (priv->bInactivePs) { + if (priv->bInactivePs) { rtState = priv->eRFPowerState; /* @@ -1554,7 +1535,7 @@ IPSEnter( (5) AP mode (send Beacon) */ if (rtState == eRfOn && !priv->bSwRfProcessing - && (priv->ieee80211->state != IEEE80211_LINKED)) { + && (priv->ieee80211->state != IEEE80211_LINKED)) { priv->eInactivePowerState = eRfOff; InactivePowerSave(dev); } @@ -1567,9 +1548,9 @@ IPSLeave( { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); RT_RF_POWER_STATE rtState; - if (priv->bInactivePs) { + if (priv->bInactivePs) { rtState = priv->eRFPowerState; - if ((rtState == eRfOff || rtState == eRfSleep) && (!priv->bSwRfProcessing) && priv->RfOffReason <= RF_CHANGE_BY_IPS) { + if ((rtState == eRfOff || rtState == eRfSleep) && (!priv->bSwRfProcessing) && priv->RfOffReason <= RF_CHANGE_BY_IPS) { priv->eInactivePowerState = eRfOn; InactivePowerSave(dev); } @@ -1582,8 +1563,8 @@ void rtl8185b_adapter_start(struct net_device *dev) struct ieee80211_device *ieee = priv->ieee80211; u8 SupportedWirelessMode; - u8 InitWirelessMode; - u8 bInvalidWirelessMode = 0; + u8 InitWirelessMode; + u8 bInvalidWirelessMode = 0; u8 tmpu8; u8 btCR9346; u8 TmpU1b; @@ -1598,14 +1579,14 @@ void rtl8185b_adapter_start(struct net_device *dev) HwConfigureRTL8185(dev); write_nic_dword(dev, MAC0, ((u32 *)dev->dev_addr)[0]); write_nic_word(dev, MAC4, ((u32 *)dev->dev_addr)[1] & 0xffff); - write_nic_byte(dev, MSR, read_nic_byte(dev, MSR) & 0xf3); /* default network type to 'No Link' */ + write_nic_byte(dev, MSR, read_nic_byte(dev, MSR) & 0xf3); /* default network type to 'No Link' */ write_nic_word(dev, BcnItv, 100); write_nic_word(dev, AtimWnd, 2); PlatformIOWrite2Byte(dev, FEMR, 0xFFFF); write_nic_byte(dev, WPA_CONFIG, 0); MacConfig_85BASIC(dev); - /* Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07, by rcnjko. */ - /* BT_DEMO_BOARD type */ + /* Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07, by rcnjko. */ + /* BT_DEMO_BOARD type */ PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x569a); /* @@ -1613,41 +1594,41 @@ void rtl8185b_adapter_start(struct net_device *dev) Set up PHY related. ----------------------------------------------------------------------------- */ - /* Enable Config3.PARAM_En to revise AnaaParm. */ - write_nic_byte(dev, CR9346, 0xc0); /* enable config register write */ + /* Enable Config3.PARAM_En to revise AnaaParm. */ + write_nic_byte(dev, CR9346, 0xc0); /* enable config register write */ tmpu8 = read_nic_byte(dev, CONFIG3); write_nic_byte(dev, CONFIG3, (tmpu8 | CONFIG3_PARM_En)); - /* Turn on Analog power. */ - /* Asked for by William, otherwise, MAC 3-wire can't work, 2006.06.27, by rcnjko. */ + /* Turn on Analog power. */ + /* Asked for by William, otherwise, MAC 3-wire can't work, 2006.06.27, by rcnjko. */ write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON); write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON); write_nic_word(dev, ANAPARAM3, 0x0010); write_nic_byte(dev, CONFIG3, tmpu8); write_nic_byte(dev, CR9346, 0x00); - /* enable EEM0 and EEM1 in 9346CR */ + /* enable EEM0 and EEM1 in 9346CR */ btCR9346 = read_nic_byte(dev, CR9346); write_nic_byte(dev, CR9346, (btCR9346 | 0xC0)); - /* B cut use LED1 to control HW RF on/off */ + /* B cut use LED1 to control HW RF on/off */ TmpU1b = read_nic_byte(dev, CONFIG5); TmpU1b = TmpU1b & ~BIT3; write_nic_byte(dev, CONFIG5, TmpU1b); - /* disable EEM0 and EEM1 in 9346CR */ + /* disable EEM0 and EEM1 in 9346CR */ btCR9346 &= ~(0xC0); write_nic_byte(dev, CR9346, btCR9346); - /* Enable Led (suggested by Jong) */ - /* B-cut RF Radio on/off 5e[3]=0 */ + /* Enable Led (suggested by Jong) */ + /* B-cut RF Radio on/off 5e[3]=0 */ btPSR = read_nic_byte(dev, PSR); write_nic_byte(dev, PSR, (btPSR | BIT3)); - /* setup initial timing for RFE. */ + /* setup initial timing for RFE. */ write_nic_word(dev, RFPinsOutput, 0x0480); SetOutputEnableOfRfPins(dev); write_nic_word(dev, RFPinsSelect, 0x2488); - /* PHY config. */ + /* PHY config. */ PhyConfig8185(dev); /* @@ -1659,28 +1640,28 @@ void rtl8185b_adapter_start(struct net_device *dev) if ((ieee->mode != WIRELESS_MODE_B) && (ieee->mode != WIRELESS_MODE_G) && (ieee->mode != WIRELESS_MODE_A) && - (ieee->mode != WIRELESS_MODE_AUTO)) { - /* It should be one of B, G, A, or AUTO. */ + (ieee->mode != WIRELESS_MODE_AUTO)) { + /* It should be one of B, G, A, or AUTO. */ bInvalidWirelessMode = 1; - } else { - /* One of B, G, A, or AUTO. */ - /* Check if the wireless mode is supported by RF. */ + } else { + /* One of B, G, A, or AUTO. */ + /* Check if the wireless mode is supported by RF. */ if ((ieee->mode != WIRELESS_MODE_AUTO) && - (ieee->mode & SupportedWirelessMode) == 0) { + (ieee->mode & SupportedWirelessMode) == 0) { bInvalidWirelessMode = 1; } } - if (bInvalidWirelessMode || ieee->mode == WIRELESS_MODE_AUTO) { - /* Auto or other invalid value. */ - /* Assigne a wireless mode to initialize. */ - if ((SupportedWirelessMode & WIRELESS_MODE_A)) { + if (bInvalidWirelessMode || ieee->mode == WIRELESS_MODE_AUTO) { + /* Auto or other invalid value. */ + /* Assigne a wireless mode to initialize. */ + if ((SupportedWirelessMode & WIRELESS_MODE_A)) { InitWirelessMode = WIRELESS_MODE_A; - } else if ((SupportedWirelessMode & WIRELESS_MODE_G)) { + } else if ((SupportedWirelessMode & WIRELESS_MODE_G)) { InitWirelessMode = WIRELESS_MODE_G; - } else if ((SupportedWirelessMode & WIRELESS_MODE_B)) { + } else if ((SupportedWirelessMode & WIRELESS_MODE_B)) { InitWirelessMode = WIRELESS_MODE_B; - } else { + } else { DMESGW("InitializeAdapter8185(): No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", SupportedWirelessMode); InitWirelessMode = WIRELESS_MODE_B; @@ -1690,11 +1671,11 @@ void rtl8185b_adapter_start(struct net_device *dev) if (bInvalidWirelessMode) ieee->mode = (WIRELESS_MODE)InitWirelessMode; - } else { - /* One of B, G, A. */ + } else { + /* One of B, G, A. */ InitWirelessMode = ieee->mode; } -/* by amy for power save */ +/* by amy for power save */ priv->eRFPowerState = eRfOff; priv->RfOffReason = 0; { @@ -1706,7 +1687,7 @@ void rtl8185b_adapter_start(struct net_device *dev) if (priv->bInactivePs) MgntActSet_RF_State(dev , eRfOff, RF_CHANGE_BY_IPS); -/* by amy for power save */ +/* by amy for power save */ ActSetWirelessMode8185(dev, (u8)(InitWirelessMode)); @@ -1715,7 +1696,7 @@ void rtl8185b_adapter_start(struct net_device *dev) rtl8185b_irq_enable(dev); netif_start_queue(dev); - } +} void rtl8185b_rx_enable(struct net_device *dev) { @@ -1728,7 +1709,7 @@ void rtl8185b_rx_enable(struct net_device *dev) DMESG("NIC in promisc mode"); if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || \ - dev->flags & IFF_PROMISC) { + dev->flags & IFF_PROMISC) { priv->ReceiveConfig = priv->ReceiveConfig & (~RCR_APM); priv->ReceiveConfig = priv->ReceiveConfig | RCR_AAP; } -- cgit v0.10.2 From 3d2ec48ee4934bc046da1ce0ac65ef98b2b8516c Mon Sep 17 00:00:00 2001 From: Andrew Miller Date: Fri, 16 Mar 2012 18:47:37 -0400 Subject: Staging: rtl8187se: r8185b_init.c: Fix function declarations Reformated the function declarations Signed-off-by: Andrew Miller Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c index 3c1ca69..5650ef1 100644 --- a/drivers/staging/rtl8187se/r8185b_init.c +++ b/drivers/staging/rtl8187se/r8185b_init.c @@ -117,24 +117,14 @@ static u8 OFDM_CONFIG[] = { * the code is ported from Windows source code ----------------------------------------------------------------*/ -void -PlatformIOWrite1Byte( - struct net_device *dev, - u32 offset, - u8 data - ) +void PlatformIOWrite1Byte(struct net_device *dev, u32 offset, u8 data) { write_nic_byte(dev, offset, data); read_nic_byte(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */ } -void -PlatformIOWrite2Byte( - struct net_device *dev, - u32 offset, - u16 data - ) +void PlatformIOWrite2Byte(struct net_device *dev, u32 offset, u16 data) { write_nic_word(dev, offset, data); read_nic_word(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */ @@ -143,12 +133,7 @@ PlatformIOWrite2Byte( } u8 PlatformIORead1Byte(struct net_device *dev, u32 offset); -void -PlatformIOWrite4Byte( - struct net_device *dev, - u32 offset, - u32 data - ) +void PlatformIOWrite4Byte(struct net_device *dev, u32 offset, u32 data) { /* {by amy 080312 */ if (offset == PhyAddr) { @@ -194,11 +179,7 @@ PlatformIOWrite4Byte( } } -u8 -PlatformIORead1Byte( - struct net_device *dev, - u32 offset - ) +u8 PlatformIORead1Byte(struct net_device *dev, u32 offset) { u8 data = 0; @@ -208,11 +189,7 @@ PlatformIORead1Byte( return data; } -u16 -PlatformIORead2Byte( - struct net_device *dev, - u32 offset - ) +u16 PlatformIORead2Byte(struct net_device *dev, u32 offset) { u16 data = 0; @@ -222,11 +199,7 @@ PlatformIORead2Byte( return data; } -u32 -PlatformIORead4Byte( - struct net_device *dev, - u32 offset - ) +u32 PlatformIORead4Byte(struct net_device *dev, u32 offset) { u32 data = 0; @@ -241,14 +214,11 @@ void SetOutputEnableOfRfPins(struct net_device *dev) write_nic_word(dev, RFPinsEnable, 0x1bff); } -static int -HwHSSIThreeWire( - struct net_device *dev, - u8 *pDataBuf, - u8 nDataBufBitCnt, - int bSI, - int bWrite - ) +static int HwHSSIThreeWire(struct net_device *dev, + u8 *pDataBuf, + u8 nDataBufBitCnt, + int bSI, + int bWrite) { int bResult = 1; u8 TryCnt; @@ -370,8 +340,7 @@ HwHSSIThreeWire( return bResult; } -void -RF_WriteReg(struct net_device *dev, u8 offset, u32 data) +void RF_WriteReg(struct net_device *dev, u8 offset, u32 data) { u32 data2Write; u8 len; @@ -399,11 +368,7 @@ u32 RF_ReadReg(struct net_device *dev, u8 offset) /* by Owen on 04/07/14 for writing BB register successfully */ -void -WriteBBPortUchar( - struct net_device *dev, - u32 Data - ) +void WriteBBPortUchar(struct net_device *dev, u32 Data) { /* u8 TimeoutCounter; */ u8 RegisterContent; @@ -420,11 +385,7 @@ WriteBBPortUchar( } } -u8 -ReadBBPortUchar( - struct net_device *dev, - u32 addr - ) +u8 ReadBBPortUchar(struct net_device *dev, u32 addr) { /*u8 TimeoutCounter; */ u8 RegisterContent; @@ -440,12 +401,9 @@ ReadBBPortUchar( Perform Antenna settings with antenna diversity on 87SE. Created by Roger, 2008.01.25. */ -bool -SetAntennaConfig87SE( - struct net_device *dev, - u8 DefaultAnt, /* 0: Main, 1: Aux. */ - bool bAntDiversity /* 1:Enable, 0: Disable. */ -) +bool SetAntennaConfig87SE(struct net_device *dev, + u8 DefaultAnt, /* 0: Main, 1: Aux. */ + bool bAntDiversity) /* 1:Enable, 0: Disable. */ { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); bool bAntennaSwitched = true; @@ -516,10 +474,7 @@ SetAntennaConfig87SE( * the code is ported from Windows source code ----------------------------------------------------------------*/ -void -ZEBRA_Config_85BASIC_HardCode( - struct net_device *dev - ) +void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); @@ -747,10 +702,7 @@ ZEBRA_Config_85BASIC_HardCode( } -void -UpdateInitialGain( - struct net_device *dev - ) +void UpdateInitialGain(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); @@ -825,10 +777,7 @@ UpdateInitialGain( Tx Power tracking mechanism routine on 87SE. Created by Roger, 2007.12.11. */ -void -InitTxPwrTracking87SE( - struct net_device *dev -) +void InitTxPwrTracking87SE(struct net_device *dev) { u32 u4bRfReg; @@ -838,10 +787,7 @@ InitTxPwrTracking87SE( RF_WriteReg(dev, 0x02, u4bRfReg|PWR_METER_EN); mdelay(1); } -void -PhyConfig8185( - struct net_device *dev - ) +void PhyConfig8185(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); write_nic_dword(dev, RCR, priv->ReceiveConfig); @@ -870,10 +816,7 @@ PhyConfig8185( return; } -void -HwConfigureRTL8185( - struct net_device *dev - ) +void HwConfigureRTL8185(struct net_device *dev) { /* RTL8185_TODO: Determine Retrylimit, TxAGC, AutoRateFallback control. */ u8 bUNIVERSAL_CONTROL_RL = 0; @@ -929,9 +872,7 @@ HwConfigureRTL8185( write_nic_byte(dev, RATE_FALLBACK, val8); } -static void -MacConfig_85BASIC_HardCode( - struct net_device *dev) +static void MacConfig_85BASIC_HardCode(struct net_device *dev) { /* ============================================================================ @@ -958,9 +899,7 @@ MacConfig_85BASIC_HardCode( /* ============================================================================ */ } -static void -MacConfig_85BASIC( - struct net_device *dev) +static void MacConfig_85BASIC(struct net_device *dev) { u8 u1DA; @@ -1002,10 +941,7 @@ MacConfig_85BASIC( write_nic_byte(dev, 0x24E, 0x01); } -u8 -GetSupportedWirelessMode8185( - struct net_device *dev -) +u8 GetSupportedWirelessMode8185(struct net_device *dev) { u8 btSupportedWirelessMode = 0; @@ -1013,12 +949,9 @@ GetSupportedWirelessMode8185( return btSupportedWirelessMode; } -void -ActUpdateChannelAccessSetting( - struct net_device *dev, - WIRELESS_MODE WirelessMode, - PCHANNEL_ACCESS_SETTING ChnlAccessSetting - ) +void ActUpdateChannelAccessSetting(struct net_device *dev, + WIRELESS_MODE WirelessMode, + PCHANNEL_ACCESS_SETTING ChnlAccessSetting) { struct r8180_priv *priv = ieee80211_priv(dev); struct ieee80211_device *ieee = priv->ieee80211; @@ -1172,11 +1105,7 @@ ActUpdateChannelAccessSetting( } } -void -ActSetWirelessMode8185( - struct net_device *dev, - u8 btWirelessMode - ) +void ActSetWirelessMode8185(struct net_device *dev, u8 btWirelessMode) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); struct ieee80211_device *ieee = priv->ieee80211; @@ -1230,19 +1159,14 @@ void rtl8185b_irq_enable(struct net_device *dev) priv->irq_enabled = 1; write_nic_dword(dev, IMR, priv->IntrMask); } + /* by amy for power save */ -void -DrvIFIndicateDisassociation( - struct net_device *dev, - u16 reason - ) +void DrvIFIndicateDisassociation(struct net_device *dev, u16 reason) { /* nothing is needed after disassociation request. */ - } -void -MgntDisconnectIBSS( - struct net_device *dev -) +} + +void MgntDisconnectIBSS(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); u8 i; @@ -1268,12 +1192,8 @@ MgntDisconnectIBSS( priv->ieee80211->link_change(dev); notify_wx_assoc_event(priv->ieee80211); } -void -MlmeDisassociateRequest( - struct net_device *dev, - u8 *asSta, - u8 asRsn - ) + +void MlmeDisassociateRequest(struct net_device *dev, u8 *asSta, u8 asRsn) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); u8 i; @@ -1292,11 +1212,7 @@ MlmeDisassociateRequest( } } -void -MgntDisconnectAP( - struct net_device *dev, - u8 asRsn -) +void MgntDisconnectAP(struct net_device *dev, u8 asRsn) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); @@ -1312,11 +1228,8 @@ MgntDisconnectAP( priv->ieee80211->state = IEEE80211_NOLINK; } -bool -MgntDisconnect( - struct net_device *dev, - u8 asRsn -) + +bool MgntDisconnect(struct net_device *dev, u8 asRsn) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); /* @@ -1350,11 +1263,7 @@ MgntDisconnect( Assumption: PASSIVE LEVEL. */ -bool -SetRFPowerState( - struct net_device *dev, - RT_RF_POWER_STATE eRFPowerState - ) +bool SetRFPowerState(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); bool bResult = false; @@ -1366,25 +1275,16 @@ SetRFPowerState( return bResult; } -void -HalEnableRx8185Dummy( - struct net_device *dev - ) + +void HalEnableRx8185Dummy(struct net_device *dev) { } -void -HalDisableRx8185Dummy( - struct net_device *dev - ) + +void HalDisableRx8185Dummy(struct net_device *dev) { } -bool -MgntActSet_RF_State( - struct net_device *dev, - RT_RF_POWER_STATE StateToSet, - u32 ChangeSource - ) +bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u32 ChangeSource) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); bool bActionAllowed = false; @@ -1488,10 +1388,8 @@ MgntActSet_RF_State( spin_unlock_irqrestore(&priv->rf_ps_lock, flag); return bActionAllowed; } -void -InactivePowerSave( - struct net_device *dev - ) + +void InactivePowerSave(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); /* @@ -1516,10 +1414,7 @@ InactivePowerSave( Description: Enter the inactive power save mode. RF will be off */ -void -IPSEnter( - struct net_device *dev - ) +void IPSEnter(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); RT_RF_POWER_STATE rtState; @@ -1541,10 +1436,7 @@ IPSEnter( } } } -void -IPSLeave( - struct net_device *dev - ) +void IPSLeave(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); RT_RF_POWER_STATE rtState; -- cgit v0.10.2 From f9c73f9b56efd3ed020e6a3b19d1dcdf84d93bbe Mon Sep 17 00:00:00 2001 From: Andrew Miller Date: Fri, 16 Mar 2012 18:47:38 -0400 Subject: Staging: rtl8187se: r8185b_init.c: Fix some spacing issues Fix some more spacing issues I missed before Signed-off-by: Andrew Miller Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c index 5650ef1..3f9be9b 100644 --- a/drivers/staging/rtl8187se/r8185b_init.c +++ b/drivers/staging/rtl8187se/r8185b_init.c @@ -71,10 +71,10 @@ static u8 MAC_REG_TABLE[][2] = { /* PAGA 0: */ {0x5e, 0x00}, {0x9f, 0x03} - }; + }; -static u8 ZEBRA_AGC[] = { +static u8 ZEBRA_AGC[] = { 0, 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, @@ -94,7 +94,7 @@ static u32 ZEBRA_RF_RX_GAIN_TABLE[] = { 0x0183, 0x0163, 0x0143, 0x0123, 0x0103 }; -static u8 OFDM_CONFIG[] = { +static u8 OFDM_CONFIG[] = { /* OFDM reg0x06[7:0]=0xFF: Enable power saving mode in RX */ /* OFDM reg0x3C[4]=1'b1: Enable RX power saving mode */ /* ofdm 0x3a = 0x7b ,(original : 0xfb) For ECS shielding room TP test */ @@ -121,22 +121,20 @@ void PlatformIOWrite1Byte(struct net_device *dev, u32 offset, u8 data) { write_nic_byte(dev, offset, data); read_nic_byte(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */ - } void PlatformIOWrite2Byte(struct net_device *dev, u32 offset, u16 data) { write_nic_word(dev, offset, data); read_nic_word(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */ - - } + u8 PlatformIORead1Byte(struct net_device *dev, u32 offset); void PlatformIOWrite4Byte(struct net_device *dev, u32 offset, u32 data) { /* {by amy 080312 */ - if (offset == PhyAddr) { + if (offset == PhyAddr) { /* For Base Band configuration. */ unsigned char cmdByte; unsigned long dataBytes; @@ -156,7 +154,7 @@ void PlatformIOWrite4Byte(struct net_device *dev, u32 offset, u32 data) */ /* NdisAcquireSpinLock( &(pDevice->IoSpinLock) ); */ - for (idx = 0; idx < 30; idx++) { + for (idx = 0; idx < 30; idx++) { /* Make sure command bit is clear before access it. */ u1bTmp = PlatformIORead1Byte(dev, PhyAddr); if ((u1bTmp & BIT7) == 0) @@ -224,9 +222,9 @@ static int HwHSSIThreeWire(struct net_device *dev, u8 TryCnt; u8 u1bTmp; - do { + do { /* Check if WE and RE are cleared. */ - for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) { + for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) { u1bTmp = read_nic_byte(dev, SW_3W_CMD1); if ((u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0) break; @@ -252,7 +250,7 @@ static int HwHSSIThreeWire(struct net_device *dev, write_nic_byte(dev, RF_SW_CONFIG, u1bTmp); - if (bSI) { + if (bSI) { /* jong: HW SI read must set reg84[3]=0. */ u1bTmp = read_nic_byte(dev, RFPinsSelect); u1bTmp &= ~BIT3; @@ -260,14 +258,14 @@ static int HwHSSIThreeWire(struct net_device *dev, } /* Fill up data buffer for write operation. */ - if (bWrite) { - if (nDataBufBitCnt == 16) { + if (bWrite) { + if (nDataBufBitCnt == 16) { write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf)); - } else if (nDataBufBitCnt == 64) { + } else if (nDataBufBitCnt == 64) { /* RTL8187S shouldn't enter this case */ write_nic_dword(dev, SW_3W_DB0, *((u32 *)pDataBuf)); write_nic_dword(dev, SW_3W_DB1, *((u32 *)(pDataBuf + 4))); - } else { + } else { int idx; int ByteCnt = nDataBufBitCnt / 8; /* printk("%d\n",nDataBufBitCnt); */ @@ -293,11 +291,11 @@ static int HwHSSIThreeWire(struct net_device *dev, write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx)); } - } else { /* read */ - if (bSI) { + } else { /* read */ + if (bSI) { /* SI - reg274[3:0] : RF register's Address */ write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf)); - } else { + } else { /* PI - reg274[15:12] : RF register's Address */ write_nic_word(dev, SW_3W_DB0, (*((u16 *)pDataBuf)) << 12); } @@ -323,11 +321,11 @@ static int HwHSSIThreeWire(struct net_device *dev, write_nic_byte(dev, SW_3W_CMD1, 0); /* Read back data for read operation. */ - if (bWrite == 0) { - if (bSI) { + if (bWrite == 0) { + if (bSI) { /* Serial Interface : reg363_362[11:0] */ *((u16 *)pDataBuf) = read_nic_word(dev, SI_DATA_READ) ; - } else { + } else { /* Parallel Interface : reg361_360[11:0] */ *((u16 *)pDataBuf) = read_nic_word(dev, PI_DATA_READ); } @@ -335,7 +333,7 @@ static int HwHSSIThreeWire(struct net_device *dev, *((u16 *)pDataBuf) &= 0x0FFF; } - } while (0); + } while (0); return bResult; } @@ -1296,7 +1294,7 @@ bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u Prevent the race condition of RF state change. By Bruce, 2007-11-28. Only one thread can change the RF state at one time, and others should wait to be executed. */ - while (true) { + while (true) { spin_lock_irqsave(&priv->rf_ps_lock, flag); if (priv->RFChangeInProgress) { spin_unlock_irqrestore(&priv->rf_ps_lock, flag); -- cgit v0.10.2 From 1ee6b74f3b58f4302383a170f3a4f9f17506a624 Mon Sep 17 00:00:00 2001 From: Andrew Miller Date: Fri, 16 Mar 2012 18:47:39 -0400 Subject: Staging: rtl8187se: r8185b_init.c: Removed old comments Removed some old comments and a few blank lines Signed-off-by: Andrew Miller Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c index 3f9be9b..d90cf10 100644 --- a/drivers/staging/rtl8187se/r8185b_init.c +++ b/drivers/staging/rtl8187se/r8185b_init.c @@ -25,13 +25,10 @@ Notes: #include "r8180_rtl8225.h" /* RTL8225 Radio frontend */ #include "r8180_93cx6.h" /* Card EEPROM */ #include "r8180_wx.h" - #include "ieee80211/dot11d.h" - - /* #define CONFIG_RTL8180_IO_MAP */ - #define TC_3W_POLL_MAX_TRY_CNT 5 + static u8 MAC_REG_TABLE[][2] = { /*PAGA 0: */ /* 0x34(BRSR), 0xBE(RATE_FALLBACK_CTL), 0x1E0(ARFR) would set in HwConfigureRTL8185() */ @@ -133,7 +130,6 @@ u8 PlatformIORead1Byte(struct net_device *dev, u32 offset); void PlatformIOWrite4Byte(struct net_device *dev, u32 offset, u32 data) { -/* {by amy 080312 */ if (offset == PhyAddr) { /* For Base Band configuration. */ unsigned char cmdByte; @@ -169,9 +165,7 @@ void PlatformIOWrite4Byte(struct net_device *dev, u32 offset, u32 data) write_nic_byte(dev, offset, cmdByte); /* NdisReleaseSpinLock( &(pDevice->IoSpinLock) ); */ - } -/* by amy 080312} */ - else { + } else { write_nic_dword(dev, offset, data); read_nic_dword(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */ } @@ -393,7 +387,6 @@ u8 ReadBBPortUchar(struct net_device *dev, u32 addr) return RegisterContent; } -/* {by amy 080312 */ /* Description: Perform Antenna settings with antenna diversity on 87SE. @@ -465,7 +458,6 @@ bool SetAntennaConfig87SE(struct net_device *dev, priv->CurrAntennaIndex = DefaultAnt; /* Update default settings. */ return bAntennaSwitched; } -/* by amy 080312 */ /* --------------------------------------------------------------- * Hardware Initialization. @@ -583,7 +575,6 @@ void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev) /* DAC calibration off 20070702 */ RF_WriteReg(dev, 0x06, 0x00c1); mdelay(1); RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1); -/* {by amy 080312 */ /* For crystal calibration, added by Roger, 2007.12.11. */ if (priv->bXtalCalibration) { /* reg 30. */ /* enable crystal calibration. @@ -598,7 +589,6 @@ void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev) /* using default value. Xin=6, Xout=6. */ RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1); } -/* by amy 080312 */ RF_WriteReg(dev, 0x00, 0x00bf); mdelay(1); /* switch to reg0-reg15, and HSSI enable */ RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1); /* Rx BB start calibration, 00c//+edward */ @@ -692,11 +682,8 @@ void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev) by amy for antenna ============================================================================= */ -/* {by amy 080312 */ /* Config Sw/Hw Combinational Antenna Diversity. Added by Roger, 2008.02.26. */ SetAntennaConfig87SE(dev, priv->bDefaultAntenna1, priv->bSwAntennaDiverity); -/* by amy 080312} */ -/* by amy for antenna */ } @@ -792,7 +779,6 @@ void PhyConfig8185(struct net_device *dev) priv->RFProgType = read_nic_byte(dev, CONFIG4) & 0x03; /* RF config */ ZEBRA_Config_85BASIC_HardCode(dev); -/* {by amy 080312 */ /* Set default initial gain state to 4, approved by SD3 DZ, by Bruce, 2007-06-06. */ if (priv->bDigMechanism) { if (priv->InitialGain == 0) @@ -807,7 +793,6 @@ void PhyConfig8185(struct net_device *dev) if (priv->bTxPowerTrack) InitTxPwrTracking87SE(dev); -/* by amy 080312} */ priv->InitialGainBackUp = priv->InitialGain; UpdateInitialGain(dev); @@ -1055,7 +1040,6 @@ void ActUpdateChannelAccessSetting(struct net_device *dev, PACI_AIFSN pAciAifsn = (PACI_AIFSN)(&pAcParam->f.AciAifsn); AC_CODING eACI = pAciAifsn->f.ACI; - /*modified Joseph */ /*for 8187B AsynIORead issue */ u8 AcmCtrl = 0; if (pAciAifsn->f.ACM) { @@ -1158,7 +1142,6 @@ void rtl8185b_irq_enable(struct net_device *dev) write_nic_dword(dev, IMR, priv->IntrMask); } -/* by amy for power save */ void DrvIFIndicateDisassociation(struct net_device *dev, u16 reason) { /* nothing is needed after disassociation request. */ @@ -1565,7 +1548,6 @@ void rtl8185b_adapter_start(struct net_device *dev) /* One of B, G, A. */ InitWirelessMode = ieee->mode; } -/* by amy for power save */ priv->eRFPowerState = eRfOff; priv->RfOffReason = 0; { @@ -1577,8 +1559,6 @@ void rtl8185b_adapter_start(struct net_device *dev) if (priv->bInactivePs) MgntActSet_RF_State(dev , eRfOff, RF_CHANGE_BY_IPS); -/* by amy for power save */ - ActSetWirelessMode8185(dev, (u8)(InitWirelessMode)); /* ----------------------------------------------------------------------------- */ -- cgit v0.10.2 From 4d36bf61929d5edea8968ae4ec4c45dfb6077489 Mon Sep 17 00:00:00 2001 From: Andrew Miller Date: Fri, 16 Mar 2012 18:47:40 -0400 Subject: Staging: rtl8187se: r8185b_init.c: Fix comment blocks Reformated comment blocks to meet Coding Style Signed-off-by: Andrew Miller Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c index d90cf10..af9be96 100644 --- a/drivers/staging/rtl8187se/r8185b_init.c +++ b/drivers/staging/rtl8187se/r8185b_init.c @@ -1,22 +1,22 @@ -/*++ -Copyright (c) Realtek Semiconductor Corp. All rights reserved. - -Module Name: - r8185b_init.c - -Abstract: - Hardware Initialization and Hardware IO for RTL8185B - -Major Change History: - When Who What - ---------- --------------- ------------------------------- - 2006-11-15 Xiong Created - -Notes: - This file is ported from RTL8185B Windows driver. - - ---*/ +/* + * Copyright (c) Realtek Semiconductor Corp. All rights reserved. + * + * Module Name: + * r8185b_init.c + * + * Abstract: + * Hardware Initialization and Hardware IO for RTL8185B + * + * Major Change History: + * When Who What + * ---------- --------------- ------------------------------- + * 2006-11-15 Xiong Created + * + * Notes: + * This file is ported from RTL8185B Windows driver. + * + * + */ /*--------------------------Include File------------------------------------*/ #include @@ -110,9 +110,10 @@ static u8 OFDM_CONFIG[] = { }; /*--------------------------------------------------------------- - * Hardware IO - * the code is ported from Windows source code - ----------------------------------------------------------------*/ + * Hardware IO + * the code is ported from Windows source code + *--------------------------------------------------------------- + */ void PlatformIOWrite1Byte(struct net_device *dev, u32 offset, u8 data) { @@ -141,13 +142,13 @@ void PlatformIOWrite4Byte(struct net_device *dev, u32 offset, u32 data) dataBytes = data>>8; /* - 071010, rcnjko: - The critical section is only BB read/write race condition. - Assumption: - 1. We assume NO one will access BB at DIRQL, otherwise, system will crash for - acquiring the spinlock in such context. - 2. PlatformIOWrite4Byte() MUST NOT be recursive. - */ + * 071010, rcnjko: + * The critical section is only BB read/write race condition. + * Assumption: + * 1. We assume NO one will access BB at DIRQL, otherwise, system will crash for + * acquiring the spinlock in such context. + * 2. PlatformIOWrite4Byte() MUST NOT be recursive. + */ /* NdisAcquireSpinLock( &(pDevice->IoSpinLock) ); */ for (idx = 0; idx < 30; idx++) { @@ -388,10 +389,10 @@ u8 ReadBBPortUchar(struct net_device *dev, u32 addr) return RegisterContent; } /* - Description: - Perform Antenna settings with antenna diversity on 87SE. - Created by Roger, 2008.01.25. -*/ + * Description: + * Perform Antenna settings with antenna diversity on 87SE. + * Created by Roger, 2008.01.25. + */ bool SetAntennaConfig87SE(struct net_device *dev, u8 DefaultAnt, /* 0: Main, 1: Aux. */ bool bAntDiversity) /* 1:Enable, 0: Disable. */ @@ -459,10 +460,11 @@ bool SetAntennaConfig87SE(struct net_device *dev, return bAntennaSwitched; } /* ---------------------------------------------------------------- - * Hardware Initialization. - * the code is ported from Windows source code -----------------------------------------------------------------*/ + *-------------------------------------------------------------- + * Hardware Initialization. + * the code is ported from Windows source code + *-------------------------------------------------------------- + */ void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev) { @@ -476,10 +478,10 @@ void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev) /* -============================================================================= - 87S_PCIE :: RADIOCFG.TXT -============================================================================= -*/ + *=========================================================================== + * 87S_PCIE :: RADIOCFG.TXT + *=========================================================================== + */ /* Page1 : reg16-reg30 */ @@ -577,11 +579,13 @@ void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev) RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1); /* For crystal calibration, added by Roger, 2007.12.11. */ if (priv->bXtalCalibration) { /* reg 30. */ - /* enable crystal calibration. - RF Reg[30], (1)Xin:[12:9], Xout:[8:5], addr[4:0]. - (2)PA Pwr delay timer[15:14], default: 2.4us, set BIT15=0 - (3)RF signal on/off when calibration[13], default: on, set BIT13=0. - So we should minus 4 BITs offset. */ + /* + * enable crystal calibration. + * RF Reg[30], (1)Xin:[12:9], Xout:[8:5], addr[4:0]. + * (2)PA Pwr delay timer[15:14], default: 2.4us, set BIT15=0 + * (3)RF signal on/off when calibration[13], default: on, set BIT13=0. + * So we should minus 4 BITs offset. + */ RF_WriteReg(dev, 0x0f, (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | BIT11 | BIT9); mdelay(1); printk("ZEBRA_Config_85BASIC_HardCode(): (%02x)\n", (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | BIT11 | BIT9); @@ -607,18 +611,18 @@ void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev) write_nic_byte(dev, 0x24E, (u1b24E & (~(BIT5|BIT6)))); /*============================================================================= - - ============================================================================= - CCKCONF.TXT - ============================================================================= - */ - /* [POWER SAVE] Power Saving Parameters by jong. 2007-11-27 - CCK reg0x00[7]=1'b1 :power saving for TX (default) - CCK reg0x00[6]=1'b1: power saving for RX (default) - CCK reg0x06[4]=1'b1: turn off channel estimation related circuits if not doing channel estimation. - CCK reg0x06[3]=1'b1: turn off unused circuits before cca = 1 - CCK reg0x06[2]=1'b1: turn off cck's circuit if macrst =0 - */ + * + *=========================================================================== + * CCKCONF.TXT + *=========================================================================== + * + * [POWER SAVE] Power Saving Parameters by jong. 2007-11-27 + * CCK reg0x00[7]=1'b1 :power saving for TX (default) + * CCK reg0x00[6]=1'b1: power saving for RX (default) + * CCK reg0x06[4]=1'b1: turn off channel estimation related circuits if not doing channel estimation. + * CCK reg0x06[3]=1'b1: turn off unused circuits before cca = 1 + * CCK reg0x06[2]=1'b1: turn off cck's circuit if macrst =0 + */ write_phy_cck(dev, 0x00, 0xc8); write_phy_cck(dev, 0x06, 0x1c); @@ -635,10 +639,10 @@ void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev) /* - ============================================================================= - AGC.txt - ============================================================================= - */ + *=========================================================================== + * AGC.txt + *=========================================================================== + */ write_phy_ofdm(dev, 0x00, 0x12); @@ -660,12 +664,12 @@ void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev) PlatformIOWrite4Byte(dev, PhyAddr, 0x00001080); /* Annie, 2006-05-05 */ /* - ============================================================================= - - ============================================================================= - OFDMCONF.TXT - ============================================================================= - */ + *=========================================================================== + * + *=========================================================================== + * OFDMCONF.TXT + *=========================================================================== + */ for (i = 0; i < 60; i++) { u4bRegOffset = i; @@ -678,10 +682,10 @@ void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev) } /* - ============================================================================= - by amy for antenna - ============================================================================= - */ + *=========================================================================== + * by amy for antenna + *=========================================================================== + */ /* Config Sw/Hw Combinational Antenna Diversity. Added by Roger, 2008.02.26. */ SetAntennaConfig87SE(dev, priv->bDefaultAntenna1, priv->bSwAntennaDiverity); } @@ -694,9 +698,9 @@ void UpdateInitialGain(struct net_device *dev) /* lzm add 080826 */ if (priv->eRFPowerState != eRfOn) { /* Don't access BB/RF under disable PLL situation. - RT_TRACE(COMP_DIG, DBG_LOUD, ("UpdateInitialGain - pHalData->eRFPowerState!=eRfOn\n")); - Back to the original state - */ + * RT_TRACE(COMP_DIG, DBG_LOUD, ("UpdateInitialGain - pHalData->eRFPowerState!=eRfOn\n")); + * Back to the original state + */ priv->InitialGain = priv->InitialGainBackUp; return; } @@ -758,10 +762,10 @@ void UpdateInitialGain(struct net_device *dev) } } /* - Description: - Tx Power tracking mechanism routine on 87SE. - Created by Roger, 2007.12.11. -*/ + * Description: + * Tx Power tracking mechanism routine on 87SE. + * Created by Roger, 2007.12.11. + */ void InitTxPwrTracking87SE(struct net_device *dev) { u32 u4bRfReg; @@ -786,10 +790,10 @@ void PhyConfig8185(struct net_device *dev) } /* - Enable thermal meter indication to implement TxPower tracking on 87SE. - We initialize thermal meter here to avoid unsuccessful configuration. - Added by Roger, 2007.12.11. - */ + * Enable thermal meter indication to implement TxPower tracking on 87SE. + * We initialize thermal meter here to avoid unsuccessful configuration. + * Added by Roger, 2007.12.11. + */ if (priv->bTxPowerTrack) InitTxPwrTracking87SE(dev); @@ -858,10 +862,10 @@ void HwConfigureRTL8185(struct net_device *dev) static void MacConfig_85BASIC_HardCode(struct net_device *dev) { /* - ============================================================================ - MACREG.TXT - ============================================================================ - */ + *========================================================================== + * MACREG.TXT + *========================================================================== + */ int nLinesRead = 0; u32 u4bRegOffset, u4bRegValue, u4bPageIndex = 0; int i; @@ -944,15 +948,15 @@ void ActUpdateChannelAccessSetting(struct net_device *dev, u8 u1bAIFS; /* - - TODO: We still don't know how to set up these registers, just follow WMAC to - verify 8185B FPAG. - - - Jong said CWmin/CWmax register are not functional in 8185B, - so we shall fill channel access realted register into AC parameter registers, - even in nQBss. - */ + * + * TODO: We still don't know how to set up these registers, just follow WMAC to + * verify 8185B FPAG. + * + * + * Jong said CWmin/CWmax register are not functional in 8185B, + * so we shall fill channel access realted register into AC parameter registers, + * even in nQBss. + */ ChnlAccessSetting->SIFS_Timer = 0x22; /* Suggested by Jong, 2005.12.08. */ ChnlAccessSetting->DIFS_Timer = 0x1C; /* 2006.06.02, by rcnjko. */ ChnlAccessSetting->SlotTimeTimer = 9; /* 2006.06.02, by rcnjko. */ @@ -978,9 +982,9 @@ void ActUpdateChannelAccessSetting(struct net_device *dev, if (bFollowLegacySetting) { /* - Follow 802.11 seeting to AC parameter, all AC shall use the same parameter. - 2005.12.01, by rcnjko. - */ + * Follow 802.11 seeting to AC parameter, all AC shall use the same parameter. + * 2005.12.01, by rcnjko. + */ AcParam.longData = 0; AcParam.f.AciAifsn.f.AIFSN = 2; /* Follow 802.11 DIFS. */ AcParam.f.AciAifsn.f.ACM = 0; @@ -1116,10 +1120,12 @@ void ActSetWirelessMode8185(struct net_device *dev, u8 btWirelessMode) } } - /* 2. Swtich band: RF or BB specific actions, + /* + * 2. Swtich band: RF or BB specific actions, * for example, refresh tables in omc8255, or change initial gain if necessary. * Nothing to do for Zebra to switch band. - * Update current wireless mode if we swtich to specified band successfully. */ + * Update current wireless mode if we swtich to specified band successfully. + */ ieee->mode = (WIRELESS_MODE)btWirelessMode; @@ -1161,13 +1167,14 @@ void MgntDisconnectIBSS(struct net_device *dev) priv->ieee80211->state = IEEE80211_NOLINK; /* - Stop Beacon. - - Vista add a Adhoc profile, HW radio off until OID_DOT11_RESET_REQUEST - Driver would set MSR=NO_LINK, then HW Radio ON, MgntQueue Stuck. - Because Bcn DMA isn't complete, mgnt queue would stuck until Bcn packet send. - - Disable Beacon Queue Own bit, suggested by jong */ + * Stop Beacon. + * + * Vista add a Adhoc profile, HW radio off until OID_DOT11_RESET_REQUEST + * Driver would set MSR=NO_LINK, then HW Radio ON, MgntQueue Stuck. + * Because Bcn DMA isn't complete, mgnt queue would stuck until Bcn packet send. + * + * Disable Beacon Queue Own bit, suggested by jong + */ ieee80211_stop_send_beacons(priv->ieee80211); priv->ieee80211->link_change(dev); @@ -1198,13 +1205,14 @@ void MgntDisconnectAP(struct net_device *dev, u8 asRsn) struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); /* - Commented out by rcnjko, 2005.01.27: - I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE(). - - 2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success - - In WPA WPA2 need to Clear all key ... because new key will set after new handshaking. - 2004.10.11, by rcnjko. */ + * Commented out by rcnjko, 2005.01.27: + * I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE(). + * + * 2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success + * + * In WPA WPA2 need to Clear all key ... because new key will set after new handshaking. + * 2004.10.11, by rcnjko. + */ MlmeDisassociateRequest(dev, priv->ieee80211->current_network.bssid, asRsn); priv->ieee80211->state = IEEE80211_NOLINK; @@ -1214,8 +1222,8 @@ bool MgntDisconnect(struct net_device *dev, u8 asRsn) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); /* - Schedule an workitem to wake up for ps mode, 070109, by rcnjko. - */ + * Schedule an workitem to wake up for ps mode, 070109, by rcnjko. + */ if (IS_DOT11D_ENABLE(priv->ieee80211)) Dot11d_Reset(priv->ieee80211); @@ -1225,11 +1233,13 @@ bool MgntDisconnect(struct net_device *dev, u8 asRsn) MgntDisconnectIBSS(dev); if (priv->ieee80211->iw_mode == IW_MODE_INFRA) { - /* We clear key here instead of MgntDisconnectAP() because that - MgntActSet_802_11_DISASSOCIATE() is an interface called by OS, - e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is - used to handle disassociation related things to AP, e.g. send Disassoc - frame to AP. 2005.01.27, by rcnjko. */ + /* + * We clear key here instead of MgntDisconnectAP() because that + * MgntActSet_802_11_DISASSOCIATE() is an interface called by OS, + * e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is + * used to handle disassociation related things to AP, e.g. send Disassoc + * frame to AP. 2005.01.27, by rcnjko. + */ MgntDisconnectAP(dev, asRsn); } /* Inidicate Disconnect, 2005.02.23, by rcnjko. */ @@ -1237,13 +1247,13 @@ bool MgntDisconnect(struct net_device *dev, u8 asRsn) return true; } /* - Description: - Chang RF Power State. - Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE. - - Assumption: - PASSIVE LEVEL. -*/ + * Description: + * Chang RF Power State. + * Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE. + * + * Assumption: + * PASSIVE LEVEL. + */ bool SetRFPowerState(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); @@ -1274,9 +1284,9 @@ bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u u16 RFWaitCounter = 0; unsigned long flag; /* - Prevent the race condition of RF state change. By Bruce, 2007-11-28. - Only one thread can change the RF state at one time, and others should wait to be executed. - */ + * Prevent the race condition of RF state change. By Bruce, 2007-11-28. + * Only one thread can change the RF state at one time, and others should wait to be executed. + */ while (true) { spin_lock_irqsave(&priv->rf_ps_lock, flag); if (priv->RFChangeInProgress) { @@ -1304,9 +1314,9 @@ bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u switch (StateToSet) { case eRfOn: /* - Turn On RF no matter the IPS setting because we need to update the RF state to Ndis under Vista, or - the Windows does not allow the driver to perform site survey any more. By Bruce, 2007-10-02. - */ + * Turn On RF no matter the IPS setting because we need to update the RF state to Ndis under Vista, or + * the Windows does not allow the driver to perform site survey any more. By Bruce, 2007-10-02. + */ priv->RfOffReason &= (~ChangeSource); if (!priv->RfOffReason) { @@ -1325,12 +1335,12 @@ bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u if (priv->RfOffReason > RF_CHANGE_BY_IPS) { /* - 060808, Annie: - Disconnect to current BSS when radio off. Asked by QuanTa. - - Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(), - because we do NOT need to set ssid to dummy ones. - */ + * 060808, Annie: + * Disconnect to current BSS when radio off. Asked by QuanTa. + * + * Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(), + * because we do NOT need to set ssid to dummy ones. + */ MgntDisconnect(dev, disas_lv_ss); /* Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI. */ } @@ -1374,27 +1384,27 @@ void InactivePowerSave(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); /* - This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem - is really scheduled. - The old code, sets this flag before scheduling the IPS workitem and however, at the same time the - previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing - blocks the IPS procedure of switching RF. - */ + * This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem + * is really scheduled. + * The old code, sets this flag before scheduling the IPS workitem and however, at the same time the + * previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing + * blocks the IPS procedure of switching RF. + */ priv->bSwRfProcessing = true; MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS); /* - To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20. - */ + * To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20. + */ priv->bSwRfProcessing = false; } /* - Description: - Enter the inactive power save mode. RF will be off -*/ + * Description: + * Enter the inactive power save mode. RF will be off + */ void IPSEnter(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); @@ -1403,13 +1413,13 @@ void IPSEnter(struct net_device *dev) rtState = priv->eRFPowerState; /* - Do not enter IPS in the following conditions: - (1) RF is already OFF or Sleep - (2) bSwRfProcessing (indicates the IPS is still under going) - (3) Connectted (only disconnected can trigger IPS) - (4) IBSS (send Beacon) - (5) AP mode (send Beacon) - */ + * Do not enter IPS in the following conditions: + * (1) RF is already OFF or Sleep + * (2) bSwRfProcessing (indicates the IPS is still under going) + * (3) Connectted (only disconnected can trigger IPS) + * (4) IBSS (send Beacon) + * (5) AP mode (send Beacon) + */ if (rtState == eRfOn && !priv->bSwRfProcessing && (priv->ieee80211->state != IEEE80211_LINKED)) { priv->eInactivePowerState = eRfOff; @@ -1463,10 +1473,10 @@ void rtl8185b_adapter_start(struct net_device *dev) PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x569a); /* - ----------------------------------------------------------------------------- - Set up PHY related. - ----------------------------------------------------------------------------- - */ + *--------------------------------------------------------------------------- + * Set up PHY related. + *--------------------------------------------------------------------------- + */ /* Enable Config3.PARAM_En to revise AnaaParm. */ write_nic_byte(dev, CR9346, 0xc0); /* enable config register write */ tmpu8 = read_nic_byte(dev, CONFIG3); @@ -1505,10 +1515,10 @@ void rtl8185b_adapter_start(struct net_device *dev) PhyConfig8185(dev); /* - We assume RegWirelessMode has already been initialized before, - however, we has to validate the wireless mode here and provide a - reasonable initialized value if necessary. 2005.01.13, by rcnjko. - */ + * We assume RegWirelessMode has already been initialized before, + * however, we has to validate the wireless mode here and provide a + * reasonable initialized value if necessary. 2005.01.13, by rcnjko. + */ SupportedWirelessMode = GetSupportedWirelessMode8185(dev); if ((ieee->mode != WIRELESS_MODE_B) && (ieee->mode != WIRELESS_MODE_G) && @@ -1554,8 +1564,8 @@ void rtl8185b_adapter_start(struct net_device *dev) MgntActSet_RF_State(dev, eRfOn, 0); } /* - If inactive power mode is enabled, disable rf while in disconnected state. - */ + * If inactive power mode is enabled, disable rf while in disconnected state. + */ if (priv->bInactivePs) MgntActSet_RF_State(dev , eRfOff, RF_CHANGE_BY_IPS); -- cgit v0.10.2 From 96ddcd439871658b797289dde8fcead8bde73b68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20K=C3=B6llhofer?= Date: Thu, 22 Mar 2012 22:49:55 +0100 Subject: staging/rtl8192e - fix typo in printk message In drivers/staging/rtl8192e/rtl8192e/rtl_core.c the follwing printk-message can be found: printk(KERN_ERR "rtl8193e: Unable to allocate space " This is quite obviously just a typo, all other similar messages use "rtl8192e" and the string "rtl8193e" does not occur anywhere else in the source of the driver. Signed-off-by: Axel Koellhofer Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 71adb6b..7c676c2 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -1211,7 +1211,7 @@ static void rtl8192_init_priv_variable(struct net_device *dev) priv->AcmControl = 0; priv->pFirmware = vzalloc(sizeof(struct rt_firmware)); if (!priv->pFirmware) - printk(KERN_ERR "rtl8193e: Unable to allocate space " + printk(KERN_ERR "rtl8192e: Unable to allocate space " "for firmware\n"); skb_queue_head_init(&priv->rx_queue); -- cgit v0.10.2 From ba46ce30f13a13bb24d05e21df2571ad724f1a1e Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Tue, 13 Mar 2012 19:07:18 +0100 Subject: staging: usbip: fix the usage of kthread_stop() stub_shutdown_connection() and vhci_shutdown_connection() use task_is_dead() before kthread_stop(). This buys nothing and wrong. kthread_stop() is fine even if this thread is dead. However, if it is dead nothing protects this task_struct, we shouldn't touch this memory. Change the code to do the necessary get_task_struct/put_task_struct. This patch assumes that - xxx_shutdown_connection() is always called, so we can't leak the task_struct. - kthread_stop_put() can't be called twice on the same task. Signed-off-by: Oleg Nesterov Cc: Tobias Klauser Cc: Matt Mooney , Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c index fa870e3..92ced35 100644 --- a/drivers/staging/usbip/stub_dev.c +++ b/drivers/staging/usbip/stub_dev.c @@ -113,8 +113,8 @@ static ssize_t store_sockfd(struct device *dev, struct device_attribute *attr, spin_unlock(&sdev->ud.lock); - sdev->ud.tcp_rx = kthread_run(stub_rx_loop, &sdev->ud, "stub_rx"); - sdev->ud.tcp_tx = kthread_run(stub_tx_loop, &sdev->ud, "stub_tx"); + sdev->ud.tcp_rx = kthread_get_run(stub_rx_loop, &sdev->ud, "stub_rx"); + sdev->ud.tcp_tx = kthread_get_run(stub_tx_loop, &sdev->ud, "stub_tx"); spin_lock(&sdev->ud.lock); sdev->ud.status = SDEV_ST_USED; @@ -187,10 +187,10 @@ static void stub_shutdown_connection(struct usbip_device *ud) } /* 1. stop threads */ - if (ud->tcp_rx && !task_is_dead(ud->tcp_rx)) - kthread_stop(ud->tcp_rx); - if (ud->tcp_tx && !task_is_dead(ud->tcp_tx)) - kthread_stop(ud->tcp_tx); + if (ud->tcp_rx) + kthread_stop_put(ud->tcp_rx); + if (ud->tcp_tx) + kthread_stop_put(ud->tcp_tx); /* * 2. close the socket diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h index c7b888c..5d89c0f 100644 --- a/drivers/staging/usbip/usbip_common.h +++ b/drivers/staging/usbip/usbip_common.h @@ -292,6 +292,23 @@ struct usbip_device { } eh_ops; }; +#define kthread_get_run(threadfn, data, namefmt, ...) \ +({ \ + struct task_struct *__k \ + = kthread_create(threadfn, data, namefmt, ## __VA_ARGS__); \ + if (!IS_ERR(__k)) { \ + get_task_struct(__k); \ + wake_up_process(__k); \ + } \ + __k; \ +}) + +#define kthread_stop_put(k) \ + do { \ + kthread_stop(k); \ + put_task_struct(k); \ + } while (0) + /* usbip_common.c */ void usbip_dump_urb(struct urb *purb); void usbip_dump_header(struct usbip_header *pdu); diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index dca9bf1..f708cba 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -821,10 +821,10 @@ static void vhci_shutdown_connection(struct usbip_device *ud) } /* kill threads related to this sdev, if v.c. exists */ - if (vdev->ud.tcp_rx && !task_is_dead(vdev->ud.tcp_rx)) - kthread_stop(vdev->ud.tcp_rx); - if (vdev->ud.tcp_tx && !task_is_dead(vdev->ud.tcp_tx)) - kthread_stop(vdev->ud.tcp_tx); + if (vdev->ud.tcp_rx) + kthread_stop_put(vdev->ud.tcp_rx); + if (vdev->ud.tcp_tx) + kthread_stop_put(vdev->ud.tcp_tx); pr_info("stop threads\n"); diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/staging/usbip/vhci_sysfs.c index 0cd039b..7ce9c2f 100644 --- a/drivers/staging/usbip/vhci_sysfs.c +++ b/drivers/staging/usbip/vhci_sysfs.c @@ -222,8 +222,8 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, spin_unlock(&the_controller->lock); /* end the lock */ - vdev->ud.tcp_rx = kthread_run(vhci_rx_loop, &vdev->ud, "vhci_rx"); - vdev->ud.tcp_tx = kthread_run(vhci_tx_loop, &vdev->ud, "vhci_tx"); + vdev->ud.tcp_rx = kthread_get_run(vhci_rx_loop, &vdev->ud, "vhci_rx"); + vdev->ud.tcp_tx = kthread_get_run(vhci_tx_loop, &vdev->ud, "vhci_tx"); rh_port_connect(rhport, speed); -- cgit v0.10.2 From 535f2a5ffa5b11bd6824cbab6027d5092b5517c2 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 19 Mar 2012 08:17:49 -0700 Subject: staging:nvec:nvec.h Fix typos in staging:nvec The below patch fixes a typo I found while reading. Signed-off-by: Justin P. Mattock Cc: Julian Andres Klode Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/nvec/nvec.h b/drivers/staging/nvec/nvec.h index a4c17b0..ba6ed8f 100644 --- a/drivers/staging/nvec/nvec.h +++ b/drivers/staging/nvec/nvec.h @@ -42,7 +42,7 @@ * enum nvec_event_size - The size of an event message * @NVEC_2BYTES: The message has one command byte and one data byte * @NVEC_3BYTES: The message has one command byte and two data bytes - * @NVEC_VAR_SIZE: The message has one command byte, one count byte, and as + * @NVEC_VAR_SIZE: The message has one command byte, one count byte, and has * up to as many bytes as the number in the count byte. The * maximum is 32 * -- cgit v0.10.2 From 595914fea321fdd6c3664ce6b6a33c12930c24c7 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 19 Mar 2012 08:17:50 -0700 Subject: staging:ozwpan:ozhcd.c Fix typos in staging:ozwpan The below patch fixes a typo that I found while reading. Signed-off-by: Justin P. Mattock Acked-by: Chris Kelly Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index 750b14e..cfa25e8 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c @@ -1463,7 +1463,7 @@ static void oz_process_ep0_urb(struct oz_hcd *ozhcd, struct urb *urb, rc = -ENOMEM; } else { /* Note: we are queuing the request after we have - * submitted it to be tranmitted. If the request were + * submitted it to be transmitted. If the request were * to complete before we queued it then it would not * be found in the queue. It seems impossible for * this to happen but if it did the request would -- cgit v0.10.2 From 5d25287f9b11e2395a1f6679f43aa544977b3e54 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 19 Mar 2012 08:17:51 -0700 Subject: staging:olpc_dcon:olpc_dcon_xo_1.c Fix typo in staging:olpc_dcon The below patch fixes a typo I found while reading. Signed-off-by: Justin P. Mattock Cc: Andres Salomon Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c index cb6ce0c..c87fdfa 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c +++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c @@ -116,7 +116,7 @@ static int dcon_init_xo_1(struct dcon_priv *dcon) cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_NEGATIVE_EDGE_STS); cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_NEGATIVE_EDGE_STS); - /* FIXME: Clear the posiitive status as well, just to be sure */ + /* FIXME: Clear the positive status as well, just to be sure */ cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_POSITIVE_EDGE_STS); cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_POSITIVE_EDGE_STS); -- cgit v0.10.2 From 6975e183bb59dd6cc281247925092ca42ab7e1d5 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 19 Mar 2012 08:17:52 -0700 Subject: staging:panel:panel.c Fix typo in staging:panel The below patch fixes a typo I found while reading. Signed-off-by: Justin P. Mattock Cc: Willy Tarreau Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index 6183573..7365089 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c @@ -754,7 +754,7 @@ static void lcd_backlight(int on) if (lcd_bl_pin == PIN_NONE) return; - /* The backlight is activated by seting the AUTOFEED line to +5V */ + /* The backlight is activated by setting the AUTOFEED line to +5V */ spin_lock(&pprt_lock); bits.bl = on; panel_set_bits(); -- cgit v0.10.2 From 4e24764017ee5dd9d7062e9c10af2c3c557f9c5a Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 19 Mar 2012 08:17:53 -0700 Subject: staging:quatech_usb2:quatech_usb2.c Fix typo in staging:quatech_usb2 The below patch fixes a typo that I found while reading. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/quatech_usb2/quatech_usb2.c b/drivers/staging/quatech_usb2/quatech_usb2.c index bb977e0..cb7d906 100644 --- a/drivers/staging/quatech_usb2/quatech_usb2.c +++ b/drivers/staging/quatech_usb2/quatech_usb2.c @@ -732,7 +732,7 @@ static int qt2_write(struct tty_struct *tty, struct usb_serial_port *port, } /* We must fill the first 5 bytes of anything we sent with a transmit - * header which directes the data to the correct port. The maximum + * header which directs the data to the correct port. The maximum * size we can send out in one URB is port->bulk_out_size, which caps * the number of bytes of real data we can send in each write. As the * semantics of write allow us to write less than we were give, we cap -- cgit v0.10.2 From 2f3d2b499b73b3aa05feba35a9b04c6eec1a50ec Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 19 Mar 2012 22:38:13 +0200 Subject: staging/mei: define pr_fmt prefix for pr_ macros define pr_fmt macro and remove mei: from the messages Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/mei/main.c b/drivers/staging/mei/main.c index 7c9321f..4f46738 100644 --- a/drivers/staging/mei/main.c +++ b/drivers/staging/mei/main.c @@ -14,6 +14,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -1020,7 +1022,7 @@ static int __devinit mei_probe(struct pci_dev *pdev, mutex_unlock(&mei_mutex); - pr_debug("mei: Driver initialization successful.\n"); + pr_debug("initialization successful.\n"); return 0; @@ -1204,7 +1206,7 @@ static int __init mei_init_module(void) { int ret; - pr_debug("mei: %s\n", mei_driver_string); + pr_debug("loading.\n"); /* init pci module */ ret = pci_register_driver(&mei_driver); if (ret < 0) @@ -1226,7 +1228,7 @@ static void __exit mei_exit_module(void) misc_deregister(&mei_misc_device); pci_unregister_driver(&mei_driver); - pr_debug("mei: Driver unloaded successfully.\n"); + pr_debug("unloaded successfully.\n"); } module_exit(mei_exit_module); -- cgit v0.10.2 From 5192dda1751b2c4a988e6aa198c153d840a304a2 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 19 Mar 2012 17:58:43 +0200 Subject: staging/mei: mei_wd_set_start_timeout should be static mei_wd_set_start_timeout is only used from within wd.c so remove its declaration from interface.h and mark it static Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/mei/interface.h b/drivers/staging/mei/interface.h index fb90c6f..f934b09 100644 --- a/drivers/staging/mei/interface.h +++ b/drivers/staging/mei/interface.h @@ -52,7 +52,6 @@ int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl); int mei_wd_send(struct mei_device *dev); int mei_wd_stop(struct mei_device *dev, bool preserve); bool mei_wd_host_init(struct mei_device *dev); -void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout); /* * mei_watchdog_register - Registering watchdog interface * once we got connection to the WD Client diff --git a/drivers/staging/mei/wd.c b/drivers/staging/mei/wd.c index cf4c29d..d7f40db 100644 --- a/drivers/staging/mei/wd.c +++ b/drivers/staging/mei/wd.c @@ -45,12 +45,11 @@ const uuid_le mei_wd_guid = UUID_LE(0x05B79A6F, 0x4628, 0x4D7F, 0x89, 0x9D, 0xA9, 0x15, 0x14, 0xCB, 0x32, 0xAB); -void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout) +static void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout) { dev_dbg(&dev->pdev->dev, "timeout=%d.\n", timeout); memcpy(dev->wd_data, mei_start_wd_params, MEI_WD_PARAMS_SIZE); - memcpy(dev->wd_data + MEI_WD_PARAMS_SIZE, - &timeout, sizeof(u16)); + memcpy(dev->wd_data + MEI_WD_PARAMS_SIZE, &timeout, sizeof(u16)); } /** -- cgit v0.10.2 From d39a464970185f2592cb06aa42a88764bcb12e32 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 19 Mar 2012 17:58:42 +0200 Subject: staging/mei: use dev_err instead of printk one instance of bare printk was forgotten in init.c file Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/mei/init.c b/drivers/staging/mei/init.c index eab711f..afb0a58 100644 --- a/drivers/staging/mei/init.c +++ b/drivers/staging/mei/init.c @@ -200,7 +200,7 @@ int mei_hw_init(struct mei_device *dev) if (!(dev->me_hw_state & ME_RDY_HRA)) dev_dbg(&dev->pdev->dev, "ME turn off ME_RDY.\n"); - printk(KERN_ERR "mei: link layer initialization failed.\n"); + dev_err(&dev->pdev->dev, "link layer initialization failed.\n"); ret = -ENODEV; goto out; } -- cgit v0.10.2 From b18a4d6d7d1b10c2c727de925c4883df432aa1a5 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 2 Apr 2012 20:32:37 +0300 Subject: staging/mei: remove unused variable Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/mei/main.c b/drivers/staging/mei/main.c index 4f46738..5e91010 100644 --- a/drivers/staging/mei/main.c +++ b/drivers/staging/mei/main.c @@ -42,7 +42,6 @@ #include "interface.h" -#define MEI_READ_TIMEOUT 45 #define MEI_DRIVER_NAME "mei" #define MEI_DEV_NAME "mei" -- cgit v0.10.2 From 68d923d5369e7e8f72dbc75015829b7fc83512fc Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 2 Apr 2012 20:32:38 +0300 Subject: staging/mei: struct amt_wd_dev' should it be static fix sparse warning: 'amt_wd_dev' was not declared. Should it be static Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/mei/wd.c b/drivers/staging/mei/wd.c index d7f40db..57a1642 100644 --- a/drivers/staging/mei/wd.c +++ b/drivers/staging/mei/wd.c @@ -345,7 +345,7 @@ static const struct watchdog_info wd_info = { .options = WDIOF_KEEPALIVEPING, }; -struct watchdog_device amt_wd_dev = { +static struct watchdog_device amt_wd_dev = { .info = &wd_info, .ops = &wd_ops, .timeout = AMT_WD_DEFAULT_TIMEOUT, -- cgit v0.10.2 From c38ea24e22e8c416d4a2b13355a546b5916ae296 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 2 Apr 2012 20:32:39 +0300 Subject: staging/mei: cleanup driver naming strings 1. use only mei_driver_name and remove define MEI_DRIVER_NAME 2. drop MEI_DEV_NAME and assign device name directly 3. drop mei_driver_string, it is not used Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/mei/main.c b/drivers/staging/mei/main.c index 5e91010..20f80df 100644 --- a/drivers/staging/mei/main.c +++ b/drivers/staging/mei/main.c @@ -41,15 +41,7 @@ #include "mei.h" #include "interface.h" - -#define MEI_DRIVER_NAME "mei" -#define MEI_DEV_NAME "mei" - -/* - * mei driver strings - */ -static char mei_driver_name[] = MEI_DRIVER_NAME; -static const char mei_driver_string[] = "Intel(R) Management Engine Interface"; +static const char mei_driver_name[] = "mei"; /* The device pointer */ /* Currently this driver works as long as there is only a single AMT device. */ @@ -932,7 +924,7 @@ static const struct file_operations mei_fops = { * Misc Device Struct */ static struct miscdevice mei_misc_device = { - .name = MEI_DRIVER_NAME, + .name = "mei", .fops = &mei_fops, .minor = MISC_DYNAMIC_MINOR, }; -- cgit v0.10.2 From 9487eb0a1588b8d759f7231c7aa44893525769b2 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 3 Apr 2012 23:34:58 +0300 Subject: staging/mei: refactor mei_wd_host_init function The function has returned false in both error and success cases. 1. change return value to int and return appropriate errno 2. use typical Linux kernel error handling. 3. normalize debug messages Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/mei/interface.h b/drivers/staging/mei/interface.h index f934b09..0d00435 100644 --- a/drivers/staging/mei/interface.h +++ b/drivers/staging/mei/interface.h @@ -51,7 +51,7 @@ int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl); int mei_wd_send(struct mei_device *dev); int mei_wd_stop(struct mei_device *dev, bool preserve); -bool mei_wd_host_init(struct mei_device *dev); +int mei_wd_host_init(struct mei_device *dev); /* * mei_watchdog_register - Registering watchdog interface * once we got connection to the WD Client diff --git a/drivers/staging/mei/wd.c b/drivers/staging/mei/wd.c index 57a1642..032cf67 100644 --- a/drivers/staging/mei/wd.c +++ b/drivers/staging/mei/wd.c @@ -56,11 +56,11 @@ static void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout) * host_init_wd - mei initialization wd. * * @dev: the device structure + * returns -ENENT if wd client cannot be found + * -EIO if write has failed */ -bool mei_wd_host_init(struct mei_device *dev) +int mei_wd_host_init(struct mei_device *dev) { - bool ret = false; - mei_cl_init(&dev->wd_cl, dev); /* look for WD client and connect to it */ @@ -71,25 +71,21 @@ bool mei_wd_host_init(struct mei_device *dev) mei_find_me_client_update_filext(dev, &dev->wd_cl, &mei_wd_guid, MEI_WD_HOST_CLIENT_ID); - dev_dbg(&dev->pdev->dev, "check wd_cl\n"); - if (MEI_FILE_CONNECTING == dev->wd_cl.state) { - if (mei_connect(dev, &dev->wd_cl)) { - dev_dbg(&dev->pdev->dev, "Failed to connect to WD client\n"); - dev->wd_cl.state = MEI_FILE_DISCONNECTED; - dev->wd_cl.host_client_id = 0; - ret = false; - goto end; - } else { - dev->wd_cl.timer_count = CONNECT_TIMEOUT; - } - } else { - dev_dbg(&dev->pdev->dev, "Failed to find WD client\n"); - ret = false; - goto end; + dev_dbg(&dev->pdev->dev, "wd: check client\n"); + if (MEI_FILE_CONNECTING != dev->wd_cl.state) { + dev_info(&dev->pdev->dev, "wd: failed to find the client\n"); + return -ENOENT; } -end: - return ret; + if (mei_connect(dev, &dev->wd_cl)) { + dev_err(&dev->pdev->dev, "wd: failed to connect to the client\n"); + dev->wd_cl.state = MEI_FILE_DISCONNECTED; + dev->wd_cl.host_client_id = 0; + return -EIO; + } + dev->wd_cl.timer_count = CONNECT_TIMEOUT; + + return 0; } /** -- cgit v0.10.2 From 13c398aa5c9a7eae7792726f6229d961e2915b12 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 3 Apr 2012 23:34:59 +0300 Subject: staging/mei: wd.c normalize debug and error messages 1. use wd: prefix for all messages 2. fix strings 3. change from dev_dbg to dev_err where appropriate Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/mei/wd.c b/drivers/staging/mei/wd.c index 032cf67..1e62851 100644 --- a/drivers/staging/mei/wd.c +++ b/drivers/staging/mei/wd.c @@ -47,7 +47,7 @@ const uuid_le mei_wd_guid = UUID_LE(0x05B79A6F, 0x4628, 0x4D7F, 0x89, static void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout) { - dev_dbg(&dev->pdev->dev, "timeout=%d.\n", timeout); + dev_dbg(&dev->pdev->dev, "wd: set timeout=%d.\n", timeout); memcpy(dev->wd_data, mei_start_wd_params, MEI_WD_PARAMS_SIZE); memcpy(dev->wd_data + MEI_WD_PARAMS_SIZE, &timeout, sizeof(u16)); } @@ -154,7 +154,7 @@ int mei_wd_stop(struct mei_device *dev, bool preserve) if (ret) goto out; } else { - dev_dbg(&dev->pdev->dev, "send stop WD failed\n"); + dev_err(&dev->pdev->dev, "wd: send stop failed\n"); } dev->wd_pending = false; @@ -168,13 +168,13 @@ int mei_wd_stop(struct mei_device *dev, bool preserve) dev->wd_stopped, 10 * HZ); mutex_lock(&dev->device_lock); if (dev->wd_stopped) { - dev_dbg(&dev->pdev->dev, "stop wd complete ret=%d.\n", ret); + dev_dbg(&dev->pdev->dev, "wd: stop completed ret=%d.\n", ret); ret = 0; } else { if (!ret) ret = -ETIMEDOUT; dev_warn(&dev->pdev->dev, - "stop wd failed to complete ret=%d.\n", ret); + "wd: stop failed to complete ret=%d.\n", ret); } if (preserve) @@ -203,13 +203,15 @@ static int mei_wd_ops_start(struct watchdog_device *wd_dev) mutex_lock(&dev->device_lock); if (dev->mei_state != MEI_ENABLED) { - dev_dbg(&dev->pdev->dev, "mei_state != MEI_ENABLED mei_state= %d\n", - dev->mei_state); + dev_dbg(&dev->pdev->dev, + "wd: mei_state != MEI_ENABLED mei_state = %d\n", + dev->mei_state); goto end_unlock; } if (dev->wd_cl.state != MEI_FILE_CONNECTED) { - dev_dbg(&dev->pdev->dev, "MEI Driver is not connected to Watchdog Client\n"); + dev_dbg(&dev->pdev->dev, + "MEI Driver is not connected to Watchdog Client\n"); goto end_unlock; } @@ -262,7 +264,7 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev) mutex_lock(&dev->device_lock); if (dev->wd_cl.state != MEI_FILE_CONNECTED) { - dev_dbg(&dev->pdev->dev, "wd is not connected.\n"); + dev_err(&dev->pdev->dev, "wd: not connected.\n"); ret = -ENODEV; goto end; } @@ -272,16 +274,17 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev) mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) { dev->mei_host_buffer_is_empty = false; - dev_dbg(&dev->pdev->dev, "sending watchdog ping\n"); + dev_dbg(&dev->pdev->dev, "wd: sending ping\n"); if (mei_wd_send(dev)) { - dev_dbg(&dev->pdev->dev, "wd send failed.\n"); + dev_err(&dev->pdev->dev, "wd: send failed.\n"); ret = -EIO; goto end; } if (mei_flow_ctrl_reduce(dev, &dev->wd_cl)) { - dev_dbg(&dev->pdev->dev, "mei_flow_ctrl_reduce() failed.\n"); + dev_err(&dev->pdev->dev, + "wd: mei_flow_ctrl_reduce() failed.\n"); ret = -EIO; goto end; } @@ -357,10 +360,12 @@ void mei_watchdog_register(struct mei_device *dev) dev->wd_due_counter = !!dev->wd_timeout; if (watchdog_register_device(&amt_wd_dev)) { - dev_err(&dev->pdev->dev, "unable to register watchdog device.\n"); + dev_err(&dev->pdev->dev, + "wd: unable to register watchdog device.\n"); dev->wd_interface_reg = false; } else { - dev_dbg(&dev->pdev->dev, "successfully register watchdog interface.\n"); + dev_dbg(&dev->pdev->dev, + "wd: successfully register watchdog interface.\n"); dev->wd_interface_reg = true; } } -- cgit v0.10.2 From 68a75f3f1aeae099388f63e4cec3ad08aff8e7da Mon Sep 17 00:00:00 2001 From: Rupesh Gujare Date: Thu, 29 Mar 2012 13:11:50 +0100 Subject: staging: ozwpan: Replace existing event logging mechanism This patch replaces existing event logging mechanism from ioctl to debugfs. This patch replaces previous patch submitted by Chris Kelly. Previous patch can be found at :- http://article.gmane.org/gmane.linux.usb.general/60026/ Signed-off-by: Rupesh Gujare Signed-off-by: Chris Kelly Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ozwpan/ozappif.h b/drivers/staging/ozwpan/ozappif.h index af02732..1b59b07 100644 --- a/drivers/staging/ozwpan/ozappif.h +++ b/drivers/staging/ozwpan/ozappif.h @@ -11,13 +11,13 @@ #define OZ_IOCTL_MAGIC 0xf4 struct oz_mac_addr { - unsigned char a[6]; + __u8 a[6]; }; #define OZ_MAX_PDS 8 struct oz_pd_list { - int count; + __u32 count; struct oz_mac_addr addr[OZ_MAX_PDS]; }; @@ -27,18 +27,10 @@ struct oz_binding_info { char name[OZ_MAX_BINDING_LEN]; }; -struct oz_test { - int action; -}; - #define OZ_IOCTL_GET_PD_LIST _IOR(OZ_IOCTL_MAGIC, 0, struct oz_pd_list) #define OZ_IOCTL_SET_ACTIVE_PD _IOW(OZ_IOCTL_MAGIC, 1, struct oz_mac_addr) #define OZ_IOCTL_GET_ACTIVE_PD _IOR(OZ_IOCTL_MAGIC, 2, struct oz_mac_addr) -#define OZ_IOCTL_CLEAR_EVENTS _IO(OZ_IOCTL_MAGIC, 3) -#define OZ_IOCTL_GET_EVENTS _IOR(OZ_IOCTL_MAGIC, 4, struct oz_evtlist) #define OZ_IOCTL_ADD_BINDING _IOW(OZ_IOCTL_MAGIC, 5, struct oz_binding_info) -#define OZ_IOCTL_TEST _IOWR(OZ_IOCTL_MAGIC, 6, struct oz_test) -#define OZ_IOCTL_SET_EVENT_MASK _IOW(OZ_IOCTL_MAGIC, 7, unsigned long) #define OZ_IOCTL_REMOVE_BINDING _IOW(OZ_IOCTL_MAGIC, 8, struct oz_binding_info) #define OZ_IOCTL_MAX 9 diff --git a/drivers/staging/ozwpan/ozcdev.c b/drivers/staging/ozwpan/ozcdev.c index 1c380d6..27325f7 100644 --- a/drivers/staging/ozwpan/ozcdev.c +++ b/drivers/staging/ozwpan/ozcdev.c @@ -41,9 +41,6 @@ struct oz_serial_ctx { }; /*------------------------------------------------------------------------------ */ -int g_taction; -/*------------------------------------------------------------------------------ - */ static struct oz_cdev g_cdev; /*------------------------------------------------------------------------------ * Context: process and softirq @@ -276,20 +273,6 @@ long oz_cdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return -EFAULT; } break; -#ifdef WANT_EVENT_TRACE - case OZ_IOCTL_CLEAR_EVENTS: - oz_events_clear(); - break; - case OZ_IOCTL_GET_EVENTS: - rc = oz_events_copy((void __user *)arg); - break; - case OZ_IOCTL_SET_EVENT_MASK: - if (copy_from_user(&g_evt_mask, (void __user *)arg, - sizeof(unsigned long))) { - return -EFAULT; - } - break; -#endif /* WANT_EVENT_TRACE */ case OZ_IOCTL_ADD_BINDING: case OZ_IOCTL_REMOVE_BINDING: { struct oz_binding_info b; diff --git a/drivers/staging/ozwpan/ozevent.c b/drivers/staging/ozwpan/ozevent.c index 73703d3..7f66b4f 100644 --- a/drivers/staging/ozwpan/ozevent.c +++ b/drivers/staging/ozwpan/ozevent.c @@ -5,29 +5,46 @@ */ #include "ozconfig.h" #ifdef WANT_EVENT_TRACE +#include +#include #include #include #include "oztrace.h" #include "ozevent.h" +#include "ozappif.h" /*------------------------------------------------------------------------------ + * Although the event mask is logically part of the oz_evtdev structure, it is + * needed outside of this file so define it seperately to avoid the need to + * export definition of struct oz_evtdev. */ -unsigned long g_evt_mask = 0xffffffff; +u32 g_evt_mask; /*------------------------------------------------------------------------------ */ #define OZ_MAX_EVTS 2048 /* Must be power of 2 */ -DEFINE_SPINLOCK(g_eventlock); -static int g_evt_in; -static int g_evt_out; -static int g_missed_events; -static struct oz_event g_events[OZ_MAX_EVTS]; +struct oz_evtdev { + struct dentry *root_dir; + int evt_in; + int evt_out; + int missed_events; + int present; + atomic_t users; + spinlock_t lock; + struct oz_event evts[OZ_MAX_EVTS]; +}; + +static struct oz_evtdev g_evtdev; + /*------------------------------------------------------------------------------ * Context: process */ void oz_event_init(void) { + /* Because g_evtdev is static external all fields initally zero so no + * need to reinitialised those. + */ oz_trace("Event tracing initialized\n"); - g_evt_in = g_evt_out = 0; - g_missed_events = 0; + spin_lock_init(&g_evtdev.lock); + atomic_set(&g_evtdev.users, 0); } /*------------------------------------------------------------------------------ * Context: process @@ -43,74 +60,136 @@ void oz_event_log2(u8 evt, u8 ctx1, u16 ctx2, void *ctx3, unsigned ctx4) { unsigned long irqstate; int ix; - spin_lock_irqsave(&g_eventlock, irqstate); - ix = (g_evt_in + 1) & (OZ_MAX_EVTS - 1); - if (ix != g_evt_out) { - struct oz_event *e = &g_events[g_evt_in]; + spin_lock_irqsave(&g_evtdev.lock, irqstate); + ix = (g_evtdev.evt_in + 1) & (OZ_MAX_EVTS - 1); + if (ix != g_evtdev.evt_out) { + struct oz_event *e = &g_evtdev.evts[g_evtdev.evt_in]; e->jiffies = jiffies; e->evt = evt; e->ctx1 = ctx1; e->ctx2 = ctx2; - e->ctx3 = ctx3; + e->ctx3 = (__u32)(unsigned long)ctx3; e->ctx4 = ctx4; - g_evt_in = ix; + g_evtdev.evt_in = ix; } else { - g_missed_events++; + g_evtdev.missed_events++; } - spin_unlock_irqrestore(&g_eventlock, irqstate); + spin_unlock_irqrestore(&g_evtdev.lock, irqstate); } /*------------------------------------------------------------------------------ * Context: process */ -int oz_events_copy(struct oz_evtlist __user *lst) +static void oz_events_clear(struct oz_evtdev *dev) { - int first; - int ix; - struct hdr { - int count; - int missed; - } hdr; - ix = g_evt_out; - hdr.count = g_evt_in - ix; - if (hdr.count < 0) - hdr.count += OZ_MAX_EVTS; - if (hdr.count > OZ_EVT_LIST_SZ) - hdr.count = OZ_EVT_LIST_SZ; - hdr.missed = g_missed_events; - g_missed_events = 0; - if (copy_to_user((void __user *)lst, &hdr, sizeof(hdr))) - return -EFAULT; - first = OZ_MAX_EVTS - ix; - if (first > hdr.count) - first = hdr.count; - if (first) { - int sz = first*sizeof(struct oz_event); - void __user *p = (void __user *)lst->evts; - if (copy_to_user(p, &g_events[ix], sz)) - return -EFAULT; - if (hdr.count > first) { - p = (void __user *)&lst->evts[first]; - sz = (hdr.count-first)*sizeof(struct oz_event); - if (copy_to_user(p, g_events, sz)) - return -EFAULT; - } + unsigned long irqstate; + oz_trace("Clearing events\n"); + spin_lock_irqsave(&dev->lock, irqstate); + dev->evt_in = dev->evt_out = 0; + dev->missed_events = 0; + spin_unlock_irqrestore(&dev->lock, irqstate); +} +#ifdef CONFIG_DEBUG_FS +/*------------------------------------------------------------------------------ + * Context: process + */ +int oz_events_open(struct inode *inode, struct file *filp) +{ + oz_trace("oz_evt_open()\n"); + oz_trace("Open flags: 0x%x\n", filp->f_flags); + if (atomic_add_return(1, &g_evtdev.users) == 1) { + oz_events_clear(&g_evtdev); + return nonseekable_open(inode, filp); + } else { + atomic_dec(&g_evtdev.users); + return -EBUSY; } - ix += hdr.count; - if (ix >= OZ_MAX_EVTS) - ix -= OZ_MAX_EVTS; - g_evt_out = ix; +} +/*------------------------------------------------------------------------------ + * Context: process + */ +int oz_events_release(struct inode *inode, struct file *filp) +{ + oz_events_clear(&g_evtdev); + atomic_dec(&g_evtdev.users); + g_evt_mask = 0; + oz_trace("oz_evt_release()\n"); return 0; } /*------------------------------------------------------------------------------ * Context: process */ -void oz_events_clear(void) +ssize_t oz_events_read(struct file *filp, char __user *buf, size_t count, + loff_t *fpos) { - unsigned long irqstate; - spin_lock_irqsave(&g_eventlock, irqstate); - g_evt_in = g_evt_out = 0; - g_missed_events = 0; - spin_unlock_irqrestore(&g_eventlock, irqstate); + struct oz_evtdev *dev = &g_evtdev; + int rc = 0; + int nb_evts = count / sizeof(struct oz_event); + int n; + int sz; + + n = dev->evt_in - dev->evt_out; + if (n < 0) + n += OZ_MAX_EVTS; + if (nb_evts > n) + nb_evts = n; + if (nb_evts == 0) + goto out; + n = OZ_MAX_EVTS - dev->evt_out; + if (n > nb_evts) + n = nb_evts; + sz = n * sizeof(struct oz_event); + if (copy_to_user(buf, &dev->evts[dev->evt_out], sz)) { + rc = -EFAULT; + goto out; + } + if (n == nb_evts) + goto out2; + n = nb_evts - n; + if (copy_to_user(buf + sz, dev->evts, n * sizeof(struct oz_event))) { + rc = -EFAULT; + goto out; + } +out2: + dev->evt_out = (dev->evt_out + nb_evts) & (OZ_MAX_EVTS - 1); + rc = nb_evts * sizeof(struct oz_event); +out: + return rc; } -#endif /* WANT_EVENT_TRACE */ +/*------------------------------------------------------------------------------ + */ +const struct file_operations oz_events_fops = { + .owner = THIS_MODULE, + .open = oz_events_open, + .release = oz_events_release, + .read = oz_events_read, +}; +/*------------------------------------------------------------------------------ + * Context: process + */ +void oz_debugfs_init(void) +{ + struct dentry *parent; + parent = debugfs_create_dir("ozwpan", NULL); + if (parent == NULL) { + oz_trace("Failed to create debugfs directory ozmo\n"); + return; + } else { + g_evtdev.root_dir = parent; + if (debugfs_create_file("events", S_IRUSR, parent, NULL, + &oz_events_fops) == NULL) + oz_trace("Failed to create file ozmo/events\n"); + if (debugfs_create_x32("event_mask", S_IRUSR | S_IWUSR, parent, + &g_evt_mask) == NULL) + oz_trace("Failed to create file ozmo/event_mask\n"); + } +} +/*------------------------------------------------------------------------------ + * Context: process + */ +void oz_debugfs_remove(void) +{ + debugfs_remove_recursive(g_evtdev.root_dir); +} +#endif /* CONFIG_DEBUG_FS */ +#endif /* WANT_EVENT_TRACE */ diff --git a/drivers/staging/ozwpan/ozevent.h b/drivers/staging/ozwpan/ozevent.h index f033d01..32f6f98 100644 --- a/drivers/staging/ozwpan/ozevent.h +++ b/drivers/staging/ozwpan/ozevent.h @@ -9,23 +9,24 @@ #include "ozeventdef.h" #ifdef WANT_EVENT_TRACE -extern unsigned long g_evt_mask; +extern u32 g_evt_mask; void oz_event_init(void); void oz_event_term(void); void oz_event_log2(u8 evt, u8 ctx1, u16 ctx2, void *ctx3, unsigned ctx4); +void oz_debugfs_init(void); +void oz_debugfs_remove(void); #define oz_event_log(__evt, __ctx1, __ctx2, __ctx3, __ctx4) \ do { \ if ((1<<(__evt)) & g_evt_mask) \ oz_event_log2(__evt, __ctx1, __ctx2, __ctx3, __ctx4); \ } while (0) -int oz_events_copy(struct oz_evtlist __user *lst); -void oz_events_clear(void); + #else #define oz_event_init() #define oz_event_term() #define oz_event_log(__evt, __ctx1, __ctx2, __ctx3, __ctx4) -#define oz_events_copy(__lst) -#define oz_events_clear() +#define oz_debugfs_init() +#define oz_debugfs_remove() #endif /* WANT_EVENT_TRACE */ #endif /* _OZEVENT_H */ diff --git a/drivers/staging/ozwpan/ozeventdef.h b/drivers/staging/ozwpan/ozeventdef.h index a880288..4b93898 100644 --- a/drivers/staging/ozwpan/ozeventdef.h +++ b/drivers/staging/ozwpan/ozeventdef.h @@ -29,19 +29,12 @@ #define OZ_EVT_DEBUG 20 struct oz_event { - unsigned long jiffies; - unsigned char evt; - unsigned char ctx1; - unsigned short ctx2; - void *ctx3; - unsigned ctx4; -}; - -#define OZ_EVT_LIST_SZ 64 -struct oz_evtlist { - int count; - int missed; - struct oz_event evts[OZ_EVT_LIST_SZ]; + __u32 jiffies; + __u8 evt; + __u8 ctx1; + __u16 ctx2; + __u32 ctx3; + __u32 ctx4; }; #endif /* _OZEVENTDEF_H */ diff --git a/drivers/staging/ozwpan/ozmain.c b/drivers/staging/ozwpan/ozmain.c index aaf2ccc..7579645 100644 --- a/drivers/staging/ozwpan/ozmain.c +++ b/drivers/staging/ozwpan/ozmain.c @@ -33,6 +33,9 @@ static int __init ozwpan_init(void) oz_protocol_init(g_net_dev); oz_app_enable(OZ_APPID_USB, 1); oz_apps_init(); +#ifdef CONFIG_DEBUG_FS + oz_debugfs_init(); +#endif return 0; } /*------------------------------------------------------------------------------ @@ -44,6 +47,9 @@ static void __exit ozwpan_exit(void) oz_apps_term(); oz_cdev_deregister(); oz_event_term(); +#ifdef CONFIG_DEBUG_FS + oz_debugfs_remove(); +#endif } /*------------------------------------------------------------------------------ */ @@ -53,6 +59,6 @@ module_exit(ozwpan_exit); MODULE_AUTHOR("Chris Kelly"); MODULE_DESCRIPTION("Ozmo Devices USB over WiFi hcd driver"); -MODULE_VERSION("1.0.8"); +MODULE_VERSION("1.0.9"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 1c3a4dc3d01547103a81957d41f105d462f42c4d Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 21 Mar 2012 16:40:23 -0500 Subject: staging: omap/drm: dmm should return proper errors Minor error path clean-up. Signed-off-by: Rob Clark Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c b/drivers/staging/omapdrm/omap_dmm_tiler.c index 1ecb6a7..9d83060 100644 --- a/drivers/staging/omapdrm/omap_dmm_tiler.c +++ b/drivers/staging/omapdrm/omap_dmm_tiler.c @@ -347,7 +347,7 @@ struct tiler_block *tiler_reserve_2d(enum tiler_fmt fmt, uint16_t w, ret = tcm_reserve_2d(containers[fmt], w, h, align, &block->area); if (ret) { kfree(block); - return 0; + return ERR_PTR(-ENOMEM); } /* add to allocation list */ @@ -371,7 +371,7 @@ struct tiler_block *tiler_reserve_1d(size_t size) if (tcm_reserve_1d(containers[TILFMT_PAGE], num_pages, &block->area)) { kfree(block); - return 0; + return ERR_PTR(-ENOMEM); } spin_lock(&omap_dmm->list_lock); -- cgit v0.10.2 From e06d9b3e6c0f5617fe14e137a6121c5e59edf497 Mon Sep 17 00:00:00 2001 From: wwang Date: Tue, 27 Mar 2012 16:42:42 +0800 Subject: staging:rts_pstor:Fix unbalanced parentheses Signed-off-by: wwang Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/ms.c b/drivers/staging/rts_pstor/ms.c index 66341df..e098a90 100644 --- a/drivers/staging/rts_pstor/ms.c +++ b/drivers/staging/rts_pstor/ms.c @@ -4135,7 +4135,7 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip) #else retval = ms_transfer_data(chip, MS_TM_AUTO_WRITE, PRO_WRITE_LONG_DATA, 2, WAIT_INT, 0, 0, buf + 4, 1024); - if ((retval != STATUS_SUCCESS) || check_ms_err(chip) { + if ((retval != STATUS_SUCCESS) || check_ms_err(chip)) { rtsx_clear_ms_error(chip); if (ms_card->mg_auth == 0) { if ((buf[5] & 0xC0) != 0) { -- cgit v0.10.2 From 215c47c931d2e22f05bbff31ebf9325f7479fcf5 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 26 Mar 2012 21:34:18 -0700 Subject: staging:octeon Fix typos in staging:octeon The below patch is a resend to fix some typos and comments that I have found while reading. Signed-off-by: Justin P. Mattock Acked-by: David Daney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c index 400df8c..5699e6f 100644 --- a/drivers/staging/octeon/ethernet-rx.c +++ b/drivers/staging/octeon/ethernet-rx.c @@ -162,7 +162,7 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) /* * We received a packet with either an alignment error * or a FCS error. This may be signalling that we are - * running 10Mbps with GMXX_RXX_FRM_CTL[PRE_CHK} + * running 10Mbps with GMXX_RXX_FRM_CTL[PRE_CHK] * off. If this is the case we need to parse the * packet to determine if we can remove a non spec * preamble and generate a correct packet. diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c index 56d74dc..445cdba 100644 --- a/drivers/staging/octeon/ethernet-tx.c +++ b/drivers/staging/octeon/ethernet-tx.c @@ -61,7 +61,7 @@ * You can define GET_SKBUFF_QOS() to override how the skbuff output * function determines which output queue is used. The default * implementation always uses the base queue for the port. If, for - * example, you wanted to use the skb->priority fieid, define + * example, you wanted to use the skb->priority field, define * GET_SKBUFF_QOS as: #define GET_SKBUFF_QOS(skb) ((skb)->priority) */ #ifndef GET_SKBUFF_QOS @@ -164,8 +164,8 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) #endif /* - * Prefetch the private data structure. It is larger that one - * cache line. + * Prefetch the private data structure. It is larger than the + * one cache line. */ prefetch(priv); @@ -290,8 +290,8 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) * See if we can put this skb in the FPA pool. Any strange * behavior from the Linux networking stack will most likely * be caused by a bug in the following code. If some field is - * in use by the network stack and get carried over when a - * buffer is reused, bad thing may happen. If in doubt and + * in use by the network stack and gets carried over when a + * buffer is reused, bad things may happen. If in doubt and * you dont need the absolute best performance, disable the * define REUSE_SKBUFFS_WITHOUT_FREE. The reuse of buffers has * shown a 25% increase in performance under some loads. diff --git a/drivers/staging/octeon/ethernet-util.h b/drivers/staging/octeon/ethernet-util.h index 144fb99..2da5ce1 100644 --- a/drivers/staging/octeon/ethernet-util.h +++ b/drivers/staging/octeon/ethernet-util.h @@ -38,7 +38,7 @@ static inline void *cvm_oct_get_buffer_ptr(union cvmx_buf_ptr packet_ptr) } /** - * INTERFACE - convert IPD port to locgical interface + * INTERFACE - convert IPD port to logical interface * @ipd_port: Port to check * * Returns Logical interface diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index 9112cd8..4d70acf 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c @@ -356,7 +356,7 @@ static void cvm_oct_common_set_multicast_list(struct net_device *dev) /* Force accept multicast packets */ control.s.mcst = 2; else - /* Force reject multicat packets */ + /* Force reject multicast packets */ control.s.mcst = 1; if (dev->flags & IFF_PROMISC) -- cgit v0.10.2 From 277ac73720628f032c34c1e8b157a6ae2077766f Mon Sep 17 00:00:00 2001 From: Hitoshi NAKAMORI Date: Mon, 26 Mar 2012 14:34:50 +0900 Subject: Staging:rts_pstor: fix coding style issue in rtsx_transport.c This patch changes the space of the indent to the tab that warning found by the checkpatch.pl tool. Signed-off-by: Hitoshi NAKAMORI Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts_pstor/rtsx_transport.c b/drivers/staging/rts_pstor/rtsx_transport.c index 4e3d2c1..488f950 100644 --- a/drivers/staging/rts_pstor/rtsx_transport.c +++ b/drivers/staging/rts_pstor/rtsx_transport.c @@ -130,7 +130,7 @@ unsigned int rtsx_stor_access_xfer_buf(unsigned char *buffer, /* Store the contents of buffer into srb's transfer buffer and set the * SCSI residue. */ void rtsx_stor_set_xfer_buf(unsigned char *buffer, - unsigned int buflen, struct scsi_cmnd *srb) + unsigned int buflen, struct scsi_cmnd *srb) { unsigned int index = 0, offset = 0; @@ -141,7 +141,7 @@ void rtsx_stor_set_xfer_buf(unsigned char *buffer, } void rtsx_stor_get_xfer_buf(unsigned char *buffer, - unsigned int buflen, struct scsi_cmnd *srb) + unsigned int buflen, struct scsi_cmnd *srb) { unsigned int index = 0, offset = 0; -- cgit v0.10.2 From 310c6a762e224ae38efac304c936b82ad89a4ff1 Mon Sep 17 00:00:00 2001 From: Santosh Nayak Date: Fri, 23 Mar 2012 21:14:02 +0530 Subject: staging: wlags49_h2: Replace kmalloc+memset by kzalloc and add error handling. Replace kmalloc+memset pair by kzalloc() in 'wl_wds_device_alloc()'. Add error handling to avoid null derefernce. Signed-off-by: Santosh Nayak Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c index 90820ff..6a44cb8 100644 --- a/drivers/staging/wlags49_h2/wl_netdev.c +++ b/drivers/staging/wlags49_h2/wl_netdev.c @@ -1510,8 +1510,11 @@ void wl_wds_device_alloc( struct wl_private *lp ) for( count = 0; count < NUM_WDS_PORTS; count++ ) { struct net_device *dev_wds = NULL; - dev_wds = kmalloc( sizeof( struct net_device ), GFP_KERNEL ); - memset( dev_wds, 0, sizeof( struct net_device )); + dev_wds = kzalloc(sizeof(struct net_device), GFP_KERNEL); + if (!dev_wds) { + DBG_LEAVE(DbgInfo); + return; + } ether_setup( dev_wds ); -- cgit v0.10.2 From 2f5c638ced00fff2356ce0a02f16c8e928259750 Mon Sep 17 00:00:00 2001 From: Christopher Harvey Date: Fri, 23 Mar 2012 10:55:25 -0400 Subject: staging: usbip: fix potential segfault because of unchecked return value of strchr. This doesn't happen with the usbip virtual hci module, but another module wanting to interface with this user space code could cause a seg-fault by sending data without newlines. Signed-off-by: Christopher Harvey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c index 2697877..0958ba5 100644 --- a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c +++ b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c @@ -59,7 +59,10 @@ static int parse_status(char *value) /* skip a header line */ - c = strchr(value, '\n') + 1; + c = strchr(value, '\n'); + if (!c) + return -1; + c++; while (*c != '\0') { int port, status, speed, devid; @@ -109,7 +112,10 @@ static int parse_status(char *value) /* go to the next line */ - c = strchr(c, '\n') + 1; + c = strchr(c, '\n'); + if (!c) + break; + c++; } dbg("exit"); @@ -264,11 +270,17 @@ static int get_nports(void) attr_status->method, attr_status->value); /* skip a header line */ - c = strchr(attr_status->value, '\n') + 1; + c = strchr(attr_status->value, '\n'); + if (!c) + return 0; + c++; while (*c != '\0') { /* go to the next line */ - c = strchr(c, '\n') + 1; + c = strchr(c, '\n'); + if (!c) + return nports; + c++; nports += 1; } -- cgit v0.10.2 From 3567f97965aa58b6acdfaf1ac86eed62905369ea Mon Sep 17 00:00:00 2001 From: Christopher Harvey Date: Thu, 22 Mar 2012 16:57:50 -0400 Subject: staging: usbip: Fix typo in printed text Signed-off-by: Christopher Harvey Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c index f5fba732..f0eaf04 100644 --- a/drivers/staging/usbip/vhci_rx.c +++ b/drivers/staging/usbip/vhci_rx.c @@ -162,7 +162,7 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev, * already received the result of its submit result and gave * back the URB. */ - pr_info("the urb (seqnum %d) was already given backed\n", + pr_info("the urb (seqnum %d) was already given back\n", pdu->base.seqnum); } else { usbip_dbg_vhci_rx("now giveback urb %p\n", urb); -- cgit v0.10.2 From ef23b21061bb26469646f9ad9f1c6584ca0c5b49 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Mon, 19 Mar 2012 21:50:11 +0400 Subject: staging/xgifb: remove unused variable In function XGIfb_do_set_var() remove unused variable sr_data. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 21c0378..641fd8d 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1088,7 +1088,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin + var->vsync_len; #if defined(__powerpc__) - u8 sr_data, cr_data; + u8 cr_data; #endif unsigned int drate = 0, hrate = 0; int found_mode = 0; -- cgit v0.10.2 From 30b768161564891a5109db1520bfc954ca2b3649 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Mon, 19 Mar 2012 21:50:12 +0400 Subject: staging/xgifb: drop RelIO from vb_device_info The RelIO field is unused in the driver, drop it. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 641fd8d..bc542a5 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -358,7 +358,6 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr) { - XGI_Pr->RelIO = BaseAddr; XGI_Pr->P3c4 = BaseAddr + 0x14; XGI_Pr->P3d4 = BaseAddr + 0x24; XGI_Pr->P3c0 = BaseAddr + 0x10; @@ -1911,11 +1910,9 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, xgifb_info->mmio_base = pci_resource_start(pdev, 1); xgifb_info->mmio_size = pci_resource_len(pdev, 1); xgifb_info->vga_base = pci_resource_start(pdev, 2) + 0x30; - hw_info->pjIOAddress = (unsigned char *)xgifb_info->vga_base; - /* XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */ pr_info("Relocate IO address: %lx [%08lx]\n", (unsigned long)pci_resource_start(pdev, 2), - xgifb_info->dev_info.RelIO); + xgifb_info->vga_base); if (pci_enable_device(pdev)) { ret = -EIO; diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index a5bd56a..9287658 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -236,7 +236,6 @@ struct vb_device_info { void __iomem *FBAddr; unsigned long BaseAddr; - unsigned long RelIO; unsigned char (*CR6B)[4]; unsigned char (*CR6E)[4]; -- cgit v0.10.2 From 9a801f252a1695d85da53845daf6e21671bf72ed Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Mon, 19 Mar 2012 21:50:13 +0400 Subject: staging/xgifb: simplify vga I/O ports handling XGIfb driver transfers integer port number through several typecasts via pjIOAddress field. Drop that field completely and use vga_base field of xgifb_info directly. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index bc542a5..c55240b 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1924,7 +1924,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, xgifb_info->display2_force = true; } - XGIRegInit(&xgifb_info->dev_info, (unsigned long)hw_info->pjIOAddress); + XGIRegInit(&xgifb_info->dev_info, xgifb_info->vga_base); xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD); reg1 = xgifb_reg_get(XGISR, IND_SIS_PASSWORD); diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 94d5c35..a951ca4 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -1478,7 +1478,7 @@ unsigned char XGIInitNew(struct pci_dev *pdev) pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; - pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress; + pVBInfo->BaseAddr = xgifb_info->vga_base; /* Newdebugcode(0x99); */ diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 2919924..5a00e94 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -7387,7 +7387,7 @@ unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info, unsigned short ModeIdIndex; struct vb_device_info VBINF; struct vb_device_info *pVBInfo = &VBINF; - pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress; + pVBInfo->BaseAddr = xgifb_info->vga_base; pVBInfo->IF_DEF_LVDS = 0; pVBInfo->IF_DEF_LCDA = 1; diff --git a/drivers/staging/xgifb/vgatypes.h b/drivers/staging/xgifb/vgatypes.h index a7208e3..30cdd1a 100644 --- a/drivers/staging/xgifb/vgatypes.h +++ b/drivers/staging/xgifb/vgatypes.h @@ -66,8 +66,6 @@ struct xgi_hw_device_info { unsigned long ulVideoMemorySize; /* size, in bytes, of the memory on the board */ - unsigned char *pjIOAddress; /* base I/O address of VGA ports (0x3B0) */ - unsigned char jChipType; /* Used to Identify Graphics Chip */ /* defined in the data structure type */ /* "XGI_CHIP_TYPE" */ -- cgit v0.10.2 From f650caaa49c774df0bf15a9f99168db93c7a92e8 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Mon, 19 Mar 2012 21:50:14 +0400 Subject: staging/xgifb: fix addressing issues on platform with long physical addressing Some platforms (e.g. ppc460ex) have 36-bit physical addressing, while sizeof(unsigned long) == 4. Adapt xgifb driver to use phys_addr_t for physical address variables instead of unsigned long. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index c55240b..1c93a03 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1910,8 +1910,8 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, xgifb_info->mmio_base = pci_resource_start(pdev, 1); xgifb_info->mmio_size = pci_resource_len(pdev, 1); xgifb_info->vga_base = pci_resource_start(pdev, 2) + 0x30; - pr_info("Relocate IO address: %lx [%08lx]\n", - (unsigned long)pci_resource_start(pdev, 2), + pr_info("Relocate IO address: %Lx [%08lx]\n", + (u64) pci_resource_start(pdev, 2), xgifb_info->vga_base); if (pci_enable_device(pdev)) { @@ -2003,13 +2003,13 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, xgifb_info->mmio_vbase = ioremap(xgifb_info->mmio_base, xgifb_info->mmio_size); - pr_info("Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n", - xgifb_info->video_base, + pr_info("Framebuffer at 0x%Lx, mapped to 0x%p, size %dk\n", + (u64) xgifb_info->video_base, xgifb_info->video_vbase, xgifb_info->video_size / 1024); - pr_info("MMIO at 0x%lx, mapped to 0x%p, size %ldk\n", - xgifb_info->mmio_base, xgifb_info->mmio_vbase, + pr_info("MMIO at 0x%Lx, mapped to 0x%p, size %ldk\n", + (u64) xgifb_info->mmio_base, xgifb_info->mmio_vbase, xgifb_info->mmio_size / 1024); pci_set_drvdata(pdev, xgifb_info); diff --git a/drivers/staging/xgifb/XGIfb.h b/drivers/staging/xgifb/XGIfb.h index 37bb730..bea222d 100644 --- a/drivers/staging/xgifb/XGIfb.h +++ b/drivers/staging/xgifb/XGIfb.h @@ -66,9 +66,9 @@ struct xgifb_video_info { int chip_id; unsigned int video_size; - unsigned long video_base; + phys_addr_t video_base; void __iomem *video_vbase; - unsigned long mmio_base; + phys_addr_t mmio_base; unsigned long mmio_size; void __iomem *mmio_vbase; unsigned long vga_base; -- cgit v0.10.2 From 3a05de3304d9f8dd02d4e6d987e978f64bc8943c Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:13:47 +0300 Subject: staging: xgifb: XGIfb_mode_rate_to_ddata: delete commented-out code Delete code that has been commented out. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 1c93a03..c703b83 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -201,14 +201,6 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr); RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, ModeIdIndex, XGI_Pr); - /* - temp = XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr); - if (!temp) - return 0; - - RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex; - RefreshRateTableIndex += (rateindex - 1); - */ index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5]; @@ -219,12 +211,6 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8); A = HT + 5; - /* - cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1]; - - Horizontal display enable end - HDE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x0C) << 6); - */ HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1; E = HDE + 1; -- cgit v0.10.2 From 051ff1bb3cb30e5e94d402fe5c9c1fdf4f9cd24c Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:13:48 +0300 Subject: staging: xgifb: XGIfb_mode_rate_to_ddata: initialize ModeIdIndex properly Initialize ModeIdIndex according to the selected video mode. Currently index 0 is always used and wrong video mode data may be used. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index c703b83..67323b1 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -190,7 +190,7 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, u32 *vmode) { unsigned short ModeNo = modeno; - unsigned short ModeIdIndex = 0, index = 0; + unsigned short ModeIdIndex, index = 0; unsigned short RefreshRateTableIndex = 0; unsigned short VRE, VBE, VRS, VBS, VDE, VT; @@ -199,6 +199,8 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, unsigned long cr_data3; int A, B, C, D, E, F, temp, j; InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr); + if (!XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr)) + return 0; RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, ModeIdIndex, XGI_Pr); index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; -- cgit v0.10.2 From e484975a2321ec6e86fa4b0e02f2b61875b67e2b Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:13:49 +0300 Subject: staging: xgifb: XGIfb_mode_rate_to_dclock: delete commented-out code Delete code that has been commented out. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 67323b1..50f5b9e 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -156,25 +156,12 @@ static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr, unsigned short ModeNo = modeno; unsigned short ModeIdIndex = 0, ClockIndex = 0; unsigned short RefreshRateTableIndex = 0; - - /* unsigned long temp = 0; */ int Clock; InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr); RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, ModeIdIndex, XGI_Pr); - /* - temp = XGI_SearchModeID(ModeNo , &ModeIdIndex, XGI_Pr) ; - if (!temp) { - printk(KERN_ERR "Could not find mode %x\n", ModeNo); - return 65000; - } - - RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex; - RefreshRateTableIndex += (rateindex - 1); - - */ ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000; -- cgit v0.10.2 From aca03bcc29b5848206985446a496f683fcccb268 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:13:50 +0300 Subject: staging: xgifb: XGIfb_mode_rate_to_dclock: initialize ModeIdIndex properly Initialize ModeIdIndex according to the selected video mode. Currently index 0 is always used and wrong clock data may be used. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 50f5b9e..055acb3 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -159,6 +159,8 @@ static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr, int Clock; InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr); + XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr); + RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, ModeIdIndex, XGI_Pr); -- cgit v0.10.2 From 18408da0e865537742dda474045abf88a49032f6 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:13:51 +0300 Subject: staging: xgifb: drop XG41 code XG_41 is not listed in xgifb_pci_table, so the code can be safely dropped. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index e828fd4..7621bbf 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -12,9 +12,6 @@ #define XGIFAIL(x) do { printk(x "\n"); return -EINVAL; } while (0) -#ifndef PCI_DEVICE_ID_XGI_41 -#define PCI_DEVICE_ID_XGI_41 0x041 -#endif #ifndef PCI_DEVICE_ID_XGI_42 #define PCI_DEVICE_ID_XGI_42 0x042 #endif diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 055acb3..8d10952 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1924,9 +1924,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, case PCI_DEVICE_ID_XGI_40: xgifb_info->chip = XG40; break; - case PCI_DEVICE_ID_XGI_41: - xgifb_info->chip = XG41; - break; case PCI_DEVICE_ID_XGI_42: xgifb_info->chip = XG42; break; diff --git a/drivers/staging/xgifb/XGIfb.h b/drivers/staging/xgifb/XGIfb.h index bea222d..223ba66 100644 --- a/drivers/staging/xgifb/XGIfb.h +++ b/drivers/staging/xgifb/XGIfb.h @@ -23,7 +23,6 @@ enum xgifb_display_type { enum XGI_CHIP_TYPE { XG40 = 32, - XG41, XG42, XG45, XG20 = 48, diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index a951ca4..0c2c017 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -353,7 +353,6 @@ static void XGINew_DDR1x_DefaultRegister( XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo); switch (HwDeviceExtension->jChipType) { - case XG41: case XG42: /* CR82 */ xgifb_reg_set(P3d4, @@ -556,8 +555,7 @@ static void XGINew_SetDRAMDefaultRegister340( xgifb_reg_set(P3d4, (0x8A + j), pVBInfo->CR40[1 + j][pVBInfo->ram_type]); - if ((HwDeviceExtension->jChipType == XG41) || - (HwDeviceExtension->jChipType == XG42)) + if (HwDeviceExtension->jChipType == XG42) xgifb_reg_set(P3d4, 0x8C, 0x87); xgifb_reg_set(P3d4, @@ -854,78 +852,6 @@ static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, pVBInfo->ram_channel = 1; /* Single channel */ xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x51); /* 32Mx16 bit*/ break; - case XG41: - if (XGINew_CheckFrequence(pVBInfo) == 1) { - pVBInfo->ram_bus = 32; /* 32 bits */ - pVBInfo->ram_channel = 3; /* Quad Channel */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x4C); - - if (XGINew_ReadWriteRest(25, 23, pVBInfo) == 1) - return; - - pVBInfo->ram_channel = 2; /* Dual channels */ - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x48); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x49); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - - pVBInfo->ram_channel = 3; - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x3C); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x38); - - if (XGINew_ReadWriteRest(8, 4, pVBInfo) == 1) - return; - else - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x39); - } else { /* DDR */ - pVBInfo->ram_bus = 64; /* 64 bits */ - pVBInfo->ram_channel = 2; /* Dual channels */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x5A); - - if (XGINew_ReadWriteRest(25, 24, pVBInfo) == 1) - return; - - pVBInfo->ram_channel = 1; /* Single channels */ - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x52); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x53); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - - pVBInfo->ram_channel = 2; /* Dual channels */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x4A); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - - pVBInfo->ram_channel = 1; /* Single channels */ - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x42); - - if (XGINew_ReadWriteRest(8, 4, pVBInfo) == 1) - return; - else - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x43); - } - - break; - case XG42: /* XG42 SR14 D[3] Reserve -- cgit v0.10.2 From c38d044bf295b99e90a187a1075a01d4d7c52aeb Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:13:52 +0300 Subject: staging: xgifb: drop XG45 code XG45 is not recognized/supported by the driver. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 8d10952..3eeb58a 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1656,17 +1656,6 @@ static int XGIfb_get_dram_size(struct xgifb_video_info *xgifb_info) ChannelNum = 1; break; - case XG45: - if (tmp == 1) - ChannelNum = 2; - else if (tmp == 2) - ChannelNum = 3; - else if (tmp == 3) - ChannelNum = 4; - else - ChannelNum = 1; - break; - case XG40: default: if (tmp == 2) diff --git a/drivers/staging/xgifb/XGIfb.h b/drivers/staging/xgifb/XGIfb.h index 223ba66..9068c5a 100644 --- a/drivers/staging/xgifb/XGIfb.h +++ b/drivers/staging/xgifb/XGIfb.h @@ -24,7 +24,6 @@ enum xgifb_display_type { enum XGI_CHIP_TYPE { XG40 = 32, XG42, - XG45, XG20 = 48, XG21, XG27, -- cgit v0.10.2 From b07b3a90599e6032103c76bed8f03ba1327f54b9 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:13:53 +0300 Subject: staging: xgifb: delete XGI300paneltype Delete unused table. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index 7621bbf..513e4e0 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -243,13 +243,6 @@ static const struct _XGIbios_mode { {"\0", 0x00, 0, 0, 0, 0, 0, 0, 0} }; -/* TW: CR36 evaluation */ -static const unsigned short XGI300paneltype[] = { - LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024, - LCD_1280x960, LCD_640x480, LCD_1024x600, LCD_1152x768, - LCD_1024x768, LCD_1024x768, LCD_1024x768, - LCD_1024x768, LCD_1024x768, LCD_1024x768, LCD_1024x768}; - static const unsigned short XGI310paneltype[] = { LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024, LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960, -- cgit v0.10.2 From f47f12d62141b39581e6e099c2210b5ae5b4ab0c Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:13:54 +0300 Subject: staging: xgifb: delete rate_idx from mode table The default rate_idx is same for all video modes, no need to keep that in the table. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index 513e4e0..ae778a1 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -91,156 +91,155 @@ static const struct _XGIbios_mode { u16 xres; u16 yres; u16 bpp; - u16 rate_idx; u16 cols; u16 rows; u8 chipset; } XGIbios_mode[] = { - {"320x240x16", 0x56, 0x0000, 0x0000, 320, 240, 16, 1, 40, 15, + {"320x240x16", 0x56, 0x0000, 0x0000, 320, 240, 16, 40, 15, MD_XGI315}, - {"320x480x8", 0x5A, 0x0000, 0x0000, 320, 480, 8, 1, 40, 30, + {"320x480x8", 0x5A, 0x0000, 0x0000, 320, 480, 8, 40, 30, MD_XGI315}, /* TW: FSTN */ - {"320x480x16", 0x5B, 0x0000, 0x0000, 320, 480, 16, 1, 40, 30, + {"320x480x16", 0x5B, 0x0000, 0x0000, 320, 480, 16, 40, 30, MD_XGI315}, /* TW: FSTN */ - {"640x480x8", 0x2E, 0x0101, 0x0101, 640, 480, 8, 1, 80, 30, + {"640x480x8", 0x2E, 0x0101, 0x0101, 640, 480, 8, 80, 30, MD_XGI300|MD_XGI315}, - {"640x480x16", 0x44, 0x0111, 0x0111, 640, 480, 16, 1, 80, 30, + {"640x480x16", 0x44, 0x0111, 0x0111, 640, 480, 16, 80, 30, MD_XGI300|MD_XGI315}, - {"640x480x24", 0x62, 0x013a, 0x0112, 640, 480, 32, 1, 80, 30, + {"640x480x24", 0x62, 0x013a, 0x0112, 640, 480, 32, 80, 30, MD_XGI300|MD_XGI315}, /* TW: That's for people who mix up color- and fb depth */ - {"640x480x32", 0x62, 0x013a, 0x0112, 640, 480, 32, 1, 80, 30, + {"640x480x32", 0x62, 0x013a, 0x0112, 640, 480, 32, 80, 30, MD_XGI300|MD_XGI315}, - {"720x480x8", 0x31, 0x0000, 0x0000, 720, 480, 8, 1, 90, 30, + {"720x480x8", 0x31, 0x0000, 0x0000, 720, 480, 8, 90, 30, MD_XGI300|MD_XGI315}, - {"720x480x16", 0x33, 0x0000, 0x0000, 720, 480, 16, 1, 90, 30, + {"720x480x16", 0x33, 0x0000, 0x0000, 720, 480, 16, 90, 30, MD_XGI300|MD_XGI315}, - {"720x480x24", 0x35, 0x0000, 0x0000, 720, 480, 32, 1, 90, 30, + {"720x480x24", 0x35, 0x0000, 0x0000, 720, 480, 32, 90, 30, MD_XGI300|MD_XGI315}, - {"720x480x32", 0x35, 0x0000, 0x0000, 720, 480, 32, 1, 90, 30, + {"720x480x32", 0x35, 0x0000, 0x0000, 720, 480, 32, 90, 30, MD_XGI300|MD_XGI315}, - {"720x576x8", 0x32, 0x0000, 0x0000, 720, 576, 8, 1, 90, 36, + {"720x576x8", 0x32, 0x0000, 0x0000, 720, 576, 8, 90, 36, MD_XGI300|MD_XGI315}, - {"720x576x16", 0x34, 0x0000, 0x0000, 720, 576, 16, 1, 90, 36, + {"720x576x16", 0x34, 0x0000, 0x0000, 720, 576, 16, 90, 36, MD_XGI300|MD_XGI315}, - {"720x576x24", 0x36, 0x0000, 0x0000, 720, 576, 32, 1, 90, 36, + {"720x576x24", 0x36, 0x0000, 0x0000, 720, 576, 32, 90, 36, MD_XGI300|MD_XGI315}, - {"720x576x32", 0x36, 0x0000, 0x0000, 720, 576, 32, 1, 90, 36, + {"720x576x32", 0x36, 0x0000, 0x0000, 720, 576, 32, 90, 36, MD_XGI300|MD_XGI315}, - {"800x480x8", 0x70, 0x0000, 0x0000, 800, 480, 8, 1, 100, 30, + {"800x480x8", 0x70, 0x0000, 0x0000, 800, 480, 8, 100, 30, MD_XGI300|MD_XGI315}, - {"800x480x16", 0x7a, 0x0000, 0x0000, 800, 480, 16, 1, 100, 30, + {"800x480x16", 0x7a, 0x0000, 0x0000, 800, 480, 16, 100, 30, MD_XGI300|MD_XGI315}, - {"800x480x24", 0x76, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, + {"800x480x24", 0x76, 0x0000, 0x0000, 800, 480, 32, 100, 30, MD_XGI300|MD_XGI315}, - {"800x480x32", 0x76, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, + {"800x480x32", 0x76, 0x0000, 0x0000, 800, 480, 32, 100, 30, MD_XGI300|MD_XGI315}, - {"800x600x8", 0x30, 0x0103, 0x0103, 800, 600, 8, 1, 100, 37, + {"800x600x8", 0x30, 0x0103, 0x0103, 800, 600, 8, 100, 37, MD_XGI300|MD_XGI315}, #define DEFAULT_MODE 20 /* index for 800x600x16 */ - {"800x600x16", 0x47, 0x0114, 0x0114, 800, 600, 16, 1, 100, 37, + {"800x600x16", 0x47, 0x0114, 0x0114, 800, 600, 16, 100, 37, MD_XGI300|MD_XGI315}, - {"800x600x24", 0x63, 0x013b, 0x0115, 800, 600, 32, 1, 100, 37, + {"800x600x24", 0x63, 0x013b, 0x0115, 800, 600, 32, 100, 37, MD_XGI300|MD_XGI315}, - {"800x600x32", 0x63, 0x013b, 0x0115, 800, 600, 32, 1, 100, 37, + {"800x600x32", 0x63, 0x013b, 0x0115, 800, 600, 32, 100, 37, MD_XGI300|MD_XGI315}, - {"1024x576x8", 0x71, 0x0000, 0x0000, 1024, 576, 8, 1, 128, 36, + {"1024x576x8", 0x71, 0x0000, 0x0000, 1024, 576, 8, 128, 36, MD_XGI300|MD_XGI315}, - {"1024x576x16", 0x74, 0x0000, 0x0000, 1024, 576, 16, 1, 128, 36, + {"1024x576x16", 0x74, 0x0000, 0x0000, 1024, 576, 16, 128, 36, MD_XGI300|MD_XGI315}, - {"1024x576x24", 0x77, 0x0000, 0x0000, 1024, 576, 32, 1, 128, 36, + {"1024x576x24", 0x77, 0x0000, 0x0000, 1024, 576, 32, 128, 36, MD_XGI300|MD_XGI315}, - {"1024x576x32", 0x77, 0x0000, 0x0000, 1024, 576, 32, 1, 128, 36, + {"1024x576x32", 0x77, 0x0000, 0x0000, 1024, 576, 32, 128, 36, MD_XGI300|MD_XGI315}, - {"1024x600x8", 0x20, 0x0000, 0x0000, 1024, 600, 8, 1, 128, 37, + {"1024x600x8", 0x20, 0x0000, 0x0000, 1024, 600, 8, 128, 37, MD_XGI300 }, /* TW: 300 series only */ - {"1024x600x16", 0x21, 0x0000, 0x0000, 1024, 600, 16, 1, 128, 37, + {"1024x600x16", 0x21, 0x0000, 0x0000, 1024, 600, 16, 128, 37, MD_XGI300 }, - {"1024x600x24", 0x22, 0x0000, 0x0000, 1024, 600, 32, 1, 128, 37, + {"1024x600x24", 0x22, 0x0000, 0x0000, 1024, 600, 32, 128, 37, MD_XGI300 }, - {"1024x600x32", 0x22, 0x0000, 0x0000, 1024, 600, 32, 1, 128, 37, + {"1024x600x32", 0x22, 0x0000, 0x0000, 1024, 600, 32, 128, 37, MD_XGI300 }, - {"1024x768x8", 0x38, 0x0105, 0x0105, 1024, 768, 8, 1, 128, 48, + {"1024x768x8", 0x38, 0x0105, 0x0105, 1024, 768, 8, 128, 48, MD_XGI300|MD_XGI315}, - {"1024x768x16", 0x4A, 0x0117, 0x0117, 1024, 768, 16, 1, 128, 48, + {"1024x768x16", 0x4A, 0x0117, 0x0117, 1024, 768, 16, 128, 48, MD_XGI300|MD_XGI315}, - {"1024x768x24", 0x64, 0x013c, 0x0118, 1024, 768, 32, 1, 128, 48, + {"1024x768x24", 0x64, 0x013c, 0x0118, 1024, 768, 32, 128, 48, MD_XGI300|MD_XGI315}, - {"1024x768x32", 0x64, 0x013c, 0x0118, 1024, 768, 32, 1, 128, 48, + {"1024x768x32", 0x64, 0x013c, 0x0118, 1024, 768, 32, 128, 48, MD_XGI300|MD_XGI315}, - {"1152x768x8", 0x23, 0x0000, 0x0000, 1152, 768, 8, 1, 144, 48, + {"1152x768x8", 0x23, 0x0000, 0x0000, 1152, 768, 8, 144, 48, MD_XGI300 }, /* TW: 300 series only */ - {"1152x768x16", 0x24, 0x0000, 0x0000, 1152, 768, 16, 1, 144, 48, + {"1152x768x16", 0x24, 0x0000, 0x0000, 1152, 768, 16, 144, 48, MD_XGI300 }, - {"1152x768x24", 0x25, 0x0000, 0x0000, 1152, 768, 32, 1, 144, 48, + {"1152x768x24", 0x25, 0x0000, 0x0000, 1152, 768, 32, 144, 48, MD_XGI300 }, - {"1152x768x32", 0x25, 0x0000, 0x0000, 1152, 768, 32, 1, 144, 48, + {"1152x768x32", 0x25, 0x0000, 0x0000, 1152, 768, 32, 144, 48, MD_XGI300 }, - {"1280x720x8", 0x79, 0x0000, 0x0000, 1280, 720, 8, 1, 160, 45, + {"1280x720x8", 0x79, 0x0000, 0x0000, 1280, 720, 8, 160, 45, MD_XGI300|MD_XGI315}, - {"1280x720x16", 0x75, 0x0000, 0x0000, 1280, 720, 16, 1, 160, 45, + {"1280x720x16", 0x75, 0x0000, 0x0000, 1280, 720, 16, 160, 45, MD_XGI300|MD_XGI315}, - {"1280x720x24", 0x78, 0x0000, 0x0000, 1280, 720, 32, 1, 160, 45, + {"1280x720x24", 0x78, 0x0000, 0x0000, 1280, 720, 32, 160, 45, MD_XGI300|MD_XGI315}, - {"1280x720x32", 0x78, 0x0000, 0x0000, 1280, 720, 32, 1, 160, 45, + {"1280x720x32", 0x78, 0x0000, 0x0000, 1280, 720, 32, 160, 45, MD_XGI300|MD_XGI315}, - {"1280x768x8", 0x23, 0x0000, 0x0000, 1280, 768, 8, 1, 160, 48, + {"1280x768x8", 0x23, 0x0000, 0x0000, 1280, 768, 8, 160, 48, MD_XGI315}, /* TW: 310/325 series only */ - {"1280x768x16", 0x24, 0x0000, 0x0000, 1280, 768, 16, 1, 160, 48, + {"1280x768x16", 0x24, 0x0000, 0x0000, 1280, 768, 16, 160, 48, MD_XGI315}, - {"1280x768x24", 0x25, 0x0000, 0x0000, 1280, 768, 32, 1, 160, 48, + {"1280x768x24", 0x25, 0x0000, 0x0000, 1280, 768, 32, 160, 48, MD_XGI315}, - {"1280x768x32", 0x25, 0x0000, 0x0000, 1280, 768, 32, 1, 160, 48, + {"1280x768x32", 0x25, 0x0000, 0x0000, 1280, 768, 32, 160, 48, MD_XGI315}, - {"1280x960x8", 0x7C, 0x0000, 0x0000, 1280, 960, 8, 1, 160, 60, + {"1280x960x8", 0x7C, 0x0000, 0x0000, 1280, 960, 8, 160, 60, MD_XGI300|MD_XGI315}, - {"1280x960x16", 0x7D, 0x0000, 0x0000, 1280, 960, 16, 1, 160, 60, + {"1280x960x16", 0x7D, 0x0000, 0x0000, 1280, 960, 16, 160, 60, MD_XGI300|MD_XGI315}, - {"1280x960x24", 0x7E, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, + {"1280x960x24", 0x7E, 0x0000, 0x0000, 1280, 960, 32, 160, 60, MD_XGI300|MD_XGI315}, - {"1280x960x32", 0x7E, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, + {"1280x960x32", 0x7E, 0x0000, 0x0000, 1280, 960, 32, 160, 60, MD_XGI300|MD_XGI315}, - {"1280x1024x8", 0x3A, 0x0107, 0x0107, 1280, 1024, 8, 1, 160, 64, + {"1280x1024x8", 0x3A, 0x0107, 0x0107, 1280, 1024, 8, 160, 64, MD_XGI300|MD_XGI315}, - {"1280x1024x16", 0x4D, 0x011a, 0x011a, 1280, 1024, 16, 1, 160, 64, + {"1280x1024x16", 0x4D, 0x011a, 0x011a, 1280, 1024, 16, 160, 64, MD_XGI300|MD_XGI315}, - {"1280x1024x24", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 1, 160, 64, + {"1280x1024x24", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 160, 64, MD_XGI300|MD_XGI315}, - {"1280x1024x32", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 1, 160, 64, + {"1280x1024x32", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 160, 64, MD_XGI300|MD_XGI315}, - {"1400x1050x8", 0x26, 0x0000, 0x0000, 1400, 1050, 8, 1, 175, 65, + {"1400x1050x8", 0x26, 0x0000, 0x0000, 1400, 1050, 8, 175, 65, MD_XGI315}, /* TW: 310/325 series only */ - {"1400x1050x16", 0x27, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65, + {"1400x1050x16", 0x27, 0x0000, 0x0000, 1400, 1050, 16, 175, 65, MD_XGI315}, - {"1400x1050x24", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, + {"1400x1050x24", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 175, 65, MD_XGI315}, - {"1400x1050x32", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, + {"1400x1050x32", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 175, 65, MD_XGI315}, - {"1600x1200x8", 0x3C, 0x0130, 0x011c, 1600, 1200, 8, 1, 200, 75, + {"1600x1200x8", 0x3C, 0x0130, 0x011c, 1600, 1200, 8, 200, 75, MD_XGI300|MD_XGI315}, - {"1600x1200x16", 0x3D, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, + {"1600x1200x16", 0x3D, 0x0131, 0x011e, 1600, 1200, 16, 200, 75, MD_XGI300|MD_XGI315}, - {"1600x1200x24", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, + {"1600x1200x24", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 200, 75, MD_XGI300|MD_XGI315}, - {"1600x1200x32", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, + {"1600x1200x32", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 200, 75, MD_XGI300|MD_XGI315}, - {"1920x1440x8", 0x68, 0x013f, 0x0000, 1920, 1440, 8, 1, 240, 75, + {"1920x1440x8", 0x68, 0x013f, 0x0000, 1920, 1440, 8, 240, 75, MD_XGI300|MD_XGI315}, - {"1920x1440x16", 0x69, 0x0140, 0x0000, 1920, 1440, 16, 1, 240, 75, + {"1920x1440x16", 0x69, 0x0140, 0x0000, 1920, 1440, 16, 240, 75, MD_XGI300|MD_XGI315}, - {"1920x1440x24", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, + {"1920x1440x24", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 240, 75, MD_XGI300|MD_XGI315}, - {"1920x1440x32", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, + {"1920x1440x32", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 240, 75, MD_XGI300|MD_XGI315}, - {"2048x1536x8", 0x6c, 0x0000, 0x0000, 2048, 1536, 8, 1, 256, 96, + {"2048x1536x8", 0x6c, 0x0000, 0x0000, 2048, 1536, 8, 256, 96, MD_XGI315}, /* TW: 310/325 series only */ - {"2048x1536x16", 0x6d, 0x0000, 0x0000, 2048, 1536, 16, 1, 256, 96, + {"2048x1536x16", 0x6d, 0x0000, 0x0000, 2048, 1536, 16, 256, 96, MD_XGI315}, - {"2048x1536x24", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96, + {"2048x1536x24", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 256, 96, MD_XGI315}, - {"2048x1536x32", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96, + {"2048x1536x32", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 256, 96, MD_XGI315}, - {"\0", 0x00, 0, 0, 0, 0, 0, 0, 0} + {"\0", 0x00, 0, 0, 0, 0, 0, 0} }; static const unsigned short XGI310paneltype[] = { diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 3eeb58a..5982c0d 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1138,8 +1138,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, if (XGIfb_search_refresh_rate(xgifb_info, xgifb_info->refresh_rate) == 0) { - xgifb_info->rate_idx = - XGIbios_mode[xgifb_info->mode_idx].rate_idx; + xgifb_info->rate_idx = 1; xgifb_info->refresh_rate = 60; } @@ -2134,8 +2133,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, xgifb_info->refresh_rate = 60; if (XGIfb_search_refresh_rate(xgifb_info, xgifb_info->refresh_rate) == 0) { - xgifb_info->rate_idx = - XGIbios_mode[xgifb_info->mode_idx].rate_idx; + xgifb_info->rate_idx = 1; xgifb_info->refresh_rate = 60; } -- cgit v0.10.2 From f9e5de0f175d114a850630f4e86a2eed4f7a7a75 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:13:55 +0300 Subject: staging: xgifb: eliminate string comparison from mode search Eliminate string comparison from the video mode search. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 5982c0d..85dbf32 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -390,19 +390,26 @@ static int XGIfb_GetXG21DefaultLVDSModeIdx(struct xgifb_video_info *xgifb_info) static void XGIfb_search_mode(struct xgifb_video_info *xgifb_info, const char *name) { - int i = 0, j = 0, l; + unsigned int xres; + unsigned int yres; + unsigned int bpp; + int i; - while (XGIbios_mode[i].mode_no != 0) { - l = min(strlen(name), strlen(XGIbios_mode[i].name)); - if (!strncmp(name, XGIbios_mode[i].name, l)) { + if (sscanf(name, "%ux%ux%u", &xres, &yres, &bpp) != 3) + goto invalid_mode; + + if (bpp == 24) + bpp = 32; /* That's for people who mix up color and fb depth. */ + + for (i = 0; XGIbios_mode[i].mode_no != 0; i++) + if (XGIbios_mode[i].xres == xres && + XGIbios_mode[i].yres == yres && + XGIbios_mode[i].bpp == bpp) { xgifb_info->mode_idx = i; - j = 1; - break; + return; } - i++; - } - if (!j) - pr_info("Invalid mode '%s'\n", name); +invalid_mode: + pr_info("Invalid mode '%s'\n", name); } static void XGIfb_search_vesamode(struct xgifb_video_info *xgifb_info, -- cgit v0.10.2 From ba6288f6ace83faeb5f6fd15bbaf7281bd1e945f Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:13:56 +0300 Subject: staging: xgifb: drop redudant mode table entries Since the mode search is not string-based anymore, we can drop XxYx24 entries which were just duplicated XxYx32 entries. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index ae778a1..fef9adf 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -105,17 +105,12 @@ static const struct _XGIbios_mode { MD_XGI300|MD_XGI315}, {"640x480x16", 0x44, 0x0111, 0x0111, 640, 480, 16, 80, 30, MD_XGI300|MD_XGI315}, - {"640x480x24", 0x62, 0x013a, 0x0112, 640, 480, 32, 80, 30, - MD_XGI300|MD_XGI315}, /* TW: That's for people who mix up color- - and fb depth */ {"640x480x32", 0x62, 0x013a, 0x0112, 640, 480, 32, 80, 30, MD_XGI300|MD_XGI315}, {"720x480x8", 0x31, 0x0000, 0x0000, 720, 480, 8, 90, 30, MD_XGI300|MD_XGI315}, {"720x480x16", 0x33, 0x0000, 0x0000, 720, 480, 16, 90, 30, MD_XGI300|MD_XGI315}, - {"720x480x24", 0x35, 0x0000, 0x0000, 720, 480, 32, 90, 30, - MD_XGI300|MD_XGI315}, {"720x480x32", 0x35, 0x0000, 0x0000, 720, 480, 32, 90, 30, MD_XGI300|MD_XGI315}, {"720x576x8", 0x32, 0x0000, 0x0000, 720, 576, 8, 90, 36, @@ -130,17 +125,13 @@ static const struct _XGIbios_mode { MD_XGI300|MD_XGI315}, {"800x480x16", 0x7a, 0x0000, 0x0000, 800, 480, 16, 100, 30, MD_XGI300|MD_XGI315}, - {"800x480x24", 0x76, 0x0000, 0x0000, 800, 480, 32, 100, 30, - MD_XGI300|MD_XGI315}, {"800x480x32", 0x76, 0x0000, 0x0000, 800, 480, 32, 100, 30, MD_XGI300|MD_XGI315}, {"800x600x8", 0x30, 0x0103, 0x0103, 800, 600, 8, 100, 37, MD_XGI300|MD_XGI315}, -#define DEFAULT_MODE 20 /* index for 800x600x16 */ +#define DEFAULT_MODE 17 /* index for 800x600x16 */ {"800x600x16", 0x47, 0x0114, 0x0114, 800, 600, 16, 100, 37, MD_XGI300|MD_XGI315}, - {"800x600x24", 0x63, 0x013b, 0x0115, 800, 600, 32, 100, 37, - MD_XGI300|MD_XGI315}, {"800x600x32", 0x63, 0x013b, 0x0115, 800, 600, 32, 100, 37, MD_XGI300|MD_XGI315}, {"1024x576x8", 0x71, 0x0000, 0x0000, 1024, 576, 8, 128, 36, @@ -155,8 +146,6 @@ static const struct _XGIbios_mode { MD_XGI300 }, /* TW: 300 series only */ {"1024x600x16", 0x21, 0x0000, 0x0000, 1024, 600, 16, 128, 37, MD_XGI300 }, - {"1024x600x24", 0x22, 0x0000, 0x0000, 1024, 600, 32, 128, 37, - MD_XGI300 }, {"1024x600x32", 0x22, 0x0000, 0x0000, 1024, 600, 32, 128, 37, MD_XGI300 }, {"1024x768x8", 0x38, 0x0105, 0x0105, 1024, 768, 8, 128, 48, @@ -171,72 +160,54 @@ static const struct _XGIbios_mode { MD_XGI300 }, /* TW: 300 series only */ {"1152x768x16", 0x24, 0x0000, 0x0000, 1152, 768, 16, 144, 48, MD_XGI300 }, - {"1152x768x24", 0x25, 0x0000, 0x0000, 1152, 768, 32, 144, 48, - MD_XGI300 }, {"1152x768x32", 0x25, 0x0000, 0x0000, 1152, 768, 32, 144, 48, MD_XGI300 }, {"1280x720x8", 0x79, 0x0000, 0x0000, 1280, 720, 8, 160, 45, MD_XGI300|MD_XGI315}, {"1280x720x16", 0x75, 0x0000, 0x0000, 1280, 720, 16, 160, 45, MD_XGI300|MD_XGI315}, - {"1280x720x24", 0x78, 0x0000, 0x0000, 1280, 720, 32, 160, 45, - MD_XGI300|MD_XGI315}, {"1280x720x32", 0x78, 0x0000, 0x0000, 1280, 720, 32, 160, 45, MD_XGI300|MD_XGI315}, {"1280x768x8", 0x23, 0x0000, 0x0000, 1280, 768, 8, 160, 48, MD_XGI315}, /* TW: 310/325 series only */ {"1280x768x16", 0x24, 0x0000, 0x0000, 1280, 768, 16, 160, 48, MD_XGI315}, - {"1280x768x24", 0x25, 0x0000, 0x0000, 1280, 768, 32, 160, 48, - MD_XGI315}, {"1280x768x32", 0x25, 0x0000, 0x0000, 1280, 768, 32, 160, 48, MD_XGI315}, {"1280x960x8", 0x7C, 0x0000, 0x0000, 1280, 960, 8, 160, 60, MD_XGI300|MD_XGI315}, {"1280x960x16", 0x7D, 0x0000, 0x0000, 1280, 960, 16, 160, 60, MD_XGI300|MD_XGI315}, - {"1280x960x24", 0x7E, 0x0000, 0x0000, 1280, 960, 32, 160, 60, - MD_XGI300|MD_XGI315}, {"1280x960x32", 0x7E, 0x0000, 0x0000, 1280, 960, 32, 160, 60, MD_XGI300|MD_XGI315}, {"1280x1024x8", 0x3A, 0x0107, 0x0107, 1280, 1024, 8, 160, 64, MD_XGI300|MD_XGI315}, {"1280x1024x16", 0x4D, 0x011a, 0x011a, 1280, 1024, 16, 160, 64, MD_XGI300|MD_XGI315}, - {"1280x1024x24", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 160, 64, - MD_XGI300|MD_XGI315}, {"1280x1024x32", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 160, 64, MD_XGI300|MD_XGI315}, {"1400x1050x8", 0x26, 0x0000, 0x0000, 1400, 1050, 8, 175, 65, MD_XGI315}, /* TW: 310/325 series only */ {"1400x1050x16", 0x27, 0x0000, 0x0000, 1400, 1050, 16, 175, 65, MD_XGI315}, - {"1400x1050x24", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 175, 65, - MD_XGI315}, {"1400x1050x32", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 175, 65, MD_XGI315}, {"1600x1200x8", 0x3C, 0x0130, 0x011c, 1600, 1200, 8, 200, 75, MD_XGI300|MD_XGI315}, {"1600x1200x16", 0x3D, 0x0131, 0x011e, 1600, 1200, 16, 200, 75, MD_XGI300|MD_XGI315}, - {"1600x1200x24", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 200, 75, - MD_XGI300|MD_XGI315}, {"1600x1200x32", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 200, 75, MD_XGI300|MD_XGI315}, {"1920x1440x8", 0x68, 0x013f, 0x0000, 1920, 1440, 8, 240, 75, MD_XGI300|MD_XGI315}, {"1920x1440x16", 0x69, 0x0140, 0x0000, 1920, 1440, 16, 240, 75, MD_XGI300|MD_XGI315}, - {"1920x1440x24", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 240, 75, - MD_XGI300|MD_XGI315}, {"1920x1440x32", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 240, 75, MD_XGI300|MD_XGI315}, {"2048x1536x8", 0x6c, 0x0000, 0x0000, 2048, 1536, 8, 256, 96, MD_XGI315}, /* TW: 310/325 series only */ {"2048x1536x16", 0x6d, 0x0000, 0x0000, 2048, 1536, 16, 256, 96, MD_XGI315}, - {"2048x1536x24", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 256, 96, - MD_XGI315}, {"2048x1536x32", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 256, 96, MD_XGI315}, {"\0", 0x00, 0, 0, 0, 0, 0, 0} -- cgit v0.10.2 From 283b846940dabdb2d8dadc48f51087f15dc696ce Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:13:57 +0300 Subject: staging: xgifb: delete mode names from the mode table Delete mode names from the table. They are just redundant data. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index fef9adf..b8f9337 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -84,7 +84,6 @@ static int XGIfb_tvplug = -1; /* mode table */ static const struct _XGIbios_mode { - char name[15]; u8 mode_no; u16 vesa_mode_no_1; /* "XGI defined" VESA mode number */ u16 vesa_mode_no_2; /* Real VESA mode numbers */ @@ -95,122 +94,122 @@ static const struct _XGIbios_mode { u16 rows; u8 chipset; } XGIbios_mode[] = { - {"320x240x16", 0x56, 0x0000, 0x0000, 320, 240, 16, 40, 15, + { 0x56, 0x0000, 0x0000, 320, 240, 16, 40, 15, MD_XGI315}, - {"320x480x8", 0x5A, 0x0000, 0x0000, 320, 480, 8, 40, 30, + { 0x5A, 0x0000, 0x0000, 320, 480, 8, 40, 30, MD_XGI315}, /* TW: FSTN */ - {"320x480x16", 0x5B, 0x0000, 0x0000, 320, 480, 16, 40, 30, + { 0x5B, 0x0000, 0x0000, 320, 480, 16, 40, 30, MD_XGI315}, /* TW: FSTN */ - {"640x480x8", 0x2E, 0x0101, 0x0101, 640, 480, 8, 80, 30, + { 0x2E, 0x0101, 0x0101, 640, 480, 8, 80, 30, MD_XGI300|MD_XGI315}, - {"640x480x16", 0x44, 0x0111, 0x0111, 640, 480, 16, 80, 30, + { 0x44, 0x0111, 0x0111, 640, 480, 16, 80, 30, MD_XGI300|MD_XGI315}, - {"640x480x32", 0x62, 0x013a, 0x0112, 640, 480, 32, 80, 30, + { 0x62, 0x013a, 0x0112, 640, 480, 32, 80, 30, MD_XGI300|MD_XGI315}, - {"720x480x8", 0x31, 0x0000, 0x0000, 720, 480, 8, 90, 30, + { 0x31, 0x0000, 0x0000, 720, 480, 8, 90, 30, MD_XGI300|MD_XGI315}, - {"720x480x16", 0x33, 0x0000, 0x0000, 720, 480, 16, 90, 30, + { 0x33, 0x0000, 0x0000, 720, 480, 16, 90, 30, MD_XGI300|MD_XGI315}, - {"720x480x32", 0x35, 0x0000, 0x0000, 720, 480, 32, 90, 30, + { 0x35, 0x0000, 0x0000, 720, 480, 32, 90, 30, MD_XGI300|MD_XGI315}, - {"720x576x8", 0x32, 0x0000, 0x0000, 720, 576, 8, 90, 36, + { 0x32, 0x0000, 0x0000, 720, 576, 8, 90, 36, MD_XGI300|MD_XGI315}, - {"720x576x16", 0x34, 0x0000, 0x0000, 720, 576, 16, 90, 36, + { 0x34, 0x0000, 0x0000, 720, 576, 16, 90, 36, MD_XGI300|MD_XGI315}, - {"720x576x24", 0x36, 0x0000, 0x0000, 720, 576, 32, 90, 36, + { 0x36, 0x0000, 0x0000, 720, 576, 32, 90, 36, MD_XGI300|MD_XGI315}, - {"720x576x32", 0x36, 0x0000, 0x0000, 720, 576, 32, 90, 36, + { 0x36, 0x0000, 0x0000, 720, 576, 32, 90, 36, MD_XGI300|MD_XGI315}, - {"800x480x8", 0x70, 0x0000, 0x0000, 800, 480, 8, 100, 30, + { 0x70, 0x0000, 0x0000, 800, 480, 8, 100, 30, MD_XGI300|MD_XGI315}, - {"800x480x16", 0x7a, 0x0000, 0x0000, 800, 480, 16, 100, 30, + { 0x7a, 0x0000, 0x0000, 800, 480, 16, 100, 30, MD_XGI300|MD_XGI315}, - {"800x480x32", 0x76, 0x0000, 0x0000, 800, 480, 32, 100, 30, + { 0x76, 0x0000, 0x0000, 800, 480, 32, 100, 30, MD_XGI300|MD_XGI315}, - {"800x600x8", 0x30, 0x0103, 0x0103, 800, 600, 8, 100, 37, + { 0x30, 0x0103, 0x0103, 800, 600, 8, 100, 37, MD_XGI300|MD_XGI315}, #define DEFAULT_MODE 17 /* index for 800x600x16 */ - {"800x600x16", 0x47, 0x0114, 0x0114, 800, 600, 16, 100, 37, + { 0x47, 0x0114, 0x0114, 800, 600, 16, 100, 37, MD_XGI300|MD_XGI315}, - {"800x600x32", 0x63, 0x013b, 0x0115, 800, 600, 32, 100, 37, + { 0x63, 0x013b, 0x0115, 800, 600, 32, 100, 37, MD_XGI300|MD_XGI315}, - {"1024x576x8", 0x71, 0x0000, 0x0000, 1024, 576, 8, 128, 36, + { 0x71, 0x0000, 0x0000, 1024, 576, 8, 128, 36, MD_XGI300|MD_XGI315}, - {"1024x576x16", 0x74, 0x0000, 0x0000, 1024, 576, 16, 128, 36, + { 0x74, 0x0000, 0x0000, 1024, 576, 16, 128, 36, MD_XGI300|MD_XGI315}, - {"1024x576x24", 0x77, 0x0000, 0x0000, 1024, 576, 32, 128, 36, + { 0x77, 0x0000, 0x0000, 1024, 576, 32, 128, 36, MD_XGI300|MD_XGI315}, - {"1024x576x32", 0x77, 0x0000, 0x0000, 1024, 576, 32, 128, 36, + { 0x77, 0x0000, 0x0000, 1024, 576, 32, 128, 36, MD_XGI300|MD_XGI315}, - {"1024x600x8", 0x20, 0x0000, 0x0000, 1024, 600, 8, 128, 37, + { 0x20, 0x0000, 0x0000, 1024, 600, 8, 128, 37, MD_XGI300 }, /* TW: 300 series only */ - {"1024x600x16", 0x21, 0x0000, 0x0000, 1024, 600, 16, 128, 37, + { 0x21, 0x0000, 0x0000, 1024, 600, 16, 128, 37, MD_XGI300 }, - {"1024x600x32", 0x22, 0x0000, 0x0000, 1024, 600, 32, 128, 37, + { 0x22, 0x0000, 0x0000, 1024, 600, 32, 128, 37, MD_XGI300 }, - {"1024x768x8", 0x38, 0x0105, 0x0105, 1024, 768, 8, 128, 48, + { 0x38, 0x0105, 0x0105, 1024, 768, 8, 128, 48, MD_XGI300|MD_XGI315}, - {"1024x768x16", 0x4A, 0x0117, 0x0117, 1024, 768, 16, 128, 48, + { 0x4A, 0x0117, 0x0117, 1024, 768, 16, 128, 48, MD_XGI300|MD_XGI315}, - {"1024x768x24", 0x64, 0x013c, 0x0118, 1024, 768, 32, 128, 48, + { 0x64, 0x013c, 0x0118, 1024, 768, 32, 128, 48, MD_XGI300|MD_XGI315}, - {"1024x768x32", 0x64, 0x013c, 0x0118, 1024, 768, 32, 128, 48, + { 0x64, 0x013c, 0x0118, 1024, 768, 32, 128, 48, MD_XGI300|MD_XGI315}, - {"1152x768x8", 0x23, 0x0000, 0x0000, 1152, 768, 8, 144, 48, + { 0x23, 0x0000, 0x0000, 1152, 768, 8, 144, 48, MD_XGI300 }, /* TW: 300 series only */ - {"1152x768x16", 0x24, 0x0000, 0x0000, 1152, 768, 16, 144, 48, + { 0x24, 0x0000, 0x0000, 1152, 768, 16, 144, 48, MD_XGI300 }, - {"1152x768x32", 0x25, 0x0000, 0x0000, 1152, 768, 32, 144, 48, + { 0x25, 0x0000, 0x0000, 1152, 768, 32, 144, 48, MD_XGI300 }, - {"1280x720x8", 0x79, 0x0000, 0x0000, 1280, 720, 8, 160, 45, + { 0x79, 0x0000, 0x0000, 1280, 720, 8, 160, 45, MD_XGI300|MD_XGI315}, - {"1280x720x16", 0x75, 0x0000, 0x0000, 1280, 720, 16, 160, 45, + { 0x75, 0x0000, 0x0000, 1280, 720, 16, 160, 45, MD_XGI300|MD_XGI315}, - {"1280x720x32", 0x78, 0x0000, 0x0000, 1280, 720, 32, 160, 45, + { 0x78, 0x0000, 0x0000, 1280, 720, 32, 160, 45, MD_XGI300|MD_XGI315}, - {"1280x768x8", 0x23, 0x0000, 0x0000, 1280, 768, 8, 160, 48, + { 0x23, 0x0000, 0x0000, 1280, 768, 8, 160, 48, MD_XGI315}, /* TW: 310/325 series only */ - {"1280x768x16", 0x24, 0x0000, 0x0000, 1280, 768, 16, 160, 48, + { 0x24, 0x0000, 0x0000, 1280, 768, 16, 160, 48, MD_XGI315}, - {"1280x768x32", 0x25, 0x0000, 0x0000, 1280, 768, 32, 160, 48, + { 0x25, 0x0000, 0x0000, 1280, 768, 32, 160, 48, MD_XGI315}, - {"1280x960x8", 0x7C, 0x0000, 0x0000, 1280, 960, 8, 160, 60, + { 0x7C, 0x0000, 0x0000, 1280, 960, 8, 160, 60, MD_XGI300|MD_XGI315}, - {"1280x960x16", 0x7D, 0x0000, 0x0000, 1280, 960, 16, 160, 60, + { 0x7D, 0x0000, 0x0000, 1280, 960, 16, 160, 60, MD_XGI300|MD_XGI315}, - {"1280x960x32", 0x7E, 0x0000, 0x0000, 1280, 960, 32, 160, 60, + { 0x7E, 0x0000, 0x0000, 1280, 960, 32, 160, 60, MD_XGI300|MD_XGI315}, - {"1280x1024x8", 0x3A, 0x0107, 0x0107, 1280, 1024, 8, 160, 64, + { 0x3A, 0x0107, 0x0107, 1280, 1024, 8, 160, 64, MD_XGI300|MD_XGI315}, - {"1280x1024x16", 0x4D, 0x011a, 0x011a, 1280, 1024, 16, 160, 64, + { 0x4D, 0x011a, 0x011a, 1280, 1024, 16, 160, 64, MD_XGI300|MD_XGI315}, - {"1280x1024x32", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 160, 64, + { 0x65, 0x013d, 0x011b, 1280, 1024, 32, 160, 64, MD_XGI300|MD_XGI315}, - {"1400x1050x8", 0x26, 0x0000, 0x0000, 1400, 1050, 8, 175, 65, + { 0x26, 0x0000, 0x0000, 1400, 1050, 8, 175, 65, MD_XGI315}, /* TW: 310/325 series only */ - {"1400x1050x16", 0x27, 0x0000, 0x0000, 1400, 1050, 16, 175, 65, + { 0x27, 0x0000, 0x0000, 1400, 1050, 16, 175, 65, MD_XGI315}, - {"1400x1050x32", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 175, 65, + { 0x28, 0x0000, 0x0000, 1400, 1050, 32, 175, 65, MD_XGI315}, - {"1600x1200x8", 0x3C, 0x0130, 0x011c, 1600, 1200, 8, 200, 75, + { 0x3C, 0x0130, 0x011c, 1600, 1200, 8, 200, 75, MD_XGI300|MD_XGI315}, - {"1600x1200x16", 0x3D, 0x0131, 0x011e, 1600, 1200, 16, 200, 75, + { 0x3D, 0x0131, 0x011e, 1600, 1200, 16, 200, 75, MD_XGI300|MD_XGI315}, - {"1600x1200x32", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 200, 75, + { 0x66, 0x013e, 0x011f, 1600, 1200, 32, 200, 75, MD_XGI300|MD_XGI315}, - {"1920x1440x8", 0x68, 0x013f, 0x0000, 1920, 1440, 8, 240, 75, + { 0x68, 0x013f, 0x0000, 1920, 1440, 8, 240, 75, MD_XGI300|MD_XGI315}, - {"1920x1440x16", 0x69, 0x0140, 0x0000, 1920, 1440, 16, 240, 75, + { 0x69, 0x0140, 0x0000, 1920, 1440, 16, 240, 75, MD_XGI300|MD_XGI315}, - {"1920x1440x32", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 240, 75, + { 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 240, 75, MD_XGI300|MD_XGI315}, - {"2048x1536x8", 0x6c, 0x0000, 0x0000, 2048, 1536, 8, 256, 96, + { 0x6c, 0x0000, 0x0000, 2048, 1536, 8, 256, 96, MD_XGI315}, /* TW: 310/325 series only */ - {"2048x1536x16", 0x6d, 0x0000, 0x0000, 2048, 1536, 16, 256, 96, + { 0x6d, 0x0000, 0x0000, 2048, 1536, 16, 256, 96, MD_XGI315}, - {"2048x1536x32", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 256, 96, + { 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 256, 96, MD_XGI315}, - {"\0", 0x00, 0, 0, 0, 0, 0, 0} + { 0 }, }; static const unsigned short XGI310paneltype[] = { -- cgit v0.10.2 From c6d5841b5f693cd47a17b452735d20a1674b41b5 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:13:58 +0300 Subject: staging: xgifb: delete mode rows and columns Delete redudant rows and columns data. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index b8f9337..0e2a625 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -90,124 +90,122 @@ static const struct _XGIbios_mode { u16 xres; u16 yres; u16 bpp; - u16 cols; - u16 rows; u8 chipset; } XGIbios_mode[] = { - { 0x56, 0x0000, 0x0000, 320, 240, 16, 40, 15, + { 0x56, 0x0000, 0x0000, 320, 240, 16, MD_XGI315}, - { 0x5A, 0x0000, 0x0000, 320, 480, 8, 40, 30, + { 0x5A, 0x0000, 0x0000, 320, 480, 8, MD_XGI315}, /* TW: FSTN */ - { 0x5B, 0x0000, 0x0000, 320, 480, 16, 40, 30, + { 0x5B, 0x0000, 0x0000, 320, 480, 16, MD_XGI315}, /* TW: FSTN */ - { 0x2E, 0x0101, 0x0101, 640, 480, 8, 80, 30, + { 0x2E, 0x0101, 0x0101, 640, 480, 8, MD_XGI300|MD_XGI315}, - { 0x44, 0x0111, 0x0111, 640, 480, 16, 80, 30, + { 0x44, 0x0111, 0x0111, 640, 480, 16, MD_XGI300|MD_XGI315}, - { 0x62, 0x013a, 0x0112, 640, 480, 32, 80, 30, + { 0x62, 0x013a, 0x0112, 640, 480, 32, MD_XGI300|MD_XGI315}, - { 0x31, 0x0000, 0x0000, 720, 480, 8, 90, 30, + { 0x31, 0x0000, 0x0000, 720, 480, 8, MD_XGI300|MD_XGI315}, - { 0x33, 0x0000, 0x0000, 720, 480, 16, 90, 30, + { 0x33, 0x0000, 0x0000, 720, 480, 16, MD_XGI300|MD_XGI315}, - { 0x35, 0x0000, 0x0000, 720, 480, 32, 90, 30, + { 0x35, 0x0000, 0x0000, 720, 480, 32, MD_XGI300|MD_XGI315}, - { 0x32, 0x0000, 0x0000, 720, 576, 8, 90, 36, + { 0x32, 0x0000, 0x0000, 720, 576, 8, MD_XGI300|MD_XGI315}, - { 0x34, 0x0000, 0x0000, 720, 576, 16, 90, 36, + { 0x34, 0x0000, 0x0000, 720, 576, 16, MD_XGI300|MD_XGI315}, - { 0x36, 0x0000, 0x0000, 720, 576, 32, 90, 36, + { 0x36, 0x0000, 0x0000, 720, 576, 32, MD_XGI300|MD_XGI315}, - { 0x36, 0x0000, 0x0000, 720, 576, 32, 90, 36, + { 0x36, 0x0000, 0x0000, 720, 576, 32, MD_XGI300|MD_XGI315}, - { 0x70, 0x0000, 0x0000, 800, 480, 8, 100, 30, + { 0x70, 0x0000, 0x0000, 800, 480, 8, MD_XGI300|MD_XGI315}, - { 0x7a, 0x0000, 0x0000, 800, 480, 16, 100, 30, + { 0x7a, 0x0000, 0x0000, 800, 480, 16, MD_XGI300|MD_XGI315}, - { 0x76, 0x0000, 0x0000, 800, 480, 32, 100, 30, + { 0x76, 0x0000, 0x0000, 800, 480, 32, MD_XGI300|MD_XGI315}, - { 0x30, 0x0103, 0x0103, 800, 600, 8, 100, 37, + { 0x30, 0x0103, 0x0103, 800, 600, 8, MD_XGI300|MD_XGI315}, #define DEFAULT_MODE 17 /* index for 800x600x16 */ - { 0x47, 0x0114, 0x0114, 800, 600, 16, 100, 37, + { 0x47, 0x0114, 0x0114, 800, 600, 16, MD_XGI300|MD_XGI315}, - { 0x63, 0x013b, 0x0115, 800, 600, 32, 100, 37, + { 0x63, 0x013b, 0x0115, 800, 600, 32, MD_XGI300|MD_XGI315}, - { 0x71, 0x0000, 0x0000, 1024, 576, 8, 128, 36, + { 0x71, 0x0000, 0x0000, 1024, 576, 8, MD_XGI300|MD_XGI315}, - { 0x74, 0x0000, 0x0000, 1024, 576, 16, 128, 36, + { 0x74, 0x0000, 0x0000, 1024, 576, 16, MD_XGI300|MD_XGI315}, - { 0x77, 0x0000, 0x0000, 1024, 576, 32, 128, 36, + { 0x77, 0x0000, 0x0000, 1024, 576, 32, MD_XGI300|MD_XGI315}, - { 0x77, 0x0000, 0x0000, 1024, 576, 32, 128, 36, + { 0x77, 0x0000, 0x0000, 1024, 576, 32, MD_XGI300|MD_XGI315}, - { 0x20, 0x0000, 0x0000, 1024, 600, 8, 128, 37, + { 0x20, 0x0000, 0x0000, 1024, 600, 8, MD_XGI300 }, /* TW: 300 series only */ - { 0x21, 0x0000, 0x0000, 1024, 600, 16, 128, 37, + { 0x21, 0x0000, 0x0000, 1024, 600, 16, MD_XGI300 }, - { 0x22, 0x0000, 0x0000, 1024, 600, 32, 128, 37, + { 0x22, 0x0000, 0x0000, 1024, 600, 32, MD_XGI300 }, - { 0x38, 0x0105, 0x0105, 1024, 768, 8, 128, 48, + { 0x38, 0x0105, 0x0105, 1024, 768, 8, MD_XGI300|MD_XGI315}, - { 0x4A, 0x0117, 0x0117, 1024, 768, 16, 128, 48, + { 0x4A, 0x0117, 0x0117, 1024, 768, 16, MD_XGI300|MD_XGI315}, - { 0x64, 0x013c, 0x0118, 1024, 768, 32, 128, 48, + { 0x64, 0x013c, 0x0118, 1024, 768, 32, MD_XGI300|MD_XGI315}, - { 0x64, 0x013c, 0x0118, 1024, 768, 32, 128, 48, + { 0x64, 0x013c, 0x0118, 1024, 768, 32, MD_XGI300|MD_XGI315}, - { 0x23, 0x0000, 0x0000, 1152, 768, 8, 144, 48, + { 0x23, 0x0000, 0x0000, 1152, 768, 8, MD_XGI300 }, /* TW: 300 series only */ - { 0x24, 0x0000, 0x0000, 1152, 768, 16, 144, 48, + { 0x24, 0x0000, 0x0000, 1152, 768, 16, MD_XGI300 }, - { 0x25, 0x0000, 0x0000, 1152, 768, 32, 144, 48, + { 0x25, 0x0000, 0x0000, 1152, 768, 32, MD_XGI300 }, - { 0x79, 0x0000, 0x0000, 1280, 720, 8, 160, 45, + { 0x79, 0x0000, 0x0000, 1280, 720, 8, MD_XGI300|MD_XGI315}, - { 0x75, 0x0000, 0x0000, 1280, 720, 16, 160, 45, + { 0x75, 0x0000, 0x0000, 1280, 720, 16, MD_XGI300|MD_XGI315}, - { 0x78, 0x0000, 0x0000, 1280, 720, 32, 160, 45, + { 0x78, 0x0000, 0x0000, 1280, 720, 32, MD_XGI300|MD_XGI315}, - { 0x23, 0x0000, 0x0000, 1280, 768, 8, 160, 48, + { 0x23, 0x0000, 0x0000, 1280, 768, 8, MD_XGI315}, /* TW: 310/325 series only */ - { 0x24, 0x0000, 0x0000, 1280, 768, 16, 160, 48, + { 0x24, 0x0000, 0x0000, 1280, 768, 16, MD_XGI315}, - { 0x25, 0x0000, 0x0000, 1280, 768, 32, 160, 48, + { 0x25, 0x0000, 0x0000, 1280, 768, 32, MD_XGI315}, - { 0x7C, 0x0000, 0x0000, 1280, 960, 8, 160, 60, + { 0x7C, 0x0000, 0x0000, 1280, 960, 8, MD_XGI300|MD_XGI315}, - { 0x7D, 0x0000, 0x0000, 1280, 960, 16, 160, 60, + { 0x7D, 0x0000, 0x0000, 1280, 960, 16, MD_XGI300|MD_XGI315}, - { 0x7E, 0x0000, 0x0000, 1280, 960, 32, 160, 60, + { 0x7E, 0x0000, 0x0000, 1280, 960, 32, MD_XGI300|MD_XGI315}, - { 0x3A, 0x0107, 0x0107, 1280, 1024, 8, 160, 64, + { 0x3A, 0x0107, 0x0107, 1280, 1024, 8, MD_XGI300|MD_XGI315}, - { 0x4D, 0x011a, 0x011a, 1280, 1024, 16, 160, 64, + { 0x4D, 0x011a, 0x011a, 1280, 1024, 16, MD_XGI300|MD_XGI315}, - { 0x65, 0x013d, 0x011b, 1280, 1024, 32, 160, 64, + { 0x65, 0x013d, 0x011b, 1280, 1024, 32, MD_XGI300|MD_XGI315}, - { 0x26, 0x0000, 0x0000, 1400, 1050, 8, 175, 65, + { 0x26, 0x0000, 0x0000, 1400, 1050, 8, MD_XGI315}, /* TW: 310/325 series only */ - { 0x27, 0x0000, 0x0000, 1400, 1050, 16, 175, 65, + { 0x27, 0x0000, 0x0000, 1400, 1050, 16, MD_XGI315}, - { 0x28, 0x0000, 0x0000, 1400, 1050, 32, 175, 65, + { 0x28, 0x0000, 0x0000, 1400, 1050, 32, MD_XGI315}, - { 0x3C, 0x0130, 0x011c, 1600, 1200, 8, 200, 75, + { 0x3C, 0x0130, 0x011c, 1600, 1200, 8, MD_XGI300|MD_XGI315}, - { 0x3D, 0x0131, 0x011e, 1600, 1200, 16, 200, 75, + { 0x3D, 0x0131, 0x011e, 1600, 1200, 16, MD_XGI300|MD_XGI315}, - { 0x66, 0x013e, 0x011f, 1600, 1200, 32, 200, 75, + { 0x66, 0x013e, 0x011f, 1600, 1200, 32, MD_XGI300|MD_XGI315}, - { 0x68, 0x013f, 0x0000, 1920, 1440, 8, 240, 75, + { 0x68, 0x013f, 0x0000, 1920, 1440, 8, MD_XGI300|MD_XGI315}, - { 0x69, 0x0140, 0x0000, 1920, 1440, 16, 240, 75, + { 0x69, 0x0140, 0x0000, 1920, 1440, 16, MD_XGI300|MD_XGI315}, - { 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 240, 75, + { 0x6B, 0x0141, 0x0000, 1920, 1440, 32, MD_XGI300|MD_XGI315}, - { 0x6c, 0x0000, 0x0000, 2048, 1536, 8, 256, 96, + { 0x6c, 0x0000, 0x0000, 2048, 1536, 8, MD_XGI315}, /* TW: 310/325 series only */ - { 0x6d, 0x0000, 0x0000, 2048, 1536, 16, 256, 96, + { 0x6d, 0x0000, 0x0000, 2048, 1536, 16, MD_XGI315}, - { 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 256, 96, + { 0x6e, 0x0000, 0x0000, 2048, 1536, 32, MD_XGI315}, { 0 }, }; -- cgit v0.10.2 From ac64fdf48810ec7f64da0902ff0872d5bce5eda0 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:13:59 +0300 Subject: staging: xgifb: delete MD_XGI300 Nobody cares about this bit. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index 0e2a625..ad83cd6 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -79,8 +79,7 @@ static int XGIfb_tvplug = -1; /* TW: For ioctl XGIFB_GET_INFO */ /* XGIfb_info XGIfbinfo; */ -#define MD_XGI300 1 -#define MD_XGI315 2 +#define MD_XGI315 1 /* mode table */ static const struct _XGIbios_mode { @@ -99,72 +98,72 @@ static const struct _XGIbios_mode { { 0x5B, 0x0000, 0x0000, 320, 480, 16, MD_XGI315}, /* TW: FSTN */ { 0x2E, 0x0101, 0x0101, 640, 480, 8, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x44, 0x0111, 0x0111, 640, 480, 16, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x62, 0x013a, 0x0112, 640, 480, 32, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x31, 0x0000, 0x0000, 720, 480, 8, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x33, 0x0000, 0x0000, 720, 480, 16, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x35, 0x0000, 0x0000, 720, 480, 32, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x32, 0x0000, 0x0000, 720, 576, 8, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x34, 0x0000, 0x0000, 720, 576, 16, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x36, 0x0000, 0x0000, 720, 576, 32, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x36, 0x0000, 0x0000, 720, 576, 32, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x70, 0x0000, 0x0000, 800, 480, 8, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x7a, 0x0000, 0x0000, 800, 480, 16, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x76, 0x0000, 0x0000, 800, 480, 32, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x30, 0x0103, 0x0103, 800, 600, 8, - MD_XGI300|MD_XGI315}, + MD_XGI315}, #define DEFAULT_MODE 17 /* index for 800x600x16 */ { 0x47, 0x0114, 0x0114, 800, 600, 16, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x63, 0x013b, 0x0115, 800, 600, 32, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x71, 0x0000, 0x0000, 1024, 576, 8, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x74, 0x0000, 0x0000, 1024, 576, 16, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x77, 0x0000, 0x0000, 1024, 576, 32, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x77, 0x0000, 0x0000, 1024, 576, 32, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x20, 0x0000, 0x0000, 1024, 600, 8, - MD_XGI300 }, /* TW: 300 series only */ + }, { 0x21, 0x0000, 0x0000, 1024, 600, 16, - MD_XGI300 }, + }, { 0x22, 0x0000, 0x0000, 1024, 600, 32, - MD_XGI300 }, + }, { 0x38, 0x0105, 0x0105, 1024, 768, 8, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x4A, 0x0117, 0x0117, 1024, 768, 16, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x64, 0x013c, 0x0118, 1024, 768, 32, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x64, 0x013c, 0x0118, 1024, 768, 32, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x23, 0x0000, 0x0000, 1152, 768, 8, - MD_XGI300 }, /* TW: 300 series only */ + }, { 0x24, 0x0000, 0x0000, 1152, 768, 16, - MD_XGI300 }, + }, { 0x25, 0x0000, 0x0000, 1152, 768, 32, - MD_XGI300 }, + }, { 0x79, 0x0000, 0x0000, 1280, 720, 8, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x75, 0x0000, 0x0000, 1280, 720, 16, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x78, 0x0000, 0x0000, 1280, 720, 32, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x23, 0x0000, 0x0000, 1280, 768, 8, MD_XGI315}, /* TW: 310/325 series only */ { 0x24, 0x0000, 0x0000, 1280, 768, 16, @@ -172,17 +171,17 @@ static const struct _XGIbios_mode { { 0x25, 0x0000, 0x0000, 1280, 768, 32, MD_XGI315}, { 0x7C, 0x0000, 0x0000, 1280, 960, 8, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x7D, 0x0000, 0x0000, 1280, 960, 16, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x7E, 0x0000, 0x0000, 1280, 960, 32, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x3A, 0x0107, 0x0107, 1280, 1024, 8, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x4D, 0x011a, 0x011a, 1280, 1024, 16, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x65, 0x013d, 0x011b, 1280, 1024, 32, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x26, 0x0000, 0x0000, 1400, 1050, 8, MD_XGI315}, /* TW: 310/325 series only */ { 0x27, 0x0000, 0x0000, 1400, 1050, 16, @@ -190,17 +189,17 @@ static const struct _XGIbios_mode { { 0x28, 0x0000, 0x0000, 1400, 1050, 32, MD_XGI315}, { 0x3C, 0x0130, 0x011c, 1600, 1200, 8, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x3D, 0x0131, 0x011e, 1600, 1200, 16, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x66, 0x013e, 0x011f, 1600, 1200, 32, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x68, 0x013f, 0x0000, 1920, 1440, 8, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x69, 0x0140, 0x0000, 1920, 1440, 16, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x6B, 0x0141, 0x0000, 1920, 1440, 32, - MD_XGI300|MD_XGI315}, + MD_XGI315}, { 0x6c, 0x0000, 0x0000, 2048, 1536, 8, MD_XGI315}, /* TW: 310/325 series only */ { 0x6d, 0x0000, 0x0000, 2048, 1536, 16, -- cgit v0.10.2 From 77f3e4b1593a9ec44b4d15a5edca8fede2f0c3ff Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:14:00 +0300 Subject: staging: xgifb: unwrap mode table lines Unwrap lines to improve readability. Comments were deleted as they were not really informative. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index ad83cd6..9c62aeb 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -91,121 +91,64 @@ static const struct _XGIbios_mode { u16 bpp; u8 chipset; } XGIbios_mode[] = { - { 0x56, 0x0000, 0x0000, 320, 240, 16, - MD_XGI315}, - { 0x5A, 0x0000, 0x0000, 320, 480, 8, - MD_XGI315}, /* TW: FSTN */ - { 0x5B, 0x0000, 0x0000, 320, 480, 16, - MD_XGI315}, /* TW: FSTN */ - { 0x2E, 0x0101, 0x0101, 640, 480, 8, - MD_XGI315}, - { 0x44, 0x0111, 0x0111, 640, 480, 16, - MD_XGI315}, - { 0x62, 0x013a, 0x0112, 640, 480, 32, - MD_XGI315}, - { 0x31, 0x0000, 0x0000, 720, 480, 8, - MD_XGI315}, - { 0x33, 0x0000, 0x0000, 720, 480, 16, - MD_XGI315}, - { 0x35, 0x0000, 0x0000, 720, 480, 32, - MD_XGI315}, - { 0x32, 0x0000, 0x0000, 720, 576, 8, - MD_XGI315}, - { 0x34, 0x0000, 0x0000, 720, 576, 16, - MD_XGI315}, - { 0x36, 0x0000, 0x0000, 720, 576, 32, - MD_XGI315}, - { 0x36, 0x0000, 0x0000, 720, 576, 32, - MD_XGI315}, - { 0x70, 0x0000, 0x0000, 800, 480, 8, - MD_XGI315}, - { 0x7a, 0x0000, 0x0000, 800, 480, 16, - MD_XGI315}, - { 0x76, 0x0000, 0x0000, 800, 480, 32, - MD_XGI315}, - { 0x30, 0x0103, 0x0103, 800, 600, 8, - MD_XGI315}, + { 0x56, 0x0000, 0x0000, 320, 240, 16, MD_XGI315 }, + { 0x5A, 0x0000, 0x0000, 320, 480, 8, MD_XGI315 }, + { 0x5B, 0x0000, 0x0000, 320, 480, 16, MD_XGI315 }, + { 0x2E, 0x0101, 0x0101, 640, 480, 8, MD_XGI315 }, + { 0x44, 0x0111, 0x0111, 640, 480, 16, MD_XGI315 }, + { 0x62, 0x013a, 0x0112, 640, 480, 32, MD_XGI315 }, + { 0x31, 0x0000, 0x0000, 720, 480, 8, MD_XGI315 }, + { 0x33, 0x0000, 0x0000, 720, 480, 16, MD_XGI315 }, + { 0x35, 0x0000, 0x0000, 720, 480, 32, MD_XGI315 }, + { 0x32, 0x0000, 0x0000, 720, 576, 8, MD_XGI315 }, + { 0x34, 0x0000, 0x0000, 720, 576, 16, MD_XGI315 }, + { 0x36, 0x0000, 0x0000, 720, 576, 32, MD_XGI315 }, + { 0x36, 0x0000, 0x0000, 720, 576, 32, MD_XGI315 }, + { 0x70, 0x0000, 0x0000, 800, 480, 8, MD_XGI315 }, + { 0x7a, 0x0000, 0x0000, 800, 480, 16, MD_XGI315 }, + { 0x76, 0x0000, 0x0000, 800, 480, 32, MD_XGI315 }, + { 0x30, 0x0103, 0x0103, 800, 600, 8, MD_XGI315 }, #define DEFAULT_MODE 17 /* index for 800x600x16 */ - { 0x47, 0x0114, 0x0114, 800, 600, 16, - MD_XGI315}, - { 0x63, 0x013b, 0x0115, 800, 600, 32, - MD_XGI315}, - { 0x71, 0x0000, 0x0000, 1024, 576, 8, - MD_XGI315}, - { 0x74, 0x0000, 0x0000, 1024, 576, 16, - MD_XGI315}, - { 0x77, 0x0000, 0x0000, 1024, 576, 32, - MD_XGI315}, - { 0x77, 0x0000, 0x0000, 1024, 576, 32, - MD_XGI315}, - { 0x20, 0x0000, 0x0000, 1024, 600, 8, - }, - { 0x21, 0x0000, 0x0000, 1024, 600, 16, - }, - { 0x22, 0x0000, 0x0000, 1024, 600, 32, - }, - { 0x38, 0x0105, 0x0105, 1024, 768, 8, - MD_XGI315}, - { 0x4A, 0x0117, 0x0117, 1024, 768, 16, - MD_XGI315}, - { 0x64, 0x013c, 0x0118, 1024, 768, 32, - MD_XGI315}, - { 0x64, 0x013c, 0x0118, 1024, 768, 32, - MD_XGI315}, - { 0x23, 0x0000, 0x0000, 1152, 768, 8, - }, - { 0x24, 0x0000, 0x0000, 1152, 768, 16, - }, - { 0x25, 0x0000, 0x0000, 1152, 768, 32, - }, - { 0x79, 0x0000, 0x0000, 1280, 720, 8, - MD_XGI315}, - { 0x75, 0x0000, 0x0000, 1280, 720, 16, - MD_XGI315}, - { 0x78, 0x0000, 0x0000, 1280, 720, 32, - MD_XGI315}, - { 0x23, 0x0000, 0x0000, 1280, 768, 8, - MD_XGI315}, /* TW: 310/325 series only */ - { 0x24, 0x0000, 0x0000, 1280, 768, 16, - MD_XGI315}, - { 0x25, 0x0000, 0x0000, 1280, 768, 32, - MD_XGI315}, - { 0x7C, 0x0000, 0x0000, 1280, 960, 8, - MD_XGI315}, - { 0x7D, 0x0000, 0x0000, 1280, 960, 16, - MD_XGI315}, - { 0x7E, 0x0000, 0x0000, 1280, 960, 32, - MD_XGI315}, - { 0x3A, 0x0107, 0x0107, 1280, 1024, 8, - MD_XGI315}, - { 0x4D, 0x011a, 0x011a, 1280, 1024, 16, - MD_XGI315}, - { 0x65, 0x013d, 0x011b, 1280, 1024, 32, - MD_XGI315}, - { 0x26, 0x0000, 0x0000, 1400, 1050, 8, - MD_XGI315}, /* TW: 310/325 series only */ - { 0x27, 0x0000, 0x0000, 1400, 1050, 16, - MD_XGI315}, - { 0x28, 0x0000, 0x0000, 1400, 1050, 32, - MD_XGI315}, - { 0x3C, 0x0130, 0x011c, 1600, 1200, 8, - MD_XGI315}, - { 0x3D, 0x0131, 0x011e, 1600, 1200, 16, - MD_XGI315}, - { 0x66, 0x013e, 0x011f, 1600, 1200, 32, - MD_XGI315}, - { 0x68, 0x013f, 0x0000, 1920, 1440, 8, - MD_XGI315}, - { 0x69, 0x0140, 0x0000, 1920, 1440, 16, - MD_XGI315}, - { 0x6B, 0x0141, 0x0000, 1920, 1440, 32, - MD_XGI315}, - { 0x6c, 0x0000, 0x0000, 2048, 1536, 8, - MD_XGI315}, /* TW: 310/325 series only */ - { 0x6d, 0x0000, 0x0000, 2048, 1536, 16, - MD_XGI315}, - { 0x6e, 0x0000, 0x0000, 2048, 1536, 32, - MD_XGI315}, + { 0x47, 0x0114, 0x0114, 800, 600, 16, MD_XGI315 }, + { 0x63, 0x013b, 0x0115, 800, 600, 32, MD_XGI315 }, + { 0x71, 0x0000, 0x0000, 1024, 576, 8, MD_XGI315 }, + { 0x74, 0x0000, 0x0000, 1024, 576, 16, MD_XGI315 }, + { 0x77, 0x0000, 0x0000, 1024, 576, 32, MD_XGI315 }, + { 0x77, 0x0000, 0x0000, 1024, 576, 32, MD_XGI315 }, + { 0x20, 0x0000, 0x0000, 1024, 600, 8, }, + { 0x21, 0x0000, 0x0000, 1024, 600, 16, }, + { 0x22, 0x0000, 0x0000, 1024, 600, 32, }, + { 0x38, 0x0105, 0x0105, 1024, 768, 8, MD_XGI315 }, + { 0x4A, 0x0117, 0x0117, 1024, 768, 16, MD_XGI315 }, + { 0x64, 0x013c, 0x0118, 1024, 768, 32, MD_XGI315 }, + { 0x64, 0x013c, 0x0118, 1024, 768, 32, MD_XGI315 }, + { 0x23, 0x0000, 0x0000, 1152, 768, 8, }, + { 0x24, 0x0000, 0x0000, 1152, 768, 16, }, + { 0x25, 0x0000, 0x0000, 1152, 768, 32, }, + { 0x79, 0x0000, 0x0000, 1280, 720, 8, MD_XGI315 }, + { 0x75, 0x0000, 0x0000, 1280, 720, 16, MD_XGI315 }, + { 0x78, 0x0000, 0x0000, 1280, 720, 32, MD_XGI315 }, + { 0x23, 0x0000, 0x0000, 1280, 768, 8, MD_XGI315 }, + { 0x24, 0x0000, 0x0000, 1280, 768, 16, MD_XGI315 }, + { 0x25, 0x0000, 0x0000, 1280, 768, 32, MD_XGI315 }, + { 0x7C, 0x0000, 0x0000, 1280, 960, 8, MD_XGI315 }, + { 0x7D, 0x0000, 0x0000, 1280, 960, 16, MD_XGI315 }, + { 0x7E, 0x0000, 0x0000, 1280, 960, 32, MD_XGI315 }, + { 0x3A, 0x0107, 0x0107, 1280, 1024, 8, MD_XGI315 }, + { 0x4D, 0x011a, 0x011a, 1280, 1024, 16, MD_XGI315 }, + { 0x65, 0x013d, 0x011b, 1280, 1024, 32, MD_XGI315 }, + { 0x26, 0x0000, 0x0000, 1400, 1050, 8, MD_XGI315 }, + { 0x27, 0x0000, 0x0000, 1400, 1050, 16, MD_XGI315 }, + { 0x28, 0x0000, 0x0000, 1400, 1050, 32, MD_XGI315 }, + { 0x3C, 0x0130, 0x011c, 1600, 1200, 8, MD_XGI315 }, + { 0x3D, 0x0131, 0x011e, 1600, 1200, 16, MD_XGI315 }, + { 0x66, 0x013e, 0x011f, 1600, 1200, 32, MD_XGI315 }, + { 0x68, 0x013f, 0x0000, 1920, 1440, 8, MD_XGI315 }, + { 0x69, 0x0140, 0x0000, 1920, 1440, 16, MD_XGI315 }, + { 0x6B, 0x0141, 0x0000, 1920, 1440, 32, MD_XGI315 }, + { 0x6c, 0x0000, 0x0000, 2048, 1536, 8, MD_XGI315 }, + { 0x6d, 0x0000, 0x0000, 2048, 1536, 16, MD_XGI315 }, + { 0x6e, 0x0000, 0x0000, 2048, 1536, 32, MD_XGI315 }, { 0 }, }; -- cgit v0.10.2 From 34c13ee2b690fb342b313ef7059baa561da172e9 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:14:01 +0300 Subject: staging: xgifb: drop code for legacy VGA modes Drop code for mode_no <= 14. These are not supported so this is all just dead code. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 5a00e94..2561e5a 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -181,14 +181,10 @@ static unsigned char XGI_GetModePtr(unsigned short ModeNo, { unsigned char index; - if (ModeNo <= 0x13) - index = pVBInfo->SModeIDTable[ModeIdIndex].St_StTableIndex; - else { - if (pVBInfo->ModeType <= 0x02) - index = 0x1B; /* 02 -> ModeEGA */ - else - index = 0x0F; - } + if (pVBInfo->ModeType <= 0x02) + index = 0x1B; /* 02 -> ModeEGA */ + else + index = 0x0F; return index; /* Get pVBInfo->StandTable index */ } @@ -200,10 +196,7 @@ static void XGI_SetSeqRegs(unsigned short ModeNo, unsigned char tempah, SRdata; unsigned short i, modeflag; - if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; xgifb_reg_set(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */ tempah = pVBInfo->StandTable[StandTableIndex].SR[0]; @@ -254,10 +247,7 @@ static void XGI_SetATTRegs(unsigned short ModeNo, unsigned char ARdata; unsigned short i, modeflag; - if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; for (i = 0; i <= 0x13; i++) { ARdata = pVBInfo->StandTable[StandTableIndex].ATTR[i]; @@ -337,12 +327,7 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, { unsigned short tempax, tempbx, resinfo, modeflag, infoflag; - if (ModeNo <= 0x13) - /* si+St_ModeFlag */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; tempbx = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID; tempax = 0; @@ -577,11 +562,7 @@ static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, data &= 0x80; data = data >> 2; - if (ModeNo <= 0x13) - i = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - i = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - + i = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; i &= DoubleScanMode; if (i) data |= 0x80; @@ -634,158 +615,97 @@ static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - unsigned char StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx; + unsigned char index, Tempax, Tempbx, Tempcx, Tempdx; unsigned short Temp1, Temp2, Temp3; - if (ModeNo <= 0x13) { - StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo); - /* CR04 HRS */ - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4]; - /* SR2E [7:0]->HRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); - /* Tempbx: CR05 HRE */ - Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5]; - Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */ - Tempcx = Tempax; - Tempcx &= 0xE0; /* Tempcx: HRS[7:5] */ - Tempdx = Tempcx | Tempbx; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */ - if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */ - Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */ - Tempdx <<= 2; /* Tempdx << 2 */ - /* SR2F [7:2]->HRE */ - xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempdx); - xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); - - /* Tempax: CR16 VRS */ - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; - Tempbx = Tempax; /* Tempbx=Tempax */ - Tempax &= 0x01; /* Tempax: VRS[0] */ - xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS */ - - /* Tempax: CR7 VRS */ - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7]; - Tempdx = Tempbx >> 1; /* Tempdx: VRS[7:1] */ - Tempcx = Tempax & 0x04; /* Tempcx: CR7[2] */ - Tempcx <<= 5; /* Tempcx[7]: VRS[8] */ - Tempdx |= Tempcx; /* Tempdx: VRS[8:1] */ - /* SR34[7:0]: VRS[8:1] */ - xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempdx); - - /* Temp1[8]: VRS[8] unsigned char -> unsigned short */ - Temp1 = Tempcx << 1; - Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */ - Tempax &= 0x80; /* Tempax[7]: CR7[7] */ - Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */ - Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */ - - /* CR16 VRE */ - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17]; - Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ - Temp2 = Temp1 & 0x3F0; /* Temp2[9:4]: VRS[9:4] */ - Temp2 |= Tempax; /* Temp2[9:0]: VRE[9:0] */ - Temp3 = Temp1 & 0x0F; /* Temp3[3:0]: VRS[3:0] */ - if (Tempax < Temp3) /* VRE[3:0]>= 9; /* [10:9]->[1:0] */ - Tempbx = (unsigned char) Temp1; /* Tempbx[1:0]: VRS[10:9] */ - Tempax |= Tempbx; /* VRE[5:0]VRS[10:9] */ - Tempax &= 0x7F; - /* SR3F D[7:2]->VRE D[1:0]->VRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax); - } else { - index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - /* Tempax: CR4 HRS */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; - Tempcx = Tempax; /* Tempcx: HRS */ - /* SR2E[7:0]->HRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); - - Tempdx = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SRB */ - Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */ - Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */ - Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */ - Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */ - - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */ - Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */ - - Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */ - Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */ - Tempbx <<= 3; /* Tempbx[5]: HRE[5] */ - Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */ - - Temp2 = Temp1 & 0x3C0; /* Temp2[9:6]: HRS[9:6] */ - Temp2 |= Tempax; /* Temp2[9:0]: HRE[9:0] */ - - Tempcx &= 0x3F; /* Tempcx[5:0]: HRS[5:0] */ - if (Tempax < Tempcx) /* HRE < HRS */ - Temp2 |= 0x40; /* Temp2 + 0x40 */ - - Temp2 &= 0xFF; - Tempax = (unsigned char) Temp2; /* Tempax: HRE[7:0] */ - Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */ - Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */ - Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */ - /* SR2F D[7:2]->HRE, D[1:0]->HRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax); - xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); - - /* CR10 VRS */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; - Tempbx = Tempax; /* Tempbx: VRS */ - Tempax &= 0x01; /* Tempax[0]: VRS[0] */ - xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */ - /* CR7[2][7] VRE */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; - Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */ - Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */ - Tempdx <<= 5; /* Tempdx[7]: VRS[8] */ - Tempcx |= Tempdx; /* Tempcx[7:0]: VRS[8:1] */ - xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */ - - Temp1 = Tempdx; /* Temp1[7]: Tempdx[7] */ - Temp1 <<= 1; /* Temp1[8]: VRS[8] */ - Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */ - Tempax &= 0x80; - Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */ - Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */ - /* Tempax: SRA */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; - Tempax &= 0x08; /* Tempax[3]: VRS[3] */ - Temp2 = Tempax; - Temp2 <<= 7; /* Temp2[10]: VRS[10] */ - Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */ - - /* Tempax: CR11 VRE */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; - Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ - /* Tempbx: SRA */ - Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; - Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */ - Tempbx >>= 1; /* Tempbx[4]: VRE[4] */ - Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */ - Temp2 = Temp1 & 0x7E0; /* Temp2[10:5]: VRS[10:5] */ - Temp2 |= Tempax; /* Temp2[10:5]: VRE[10:5] */ - - Temp3 = Temp1 & 0x1F; /* Temp3[4:0]: VRS[4:0] */ - if (Tempax < Temp3) /* VRE < VRS */ - Temp2 |= 0x20; /* VRE + 0x20 */ - - Temp2 &= 0xFF; - Tempax = (unsigned char) Temp2; /* Tempax: VRE[7:0] */ - Tempax <<= 2; /* Tempax[7:0]; VRE[5:0]00 */ - Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */ - Temp1 >>= 9; /* Temp1[1:0]: VRS[10:9] */ - Tempbx = (unsigned char) Temp1; - Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */ - Tempax &= 0x7F; - /* SR3F D[7:2]->VRE D[1:0]->VRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax); - } + index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + /* Tempax: CR4 HRS */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; + Tempcx = Tempax; /* Tempcx: HRS */ + /* SR2E[7:0]->HRS */ + xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); + + Tempdx = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SRB */ + Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */ + Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */ + Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */ + Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */ + + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */ + Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */ + + Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */ + Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */ + Tempbx <<= 3; /* Tempbx[5]: HRE[5] */ + Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */ + + Temp2 = Temp1 & 0x3C0; /* Temp2[9:6]: HRS[9:6] */ + Temp2 |= Tempax; /* Temp2[9:0]: HRE[9:0] */ + + Tempcx &= 0x3F; /* Tempcx[5:0]: HRS[5:0] */ + if (Tempax < Tempcx) /* HRE < HRS */ + Temp2 |= 0x40; /* Temp2 + 0x40 */ + + Temp2 &= 0xFF; + Tempax = (unsigned char) Temp2; /* Tempax: HRE[7:0] */ + Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */ + Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */ + Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */ + /* SR2F D[7:2]->HRE, D[1:0]->HRS */ + xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax); + xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); + + /* CR10 VRS */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; + Tempbx = Tempax; /* Tempbx: VRS */ + Tempax &= 0x01; /* Tempax[0]: VRS[0] */ + xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */ + /* CR7[2][7] VRE */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; + Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */ + Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */ + Tempdx <<= 5; /* Tempdx[7]: VRS[8] */ + Tempcx |= Tempdx; /* Tempcx[7:0]: VRS[8:1] */ + xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */ + + Temp1 = Tempdx; /* Temp1[7]: Tempdx[7] */ + Temp1 <<= 1; /* Temp1[8]: VRS[8] */ + Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */ + Tempax &= 0x80; + Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */ + Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */ + /* Tempax: SRA */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; + Tempax &= 0x08; /* Tempax[3]: VRS[3] */ + Temp2 = Tempax; + Temp2 <<= 7; /* Temp2[10]: VRS[10] */ + Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */ + + /* Tempax: CR11 VRE */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; + Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ + /* Tempbx: SRA */ + Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; + Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */ + Tempbx >>= 1; /* Tempbx[4]: VRE[4] */ + Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */ + Temp2 = Temp1 & 0x7E0; /* Temp2[10:5]: VRS[10:5] */ + Temp2 |= Tempax; /* Temp2[10:5]: VRE[10:5] */ + + Temp3 = Temp1 & 0x1F; /* Temp3[4:0]: VRS[4:0] */ + if (Tempax < Temp3) /* VRE < VRS */ + Temp2 |= 0x20; /* VRE + 0x20 */ + + Temp2 &= 0xFF; + Tempax = (unsigned char) Temp2; /* Tempax: VRE[7:0] */ + Tempax <<= 2; /* Tempax[7:0]; VRE[5:0]00 */ + Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */ + Temp1 >>= 9; /* Temp1[1:0]: VRS[10:9] */ + Tempbx = (unsigned char) Temp1; + Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */ + Tempax &= 0x7F; + /* SR3F D[7:2]->VRE D[1:0]->VRS */ + xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax); } static void XGI_SetXG27CRTC(unsigned short ModeNo, @@ -793,139 +713,88 @@ static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - unsigned short StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx; - - if (ModeNo <= 0x13) { - StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo); - /* CR04 HRS */ - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4]; - /* SR2E [7:0]->HRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); - /* Tempbx: CR05 HRE */ - Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5]; - Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */ - Tempcx = Tempax; - Tempcx &= 0xE0; /* Tempcx: HRS[7:5] */ - Tempdx = Tempcx | Tempbx; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */ - if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */ - Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */ - Tempdx <<= 2; /* Tempdx << 2 */ - /* SR2F [7:2]->HRE */ - xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempdx); - xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); - - /* Tempax: CR10 VRS */ - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; - xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS */ - Tempcx = Tempax; /* Tempcx=Tempax=VRS[7:0] */ - /* Tempax[7][2]: CR7[7][2] VRS[9][8] */ - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7]; - Tempbx = Tempax; /* Tempbx=CR07 */ - Tempax &= 0x04; /* Tempax[2]: CR07[2] VRS[8] */ - Tempax >>= 2; - /* SR35 D[0]->VRS D[8] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax); - Tempcx |= (Tempax << 8); /* Tempcx[8] |= VRS[8] */ - Tempcx |= (Tempbx & 0x80) << 2; /* Tempcx[9] |= VRS[9] */ - - /* CR11 VRE */ - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17]; - Tempax &= 0x0F; /* Tempax: VRE[3:0] */ - Tempbx = Tempcx; /* Tempbx=Tempcx=VRS[9:0] */ - Tempbx &= 0x3F0; /* Tempbx[9:4]: VRS[9:4] */ - Tempbx |= Tempax; /* Tempbx[9:0]: VRE[9:0] */ - if (Tempax <= (Tempcx & 0x0F)) /* VRE[3:0]<=VRS[3:0] */ - Tempbx |= 0x10; /* Tempbx: VRE + 0x10 */ - /* Tempax[7:0]: VRE[7:0] */ - Tempax = (unsigned char) Tempbx & 0xFF; - Tempax <<= 2; /* Tempax << 2: VRE[5:0] */ - Tempcx = (Tempcx & 0x600) >> 8; /* Tempcx VRS[10:9] */ - /* SR3F D[7:2]->VRE D[5:0] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); - /* SR35 D[2:1]->VRS[10:9] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x06, Tempcx); - } else { - index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - /* Tempax: CR4 HRS */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; - Tempbx = Tempax; /* Tempbx: HRS[7:0] */ - /* SR2E[7:0]->HRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); - - /* SR0B */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; - Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/ - Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */ - - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */ - Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */ - Tempcx = Tempax; /* Tempcx: HRE[4:0] */ - - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */ - Tempax &= 0x04; /* Tempax[2]: HRE[5] */ - Tempax <<= 3; /* Tempax[5]: HRE[5] */ - Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */ - - Tempbx = Tempbx & 0x3C0; /* Tempbx[9:6]: HRS[9:6] */ - Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */ - - /* Tempax: CR4 HRS */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; - Tempax &= 0x3F; /* Tempax: HRS[5:0] */ - if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */ - Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/ - - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */ - Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/ - Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/ - Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */ - /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */ - xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax); - xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); - - /* CR10 VRS */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; - /* SR34[7:0]->VRS[7:0] */ - xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax); - - Tempcx = Tempax; /* Tempcx <= VRS[7:0] */ - /* CR7[7][2] VRS[9][8] */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; - Tempbx = Tempax; /* Tempbx <= CR07[7:0] */ - Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */ - Tempax >>= 2; /* Tempax[0]: VRS[8] */ - /* SR35[0]: VRS[8] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax); - Tempcx |= (Tempax << 8); /* Tempcx <= VRS[8:0] */ - Tempcx |= ((Tempbx & 0x80) << 2); /* Tempcx <= VRS[9:0] */ - /* Tempax: SR0A */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; - Tempax &= 0x08; /* SR0A[3] VRS[10] */ - Tempcx |= (Tempax << 7); /* Tempcx <= VRS[10:0] */ - - /* Tempax: CR11 VRE */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; - Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ - /* Tempbx: SR0A */ - Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; - Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */ - Tempbx >>= 1; /* Tempbx[4]: VRE[4] */ - Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */ - Tempbx = Tempcx; /* Tempbx: VRS[10:0] */ - Tempbx &= 0x7E0; /* Tempbx[10:5]: VRS[10:5] */ - Tempbx |= Tempax; /* Tempbx: VRS[10:5]VRE[4:0] */ - - if (Tempbx <= Tempcx) /* VRE <= VRS */ - Tempbx |= 0x20; /* VRE + 0x20 */ - - /* Tempax: Tempax[7:0]; VRE[5:0]00 */ - Tempax = (Tempbx << 2) & 0xFF; - /* SR3F[7:2]:VRE[5:0] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); - Tempax = Tempcx >> 8; - /* SR35[2:0]:VRS[10:8] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07, Tempax); - } + unsigned short index, Tempax, Tempbx, Tempcx; + + index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + /* Tempax: CR4 HRS */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; + Tempbx = Tempax; /* Tempbx: HRS[7:0] */ + /* SR2E[7:0]->HRS */ + xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); + + /* SR0B */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; + Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/ + Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */ + + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */ + Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */ + Tempcx = Tempax; /* Tempcx: HRE[4:0] */ + + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */ + Tempax &= 0x04; /* Tempax[2]: HRE[5] */ + Tempax <<= 3; /* Tempax[5]: HRE[5] */ + Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */ + + Tempbx = Tempbx & 0x3C0; /* Tempbx[9:6]: HRS[9:6] */ + Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */ + + /* Tempax: CR4 HRS */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; + Tempax &= 0x3F; /* Tempax: HRS[5:0] */ + if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */ + Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/ + + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */ + Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/ + Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/ + Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */ + /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */ + xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax); + xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); + + /* CR10 VRS */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; + /* SR34[7:0]->VRS[7:0] */ + xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax); + + Tempcx = Tempax; /* Tempcx <= VRS[7:0] */ + /* CR7[7][2] VRS[9][8] */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; + Tempbx = Tempax; /* Tempbx <= CR07[7:0] */ + Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */ + Tempax >>= 2; /* Tempax[0]: VRS[8] */ + /* SR35[0]: VRS[8] */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax); + Tempcx |= (Tempax << 8); /* Tempcx <= VRS[8:0] */ + Tempcx |= ((Tempbx & 0x80) << 2); /* Tempcx <= VRS[9:0] */ + /* Tempax: SR0A */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; + Tempax &= 0x08; /* SR0A[3] VRS[10] */ + Tempcx |= (Tempax << 7); /* Tempcx <= VRS[10:0] */ + + /* Tempax: CR11 VRE */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; + Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ + /* Tempbx: SR0A */ + Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; + Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */ + Tempbx >>= 1; /* Tempbx[4]: VRE[4] */ + Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */ + Tempbx = Tempcx; /* Tempbx: VRS[10:0] */ + Tempbx &= 0x7E0; /* Tempbx[10:5]: VRS[10:5] */ + Tempbx |= Tempax; /* Tempbx: VRS[10:5]VRE[4:0] */ + + if (Tempbx <= Tempcx) /* VRE <= VRS */ + Tempbx |= 0x20; /* VRE + 0x20 */ + + /* Tempax: Tempax[7:0]; VRE[5:0]00 */ + Tempax = (Tempbx << 2) & 0xFF; + /* SR3F[7:2]:VRE[5:0] */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); + Tempax = Tempcx >> 8; + /* SR35[2:0]:VRS[10:8] */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07, Tempax); } static void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo) @@ -947,7 +816,7 @@ static void xgifb_set_lcd(int chip_id, unsigned short RefreshRateTableIndex, unsigned short ModeNo) { - unsigned short Data, Temp, b3CC; + unsigned short Data, Temp; unsigned short XGI_P3cc; XGI_P3cc = pVBInfo->P3cc; @@ -988,23 +857,13 @@ static void xgifb_set_lcd(int chip_id, xgifb_reg_and(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */ xgifb_reg_and(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */ - if (ModeNo <= 0x13) { - b3CC = (unsigned char) inb(XGI_P3cc); - if (b3CC & 0x40) - /* Hsync polarity */ - xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20); - if (b3CC & 0x80) - /* Vsync polarity */ - xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80); - } else { - Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - if (Data & 0x4000) - /* Hsync polarity */ - xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20); - if (Data & 0x8000) - /* Vsync polarity */ - xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80); - } + Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + if (Data & 0x4000) + /* Hsync polarity */ + xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20); + if (Data & 0x8000) + /* Vsync polarity */ + xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80); } /* --------------------------------------------------------------------- */ @@ -1017,30 +876,22 @@ static void XGI_UpdateXG21CRTC(unsigned short ModeNo, struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex) { - int i, index = -1; + int index = -1; xgifb_reg_and(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */ - if (ModeNo <= 0x13) { - for (i = 0; i < 12; i++) { - if (ModeNo == pVBInfo->UpdateCRT1[i].ModeID) - index = i; - } - } else { - if (ModeNo == 0x2E && - (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC == - RES640x480x60)) - index = 12; - else if (ModeNo == 0x2E && - (pVBInfo->RefIndex[RefreshRateTableIndex]. + if (ModeNo == 0x2E && + (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC == + RES640x480x60)) + index = 12; + else if (ModeNo == 0x2E && (pVBInfo->RefIndex[RefreshRateTableIndex]. Ext_CRT1CRTC == RES640x480x72)) - index = 13; - else if (ModeNo == 0x2F) - index = 14; - else if (ModeNo == 0x50) - index = 15; - else if (ModeNo == 0x59) - index = 16; - } + index = 13; + else if (ModeNo == 0x2F) + index = 14; + else if (ModeNo == 0x50) + index = 15; + else if (ModeNo == 0x59) + index = 16; if (index != -1) { xgifb_reg_set(pVBInfo->P3d4, 0x02, @@ -1057,15 +908,8 @@ static void XGI_UpdateXG21CRTC(unsigned short ModeNo, static unsigned short XGI_GetResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { - unsigned short resindex; - - if (ModeNo <= 0x13) - /* si+St_ResInfo */ - resindex = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; - else - /* si+Ext_ResInfo */ - resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - return resindex; + /* si+Ext_ResInfo */ + return pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; } static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, @@ -1079,31 +923,23 @@ static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); - if (ModeNo <= 0x13) { - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - tempax = pVBInfo->StResInfo[resindex].HTotal; - tempbx = pVBInfo->StResInfo[resindex].VTotal; - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - tempax = pVBInfo->ModeResInfo[resindex].HTotal; - tempbx = pVBInfo->ModeResInfo[resindex].VTotal; - } + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + tempax = pVBInfo->ModeResInfo[resindex].HTotal; + tempbx = pVBInfo->ModeResInfo[resindex].VTotal; if (modeflag & HalfDCLK) tempax = tempax >> 1; - if (ModeNo > 0x13) { - if (modeflag & HalfDCLK) - tempax = tempax << 1; + if (modeflag & HalfDCLK) + tempax = tempax << 1; - temp = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + temp = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - if (temp & InterlaceMode) - tempbx = tempbx >> 1; + if (temp & InterlaceMode) + tempbx = tempbx >> 1; - if (modeflag & DoubleScanMode) - tempbx = tempbx << 1; - } + if (modeflag & DoubleScanMode) + tempbx = tempbx << 1; tempcx = 8; @@ -1251,18 +1087,10 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, unsigned short CRT2Index, VCLKIndex; unsigned short modeflag, resinfo; - if (ModeNo <= 0x13) { - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; - CRT2Index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; - } else { - /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - CRT2Index = pVBInfo->RefIndex[RefreshRateTableIndex]. - Ext_CRT2CRTC; - } + /* si+Ext_ResInfo */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + CRT2Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; if (pVBInfo->IF_DEF_LVDS == 0) { CRT2Index = CRT2Index >> 6; /* for LCD */ @@ -1311,23 +1139,13 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, VCLKIndex += 25; } } else { /* for CRT2 */ - /* Port 3cch */ - VCLKIndex = (unsigned char) inb((pVBInfo->P3ca + 0x02)); - VCLKIndex = ((VCLKIndex >> 2) & 0x03); - if (ModeNo > 0x13) { - /* di+Ext_CRTVCLK */ - VCLKIndex = pVBInfo->RefIndex[ - RefreshRateTableIndex]. + /* di+Ext_CRTVCLK */ + VCLKIndex = pVBInfo->RefIndex[RefreshRateTableIndex]. Ext_CRTVCLK; - VCLKIndex &= IndexMask; - } + VCLKIndex &= IndexMask; } } else { /* LVDS */ - if (ModeNo <= 0x13) - VCLKIndex = CRT2Index; - else - VCLKIndex = CRT2Index; - + VCLKIndex = CRT2Index; VCLKIndex = VCLKIndex >> 6; if ((pVBInfo->LCDResInfo == Panel_800x600) || (pVBInfo->LCDResInfo == Panel_320x480)) @@ -1424,27 +1242,13 @@ static void XGI_SetCRT1FIFO(unsigned short ModeNo, data &= 0xfe; xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); /* diable auto-threshold */ - if (ModeNo > 0x13) { - xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x34); - data = xgifb_reg_get(pVBInfo->P3c4, 0x09); - data &= 0xC0; - xgifb_reg_set(pVBInfo->P3c4, 0x09, data | 0x30); - data = xgifb_reg_get(pVBInfo->P3c4, 0x3D); - data |= 0x01; - xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); - } else { - if (HwDeviceExtension->jChipType == XG27) { - xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x0E); - data = xgifb_reg_get(pVBInfo->P3c4, 0x09); - data &= 0xC0; - xgifb_reg_set(pVBInfo->P3c4, 0x09, data | 0x20); - } else { - xgifb_reg_set(pVBInfo->P3c4, 0x08, 0xAE); - data = xgifb_reg_get(pVBInfo->P3c4, 0x09); - data &= 0xF0; - xgifb_reg_set(pVBInfo->P3c4, 0x09, data); - } - } + xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x34); + data = xgifb_reg_get(pVBInfo->P3c4, 0x09); + data &= 0xC0; + xgifb_reg_set(pVBInfo->P3c4, 0x09, data | 0x30); + data = xgifb_reg_get(pVBInfo->P3c4, 0x3D); + data |= 0x01; + xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); if (HwDeviceExtension->jChipType == XG21) XGI_SetXG21FPBits(pVBInfo); /* Fix SR9[7:6] can't read back */ @@ -1459,13 +1263,9 @@ static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension, unsigned char index; - if (ModeNo <= 0x13) - VCLK = 0; - else { - index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; - index &= IndexMask; - VCLK = pVBInfo->VCLKData[index].CLOCK; - } + index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; + index &= IndexMask; + VCLK = pVBInfo->VCLKData[index].CLOCK; data = xgifb_reg_get(pVBInfo->P3c4, 0x32); data &= 0xf3; @@ -1501,31 +1301,20 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, unsigned short data, data2, data3, infoflag = 0, modeflag, resindex, xres; - if (ModeNo > 0x13) { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - infoflag = pVBInfo->RefIndex[RefreshRateTableIndex]. - Ext_InfoFlag; - } else - /* si+St_ModeFlag */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; if (xgifb_reg_get(pVBInfo->P3d4, 0x31) & 0x01) xgifb_reg_and_or(pVBInfo->P3c4, 0x1F, 0x3F, 0x00); - if (ModeNo > 0x13) - data = infoflag; - else - data = 0; - + data = infoflag; data2 = 0; - if (ModeNo > 0x13) { - if (pVBInfo->ModeType > 0x02) { - data2 |= 0x02; - data3 = pVBInfo->ModeType - ModeVGA; - data3 = data3 << 2; - data2 |= data3; - } + if (pVBInfo->ModeType > 0x02) { + data2 |= 0x02; + data3 = pVBInfo->ModeType - ModeVGA; + data3 = data3 << 2; + data2 |= data3; } data &= InterlaceMode; @@ -1535,10 +1324,7 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x3F, data2); resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); - if (ModeNo <= 0x13) - xres = pVBInfo->StResInfo[resindex].HTotal; - else - xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ + xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ data = 0x0000; if (infoflag & InterlaceMode) { @@ -1561,10 +1347,8 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, if (modeflag & LineCompareOff) data2 |= 0x08; - if (ModeNo > 0x13) { - if (pVBInfo->ModeType == ModeEGA) - data2 |= 0x40; - } + if (pVBInfo->ModeType == ModeEGA) + data2 |= 0x40; xgifb_reg_and_or(pVBInfo->P3c4, 0x0F, ~0x48, data2); data = 0x60; @@ -1641,11 +1425,7 @@ static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex, ah, dh; const unsigned short *table = NULL; - if (ModeNo <= 0x13) - data = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - data = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - + data = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; data &= DACInfoFlag; time = 64; @@ -1733,34 +1513,20 @@ static void XGI_GetLVDSResInfo(unsigned short ModeNo, { unsigned short resindex, xres, yres, modeflag; - if (ModeNo <= 0x13) - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; - else - /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + /* si+Ext_ResInfo */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - if (ModeNo <= 0x13) - /* si+St_ResInfo */ - resindex = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; - else - /* si+Ext_ResInfo */ - resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + /* si+Ext_ResInfo */ + resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - if (ModeNo <= 0x13) { - xres = pVBInfo->StResInfo[resindex].HTotal; - yres = pVBInfo->StResInfo[resindex].VTotal; - } else { - xres = pVBInfo->ModeResInfo[resindex].HTotal; - yres = pVBInfo->ModeResInfo[resindex].VTotal; - } - if (ModeNo > 0x13) { - if (modeflag & HalfDCLK) - xres = xres << 1; + xres = pVBInfo->ModeResInfo[resindex].HTotal; + yres = pVBInfo->ModeResInfo[resindex].VTotal; - if (modeflag & DoubleScanMode) - yres = yres << 1; - } + if (modeflag & HalfDCLK) + xres = xres << 1; + + if (modeflag & DoubleScanMode) + yres = yres << 1; if (xres == 720) xres = 640; @@ -1782,32 +1548,16 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, tempbx = BX; - if (ModeNo <= 0x13) { - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; - } + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; tempal = tempal & 0x0f; if (tempbx <= 1) { /* ExpLink */ - if (ModeNo <= 0x13) { - /* find no Ext_CRT2CRTC2 */ - tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; - } else { - tempal = pVBInfo->RefIndex[RefreshRateTableIndex]. - Ext_CRT2CRTC; - } + tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { - if (ModeNo <= 0x13) - tempal = pVBInfo->SModeIDTable[ModeIdIndex]. - St_CRT2CRTC2; - else - tempal = pVBInfo->RefIndex[ - RefreshRateTableIndex]. + tempal = pVBInfo->RefIndex[RefreshRateTableIndex]. Ext_CRT2CRTC2; } @@ -1875,9 +1625,6 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, tempbx = tempdi[i].MASK; tempdx = pVBInfo->LCDInfo; - if (ModeNo <= 0x13) /* alan 09/10/2003 */ - tempdx |= SetLCDStdMode; - if (modeflag & HalfDCLK) tempdx |= SetLCDLowResolution; @@ -2231,15 +1978,8 @@ static void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo, struct XGI330_TVDataTablStruct *tempdi = NULL; tempbx = BX; - - if (ModeNo <= 0x13) { - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; - } - + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; tempal = tempal & 0x3f; table = tempbx; @@ -2406,11 +2146,7 @@ static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, struct XGI_LVDSCRT1HDataStruct *LCDPtr = NULL; struct XGI_LVDSCRT1VDataStruct *LCDPtr1 = NULL; - if (ModeNo <= 0x13) - index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; - else - index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; - + index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; index = index & IndexMask; tempbx = 0; @@ -2526,11 +2262,7 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, struct XGI330_LCDDataDesStruct *LCDPtr = NULL; struct XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL; - if (ModeNo > 0x13) - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - else - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; tempbx = 3; if (pVBInfo->LCDInfo & EnableScalingLCD) LCDPtr1 = @@ -2822,12 +2554,8 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, unsigned short index, modeflag; unsigned char tempal; - if (ModeNo <= 0x13) - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + /* si+Ext_ResInfo */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; if ((pVBInfo->SetFlag & ProgrammingCRT2) && (!(pVBInfo->LCDInfo & EnableScalingLCD))) { /* {LCDA/LCDB} */ @@ -2888,9 +2616,6 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, if ((pVBInfo->LCDInfo & EnableScalingLCD) && (modeflag & Charx8Dot)) tempal = tempal ^ tempal; /* ; set to VCLK25MHz always */ - if (ModeNo <= 0x13) - return tempal; - tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; return tempal; } @@ -3072,11 +2797,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, { unsigned short tempax, push, tempbx, temp, modeflag; - if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; pVBInfo->SetFlag = 0; pVBInfo->ModeType = modeflag & ModeTypeMask; tempbx = 0; @@ -3276,17 +2997,8 @@ static void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex, resinfo = 0; if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (ModeNo <= 0x13) { - modeflag = pVBInfo->SModeIDTable[ModeIdIndex]. - St_ModeFlag; /* si+St_ModeFlag */ - resinfo = pVBInfo->SModeIDTable[ModeIdIndex]. - St_ResInfo; /* si+St_ResInfo */ - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex]. - Ext_ModeFlag; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex]. - Ext_RESINFO; /* si+Ext_ResInfo */ - } + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; if (pVBInfo->VBInfo & SetCRT2ToTV) { temp = xgifb_reg_get(pVBInfo->P3d4, 0x35); @@ -3373,15 +3085,9 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo, pVBInfo->LCDTypeInfo = 0; pVBInfo->LCDInfo = 0; - if (ModeNo <= 0x13) { - /* si+St_ModeFlag // */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - /* si+Ext_ResInfo // */ - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - } - + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + /* si+Ext_ResInfo // */ + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; temp = xgifb_reg_get(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */ tempbx = temp & 0x0F; @@ -3435,8 +3141,8 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo, if (pVBInfo->IF_DEF_LVDS == 0) { if ((pVBInfo->LCDResInfo == Panel_1400x1050) && (pVBInfo->VBInfo - & SetCRT2ToLCD) && (ModeNo > 0x13) && (resinfo - == 9) && (!(tempbx & EnableScalingLCD))) + & SetCRT2ToLCD) && (resinfo == 9) && + (!(tempbx & EnableScalingLCD))) /* set to center in 1280x1024 LCDB for Panel_1400x1050 */ tempbx |= SetLCDtoNonExpanding; } @@ -3446,12 +3152,9 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo, if (!(tempbx & SetLCDtoNonExpanding)) { tempbx |= XGI_EnableLVDSDDA; } else { - if (ModeNo > 0x13) { - if (pVBInfo->LCDResInfo - == Panel_1024x768) { - if (resinfo == 4) {/* 512x384 */ - tempbx |= XGI_EnableLVDSDDA; - } + if (pVBInfo->LCDResInfo == Panel_1024x768) { + if (resinfo == 4) {/* 512x384 */ + tempbx |= XGI_EnableLVDSDDA; } } } @@ -3467,56 +3170,17 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo, pVBInfo->LCDInfo = tempbx; - if (pVBInfo->IF_DEF_LVDS == 0) { - if (tempax & (LockLCDBToA | StLCDBToA)) { - if (pVBInfo->VBInfo & SetInSlaveMode) { - if (!(tempax & LockLCDBToA)) { - if (ModeNo <= 0x13) { - pVBInfo->VBInfo &= - ~(SetSimuScanMode | - SetInSlaveMode | - SetCRT2ToLCD); - pVBInfo->VBInfo |= - XGI_SetCRT2ToLCDA | - SetCRT2ToDualEdge; - } - } - } - } - } - return 1; } unsigned char XGI_SearchModeID(unsigned short ModeNo, unsigned short *ModeIdIndex, struct vb_device_info *pVBInfo) { - if (ModeNo <= 5) - ModeNo |= 1; - if (ModeNo <= 0x13) { - for (*ModeIdIndex = 0;; (*ModeIdIndex)++) { - if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == - ModeNo) - break; - if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == - 0xFF) - return 0; - } - - if (ModeNo == 0x07) - (*ModeIdIndex)++; /* 400 lines */ - if (ModeNo <= 3) - (*ModeIdIndex) += 2; /* 400 lines */ - /* else 350 lines */ - } else { - for (*ModeIdIndex = 0;; (*ModeIdIndex)++) { - if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == - ModeNo) - break; - if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == - 0xFF) - return 0; - } + for (*ModeIdIndex = 0;; (*ModeIdIndex)++) { + if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo) + break; + if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF) + return 0; } return 1; @@ -3783,21 +3447,16 @@ static void XGI_GetCRT2ResInfo(unsigned short ModeNo, unsigned short xres, yres, modeflag, resindex; resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); - if (ModeNo <= 0x13) { - xres = pVBInfo->StResInfo[resindex].HTotal; - yres = pVBInfo->StResInfo[resindex].VTotal; - } else { - xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ - yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ - /* si+St_ModeFlag */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ + yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ + /* si+St_ModeFlag */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - if (modeflag & HalfDCLK) - xres *= 2; + if (modeflag & HalfDCLK) + xres *= 2; - if (modeflag & DoubleScanMode) - yres *= 2; - } + if (modeflag & DoubleScanMode) + yres *= 2; if (pVBInfo->VBInfo & SetCRT2ToLCD) { if (pVBInfo->IF_DEF_LVDS == 0) { @@ -3861,37 +3520,23 @@ static void XGI_GetRAMDAC2DATA(unsigned short ModeNo, struct vb_device_info *pVBInfo) { unsigned short tempax, tempbx, temp1, temp2, modeflag = 0, tempcx, - StandTableIndex, CRT1Index; + CRT1Index; pVBInfo->RVBHCMAX = 1; pVBInfo->RVBHCFACT = 1; - - if (ModeNo <= 0x13) { - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo); - tempax = pVBInfo->StandTable[StandTableIndex].CRTC[0]; - tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[6]; - temp1 = pVBInfo->StandTable[StandTableIndex].CRTC[7]; - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex]. - Ext_CRT1CRTC; - CRT1Index &= IndexMask; - temp1 = (unsigned short) pVBInfo-> - XGINEWUB_CRT1Table[CRT1Index].CR[0]; - temp2 = (unsigned short) pVBInfo-> - XGINEWUB_CRT1Table[CRT1Index].CR[5]; - tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8); - tempbx = (unsigned short) pVBInfo-> - XGINEWUB_CRT1Table[CRT1Index].CR[8]; - tempcx = (unsigned short) pVBInfo-> - XGINEWUB_CRT1Table[CRT1Index].CR[14] << 8; - tempcx &= 0x0100; - tempcx = tempcx << 2; - tempbx |= tempcx; - temp1 = (unsigned short) pVBInfo-> - XGINEWUB_CRT1Table[CRT1Index].CR[9]; - } + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + CRT1Index &= IndexMask; + temp1 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[0]; + temp2 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5]; + tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8); + tempbx = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[8]; + tempcx = (unsigned short) + pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14] << 8; + tempcx &= 0x0100; + tempcx = tempcx << 2; + tempbx |= tempcx; + temp1 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9]; if (temp1 & 0x01) tempbx |= 0x0100; @@ -3921,16 +3566,9 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, struct SiS_LCDData *LCDPtr = NULL; struct SiS_TVData *TVPtr = NULL; - if (ModeNo <= 0x13) { - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; - } else { - /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - } - + /* si+Ext_ResInfo */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; pVBInfo->NewFlickerMode = 0; pVBInfo->RVBHRS = 50; @@ -4134,11 +3772,7 @@ static unsigned short XGI_GetColorDepth(unsigned short ModeNo, short index; unsigned short modeflag; - if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; index = (modeflag & ModeTypeMask) - ModeEGA; if (index < 0) @@ -4157,11 +3791,7 @@ static unsigned short XGI_GetOffset(unsigned short ModeNo, ColorDepth[] = { 0x01, 0x02, 0x04 }; modeinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo; - if (ModeNo <= 0x14) - infoflag = 0; - else - infoflag = pVBInfo-> - RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; index = (modeinfo >> 8) & 0xFF; @@ -4221,12 +3851,9 @@ static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, { unsigned short tempcx = 0, CRT1Index = 0, resinfo = 0; - if (ModeNo > 0x13) { - CRT1Index = pVBInfo-> - RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - CRT1Index &= IndexMask; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - } + CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + CRT1Index &= IndexMask; + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex, HwDeviceExtension, pVBInfo); @@ -4247,17 +3874,10 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short temp = 0, tempax = 0, tempbx = 0, tempcx = 0, pushbx = 0, CRT1Index = 0, modeflag, resinfo = 0; - if (ModeNo > 0x13) { - CRT1Index = pVBInfo-> - RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - CRT1Index &= IndexMask; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - } - - if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + CRT1Index &= IndexMask; + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* bainy change table name */ if (modeflag & HalfDCLK) { @@ -4415,18 +4035,11 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short push1, push2, tempax, tempbx = 0, tempcx, temp, resinfo, modeflag, CRT1Index; - if (ModeNo <= 0x13) { - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; - } else { - /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - CRT1Index = pVBInfo-> - RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - CRT1Index &= IndexMask; - } + /* si+Ext_ResInfo */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + CRT1Index &= IndexMask; if (!(pVBInfo->VBInfo & SetInSlaveMode)) return; @@ -4493,8 +4106,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, temp -= 6; if (pVBInfo->TVInfo & TVSimuMode) { temp -= 4; - if (ModeNo > 0x13) - temp -= 10; + temp -= 10; } } } else { @@ -4539,48 +4151,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->VBInfo & SetCRT2ToTV) { if (pVBInfo->TVInfo & TVSimuMode) { - if ((ModeNo == 0x06) || (ModeNo == 0x10) || (ModeNo - == 0x11) || (ModeNo == 0x13) || (ModeNo - == 0x0F)) { - xgifb_reg_set(pVBInfo->Part1Port, 0x07, 0x5b); - xgifb_reg_set(pVBInfo->Part1Port, 0x08, 0x03); - } - - if ((ModeNo == 0x00) || (ModeNo == 0x01)) { - if (pVBInfo->TVInfo & SetNTSCTV) { - xgifb_reg_set(pVBInfo->Part1Port, - 0x07, 0x2A); - xgifb_reg_set(pVBInfo->Part1Port, - 0x08, 0x61); - } else { - xgifb_reg_set(pVBInfo->Part1Port, - 0x07, 0x2A); - xgifb_reg_set(pVBInfo->Part1Port, - 0x08, 0x41); - xgifb_reg_set(pVBInfo->Part1Port, - 0x0C, 0xF0); - } - } - - if ((ModeNo == 0x02) || (ModeNo == 0x03) || (ModeNo - == 0x07)) { - if (pVBInfo->TVInfo & SetNTSCTV) { - xgifb_reg_set(pVBInfo->Part1Port, - 0x07, 0x54); - xgifb_reg_set(pVBInfo->Part1Port, - 0x08, 0x00); - } else { - xgifb_reg_set(pVBInfo->Part1Port, - 0x07, 0x55); - xgifb_reg_set(pVBInfo->Part1Port, - 0x08, 0x00); - xgifb_reg_set(pVBInfo->Part1Port, - 0x0C, 0xF0); - } - } - - if ((ModeNo == 0x04) || (ModeNo == 0x05) || (ModeNo - == 0x0D) || (ModeNo == 0x50)) { + if (ModeNo == 0x50) { if (pVBInfo->TVInfo & SetNTSCTV) { xgifb_reg_set(pVBInfo->Part1Port, 0x07, 0x30); @@ -4789,18 +4360,10 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned long longtemp, tempeax, tempebx, temp2, tempecx; - if (ModeNo <= 0x13) { - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; - crt2crtc = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; - } else { - /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - crt2crtc = pVBInfo->RefIndex[RefreshRateTableIndex]. - Ext_CRT2CRTC; - } + /* si+Ext_ResInfo */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + crt2crtc = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; tempax = 0; @@ -5238,18 +4801,11 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, struct XGI_LCDDesStruct *LCDBDesPtr = NULL; - if (ModeNo <= 0x13) { - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; - } else { - /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex]. - Ext_CRT1CRTC; - CRT1Index &= IndexMask; - } + /* si+Ext_ResInfo */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + CRT1Index &= IndexMask; if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) return; @@ -5535,12 +5091,8 @@ static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned char *tempdi; unsigned short modeflag; - if (ModeNo <= 0x13) - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + /* si+Ext_ResInfo */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; xgifb_reg_set(pVBInfo->Part3Port, 0x00, 0x00); if (pVBInfo->TVInfo & TVSetPAL) { @@ -5598,13 +5150,8 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned long tempebx, tempeax, templong; - if (ModeNo <= 0x13) - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - + /* si+Ext_ResInfo */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; temp = pVBInfo->RVBHCFACT; xgifb_reg_set(pVBInfo->Part4Port, 0x13, temp); @@ -5812,31 +5359,21 @@ static unsigned char XGI_XG21CheckLVDSMode(struct xgifb_video_info *xgifb_info, unsigned short xres, yres, colordepth, modeflag, resindex; resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); - if (ModeNo <= 0x13) { - xres = pVBInfo->StResInfo[resindex].HTotal; - yres = pVBInfo->StResInfo[resindex].VTotal; - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - } else { - xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ - yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ - /* si+St_ModeFlag */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - } + xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ + yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ + /* si+St_ModeFlag */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; if (!(modeflag & Charx8Dot)) { xres /= 9; xres *= 8; } - if (ModeNo > 0x13) { - if ((ModeNo > 0x13) && (modeflag & HalfDCLK)) - xres *= 2; - - if ((ModeNo > 0x13) && (modeflag & DoubleScanMode)) - yres *= 2; + if ((ModeNo > 0x13) && (modeflag & HalfDCLK)) + xres *= 2; - } + if ((ModeNo > 0x13) && (modeflag & DoubleScanMode)) + yres *= 2; if (xres > xgifb_info->lvds_data.LVDSHDE) return 0; @@ -5844,16 +5381,11 @@ static unsigned char XGI_XG21CheckLVDSMode(struct xgifb_video_info *xgifb_info, if (yres > xgifb_info->lvds_data.LVDSVDE) return 0; - if (ModeNo > 0x13) { - if (xres != xgifb_info->lvds_data.LVDSHDE || - yres != xgifb_info->lvds_data.LVDSVDE) { - colordepth = XGI_GetColorDepth(ModeNo, - ModeIdIndex, - pVBInfo); - if (colordepth > 2) - return 0; - - } + if (xres != xgifb_info->lvds_data.LVDSHDE || + yres != xgifb_info->lvds_data.LVDSVDE) { + colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, pVBInfo); + if (colordepth > 2) + return 0; } return 1; } @@ -5889,17 +5421,10 @@ static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info, XGI_SetXG21FPBits(pVBInfo); resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); - if (ModeNo <= 0x13) { - xres = pVBInfo->StResInfo[resindex].HTotal; - yres = pVBInfo->StResInfo[resindex].VTotal; - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - } else { - xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ - yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ - /* si+St_ModeFlag */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - } + xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ + yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ + /* si+St_ModeFlag */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; if (!(modeflag & Charx8Dot)) xres = xres * 8 / 9; @@ -5907,8 +5432,6 @@ static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info, LVDSHT = xgifb_info->lvds_data.LVDSHT; LVDSHBS = xres + (xgifb_info->lvds_data.LVDSHDE - xres) / 2; - if ((ModeNo <= 0x13) && (modeflag & HalfDCLK)) - LVDSHBS -= xres / 4; if (LVDSHBS > LVDSHT) LVDSHBS -= LVDSHT; @@ -5926,7 +5449,7 @@ static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info, LVDSVT = xgifb_info->lvds_data.LVDSVT; LVDSVBS = yres + (xgifb_info->lvds_data.LVDSVDE - yres) / 2; - if ((ModeNo > 0x13) && (modeflag & DoubleScanMode)) + if (modeflag & DoubleScanMode) LVDSVBS += yres / 2; if (LVDSVBS > LVDSVT) @@ -6529,12 +6052,7 @@ static void XGI_SetAntiFlicker(unsigned short ModeNo, tempbx = XGI_GetTVPtrIndex(pVBInfo); tempbx &= 0xFE; - - if (ModeNo <= 0x13) - index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex; - else - index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex; - + index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex; tempbx += index; tempah = TVAntiFlickList[tempbx]; tempah = tempah << 4; @@ -6552,12 +6070,7 @@ static void XGI_SetEdgeEnhance(unsigned short ModeNo, tempbx = XGI_GetTVPtrIndex(pVBInfo); tempbx &= 0xFE; - - if (ModeNo <= 0x13) - index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex; - else - index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex; - + index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex; tempbx += index; tempah = TVEdgeList[tempbx]; tempah = tempah << 5; @@ -6624,13 +6137,7 @@ static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex, return; } - if (ModeNo <= 0x13) - tempal = pVBInfo->SModeIDTable[ModeIdIndex]. - VB_StTVYFilterIndex; - else - tempal = pVBInfo->EModeIDTable[ModeIdIndex]. - VB_ExtTVYFilterIndex; - + tempal = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex; if (tempcl == 0) index = tempal * 4; else @@ -6705,16 +6212,14 @@ static void XGI_SetCRT2ModeRegs(unsigned short ModeNo, if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)) { tempah = 0x40; /* BTDRAM */ - if (ModeNo > 0x13) { - tempcl = pVBInfo->ModeType; - tempcl -= ModeVGA; - if (tempcl >= 0) { - /* BT Color */ - tempah = (0x008 >> tempcl); - if (tempah == 0) - tempah = 1; - tempah |= 0x040; - } + tempcl = pVBInfo->ModeType; + tempcl -= ModeVGA; + if (tempcl >= 0) { + /* BT Color */ + tempah = (0x008 >> tempcl); + if (tempah == 0) + tempah = 1; + tempah |= 0x040; } if (pVBInfo->VBInfo & SetInSlaveMode) tempah ^= 0x50; /* BTDAC */ @@ -6790,10 +6295,8 @@ static void XGI_SetCRT2ModeRegs(unsigned short ModeNo, if (pVBInfo->VBInfo & SetCRT2ToTV) { tempah |= 0x020; - if (ModeNo > 0x13) { - if (pVBInfo->VBInfo & DriverMode) - tempah = tempah ^ 0x20; - } + if (pVBInfo->VBInfo & DriverMode) + tempah = tempah ^ 0x20; } xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D, ~0x0BF, tempah); @@ -6918,13 +6421,7 @@ unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, unsigned short RefreshRateTableIndex, i, modeflag, index, temp; - if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - if (ModeNo < 0x14) - return 0xFFFF; + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; index = xgifb_reg_get(pVBInfo->P3d4, 0x33); index = index >> pVBInfo->SelectCRT2Rate; @@ -7290,9 +6787,7 @@ static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { - unsigned short StandTableIndex, RefreshRateTableIndex, b3CC, temp; - - unsigned short XGINew_P3cc = pVBInfo->P3cc; + unsigned short StandTableIndex, RefreshRateTableIndex, temp; StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo); XGI_SetSeqRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo); @@ -7333,22 +6828,6 @@ static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info, RefreshRateTableIndex, pVBInfo); } - if ((HwDeviceExtension->jChipType >= XG20) && - (HwDeviceExtension->jChipType < XG27)) { /* fix H/W DCLK/2 bug */ - if ((ModeNo == 0x00) | (ModeNo == 0x01)) { - xgifb_reg_set(pVBInfo->P3c4, 0x2B, 0x4E); - xgifb_reg_set(pVBInfo->P3c4, 0x2C, 0xE9); - b3CC = (unsigned char) inb(XGINew_P3cc); - outb((b3CC |= 0x0C), XGINew_P3cc); - } else if ((ModeNo == 0x04) | (ModeNo == 0x05) | (ModeNo - == 0x0D)) { - xgifb_reg_set(pVBInfo->P3c4, 0x2B, 0x1B); - xgifb_reg_set(pVBInfo->P3c4, 0x2C, 0xE3); - b3CC = (unsigned char) inb(XGINew_P3cc); - outb((b3CC |= 0x0C), XGINew_P3cc); - } - } - if (HwDeviceExtension->jChipType >= XG21) { temp = xgifb_reg_get(pVBInfo->P3d4, 0x38); if (temp & 0xA0) { @@ -7502,13 +6981,8 @@ unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info, pVBInfo)) return 0; - if (ModeNo <= 0x13) { - pVBInfo->ModeType = pVBInfo->SModeIDTable[ModeIdIndex]. - St_ModeFlag & ModeTypeMask; - } else { - pVBInfo->ModeType = pVBInfo->EModeIDTable[ModeIdIndex]. + pVBInfo->ModeType = pVBInfo->EModeIDTable[ModeIdIndex]. Ext_ModeFlag & ModeTypeMask; - } pVBInfo->SetFlag = 0; pVBInfo->VBInfo = DisableCRT2Display; -- cgit v0.10.2 From ace1055e5eae9174489ff91ed7847fd6042ef891 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:14:02 +0300 Subject: staging: xgifb: delete SModeIDTable Delete unused data. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 2561e5a..a0b1a32 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -60,7 +60,6 @@ static const unsigned short XGINew_VGA_DAC[] = { void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) { - pVBInfo->SModeIDTable = (struct XGI_StStruct *) XGI330_SModeIDTable; pVBInfo->StandTable = (struct SiS_StandTable_S *) XGI330_StandTable; pVBInfo->EModeIDTable = (struct XGI_ExtStruct *) XGI330_EModeIDTable; pVBInfo->RefIndex = (struct XGI_Ext2Struct *) XGI330_RefIndex; diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 9287658..5dbc8bc 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -10,18 +10,6 @@ struct XGI_LVDSCRT1VDataStruct { unsigned char Reg[7]; }; -struct XGI_StStruct { - unsigned char St_ModeID; - unsigned short St_ModeFlag; - unsigned char St_StTableIndex; - unsigned char St_CRT2CRTC; - unsigned char St_CRT2CRTC2; - unsigned char St_ResInfo; - unsigned char VB_StTVFlickerIndex; - unsigned char VB_StTVEdgeIndex; - unsigned char VB_StTVYFilterIndex; -}; - struct XGI_ExtStruct { unsigned char Ext_ModeID; unsigned short Ext_ModeFlag; @@ -313,7 +301,6 @@ struct vb_device_info { struct XGI_TimingHStruct *TimingH; struct XGI_TimingVStruct *TimingV; - struct XGI_StStruct *SModeIDTable; struct SiS_StandTable_S *StandTable; struct XGI_ExtStruct *EModeIDTable; struct XGI_Ext2Struct *RefIndex; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index dddf261..7290b15 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -128,32 +128,6 @@ static unsigned char XGI330_SR33; static unsigned char XG40_CRCF = 0x13; static unsigned char XG40_DRAMTypeDefinition = 0xFF ; -static struct XGI_StStruct XGI330_SModeIDTable[] = { - {0x01, 0x9208, 0x01, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00}, - {0x01, 0x1210, 0x14, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00}, - {0x01, 0x1010, 0x17, 0x02, 0x11, 0x00, 0x00, 0x01, 0x01}, - {0x03, 0x8208, 0x03, 0x00, 0x14, 0x00, 0x00, 0x01, 0x02}, - {0x03, 0x0210, 0x16, 0x01, 0x04, 0x01, 0x00, 0x01, 0x02}, - {0x03, 0x0010, 0x18, 0x02, 0x15, 0x00, 0x00, 0x01, 0x03}, - {0x05, 0x9209, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04}, - {0x06, 0x8209, 0x06, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05}, - {0x07, 0x0000, 0x07, 0x03, 0x05, 0x03, 0x00, 0x01, 0x03}, - {0x07, 0x0000, 0x19, 0x02, 0x15, 0x02, 0x00, 0x01, 0x03}, - {0x0d, 0x920a, 0x0d, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04}, - {0x0e, 0x820a, 0x0e, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05}, - {0x0f, 0x0202, 0x11, 0x01, 0x04, 0x01, 0x00, 0x00, 0x05}, - {0x10, 0x0212, 0x12, 0x01, 0x04, 0x01, 0x00, 0x00, 0x05}, - {0x11, 0x0212, 0x1a, 0x04, 0x24, 0x04, 0x00, 0x00, 0x05}, - {0x12, 0x0212, 0x1b, 0x04, 0x24, 0x04, 0x00, 0x00, 0x05}, - {0x13, 0x021b, 0x1c, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04}, - {0x12, 0x0010, 0x18, 0x02, 0x24, 0x02, 0x00, 0x00, 0x05},/* St_CRT2CRTC2 - not sure */ - {0x12, 0x0210, 0x18, 0x01, 0x24, 0x01, 0x00, 0x00, 0x05},/* St_CRT2CRTC2 - not sure */ - {0xff, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} -}; - - static struct XGI_ExtStruct XGI330_EModeIDTable[] = { {0x6a, 0x2212, 0x0407, 0x3a81, 0x0102, 0x08, 0x07, 0x00, 0x00, 0x07, 0x0e}, -- cgit v0.10.2 From 969f7f3b1d90fa030f1ef16f4122b4ef4f08006d Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:14:03 +0300 Subject: staging: xgifb: delete code for EGA or lower modes All supported modes have ModeType > 2. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index a0b1a32..f1cc210 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -178,13 +178,7 @@ static unsigned char XGI_GetModePtr(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { - unsigned char index; - - if (pVBInfo->ModeType <= 0x02) - index = 0x1B; /* 02 -> ModeEGA */ - else - index = 0x0F; - return index; /* Get pVBInfo->StandTable index */ + return 0x0F; } static void XGI_SetSeqRegs(unsigned short ModeNo, @@ -1308,14 +1302,10 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, data = infoflag; data2 = 0; - - if (pVBInfo->ModeType > 0x02) { - data2 |= 0x02; - data3 = pVBInfo->ModeType - ModeVGA; - data3 = data3 << 2; - data2 |= data3; - } - + data2 |= 0x02; + data3 = pVBInfo->ModeType - ModeVGA; + data3 = data3 << 2; + data2 |= data3; data &= InterlaceMode; if (data) @@ -1346,16 +1336,10 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, if (modeflag & LineCompareOff) data2 |= 0x08; - if (pVBInfo->ModeType == ModeEGA) - data2 |= 0x40; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0F, ~0x48, data2); data = 0x60; - if (pVBInfo->ModeType != ModeText) { - data = data ^ 0x60; - if (pVBInfo->ModeType != ModeEGA) - data = data ^ 0xA0; - } + data = data ^ 0x60; + data = data ^ 0xA0; xgifb_reg_and_or(pVBInfo->P3c4, 0x21, 0x1F, data); XGI_SetVCLKState(HwDeviceExtension, ModeNo, RefreshRateTableIndex, @@ -4127,14 +4111,6 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->LCDResInfo != Panel_1280x960 && pVBInfo->VGAHDE >= 800) { temp -= 7; - if (pVBInfo->ModeType == ModeEGA && - pVBInfo->VGAVDE == 1024) { - temp += 15; - if (pVBInfo->LCDResInfo != - Panel_1280x1024) - temp += 7; - } - if (pVBInfo->VGAHDE >= 1280 && pVBInfo->LCDResInfo != Panel_1280x960 && (pVBInfo->LCDInfo & LCDNonExpanding)) @@ -4822,16 +4798,6 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_and_or(pVBInfo->Part2Port, 0x2B, 0x0F, temp); temp = 0x01; - if (pVBInfo->LCDResInfo == Panel_1280x1024) { - if (pVBInfo->ModeType == ModeEGA) { - if (pVBInfo->VGAHDE >= 1024) { - temp = 0x02; - if (pVBInfo->LCDInfo & XGI_LCDVESATiming) - temp = 0x01; - } - } - } - xgifb_reg_set(pVBInfo->Part2Port, 0x0B, temp); tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */ push1 = tempbx; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 7290b15..6103574 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -129,8 +129,6 @@ static unsigned char XG40_CRCF = 0x13; static unsigned char XG40_DRAMTypeDefinition = 0xFF ; static struct XGI_ExtStruct XGI330_EModeIDTable[] = { - {0x6a, 0x2212, 0x0407, 0x3a81, 0x0102, 0x08, - 0x07, 0x00, 0x00, 0x07, 0x0e}, {0x2e, 0x0a1b, 0x0306, 0x3a57, 0x0101, 0x08, 0x06, 0x00, 0x00, 0x05, 0x06}, {0x2f, 0x0a1b, 0x0305, 0x3a50, 0x0100, 0x08, @@ -149,8 +147,6 @@ static struct XGI_ExtStruct XGI330_EModeIDTable[] = { 0x0d, 0x00, 0x00, 0x06, 0x3d}, {0x36, 0x2a1f, 0x0a0e, 0x3b8c, 0x0000, 0x08, 0x0e, 0x00, 0x00, 0x06, 0x3e}, - {0x37, 0x0212, 0x0508, 0x3aab, 0x0104, 0x08, - 0x08, 0x00, 0x00, 0x00, 0x16}, {0x38, 0x0a1b, 0x0508, 0x3aab, 0x0105, 0x08, 0x08, 0x00, 0x00, 0x00, 0x16}, {0x3a, 0x0e3b, 0x0609, 0x3adc, 0x0107, 0x08, -- cgit v0.10.2 From fb60d0c4f7837413a56285581b249d9268c724f9 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:14:04 +0300 Subject: staging: xgifb: truncate XGI330_StandTable Only single element from XGI330_StandTable is used, so the array can be truncated. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index f1cc210..c71e9dc 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -60,7 +60,7 @@ static const unsigned short XGINew_VGA_DAC[] = { void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) { - pVBInfo->StandTable = (struct SiS_StandTable_S *) XGI330_StandTable; + pVBInfo->StandTable = (struct SiS_StandTable_S *) &XGI330_StandTable; pVBInfo->EModeIDTable = (struct XGI_ExtStruct *) XGI330_EModeIDTable; pVBInfo->RefIndex = (struct XGI_Ext2Struct *) XGI330_RefIndex; pVBInfo->XGINEWUB_CRT1Table @@ -174,13 +174,6 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) } -static unsigned char XGI_GetModePtr(unsigned short ModeNo, - unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - return 0x0F; -} - static void XGI_SetSeqRegs(unsigned short ModeNo, unsigned short StandTableIndex, unsigned short ModeIdIndex, @@ -192,7 +185,7 @@ static void XGI_SetSeqRegs(unsigned short ModeNo, modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; xgifb_reg_set(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */ - tempah = pVBInfo->StandTable[StandTableIndex].SR[0]; + tempah = pVBInfo->StandTable->SR[0]; i = XGI_SetCRT2ToLCDA; if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { @@ -209,7 +202,7 @@ static void XGI_SetSeqRegs(unsigned short ModeNo, for (i = 02; i <= 04; i++) { /* Get SR2,3,4 from file */ - SRdata = pVBInfo->StandTable[StandTableIndex].SR[i - 1]; + SRdata = pVBInfo->StandTable->SR[i - 1]; xgifb_reg_set(pVBInfo->P3c4, i, SRdata); /* Set SR2 3 4 */ } } @@ -227,7 +220,7 @@ static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension, for (i = 0; i <= 0x18; i++) { /* Get CRTC from file */ - CRTCdata = pVBInfo->StandTable[StandTableIndex].CRTC[i]; + CRTCdata = pVBInfo->StandTable->CRTC[i]; xgifb_reg_set(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */ } } @@ -243,7 +236,7 @@ static void XGI_SetATTRegs(unsigned short ModeNo, modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; for (i = 0; i <= 0x13; i++) { - ARdata = pVBInfo->StandTable[StandTableIndex].ATTR[i]; + ARdata = pVBInfo->StandTable->ATTR[i]; if (modeflag & Charx8Dot) { /* ifndef Dot9 */ if (i == 0x13) { if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { @@ -279,7 +272,7 @@ static void XGI_SetGRCRegs(unsigned short StandTableIndex, for (i = 0; i <= 0x08; i++) { /* Get GR from file */ - GRdata = pVBInfo->StandTable[StandTableIndex].GRC[i]; + GRdata = pVBInfo->StandTable->GRC[i]; xgifb_reg_set(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */ } @@ -6754,9 +6747,8 @@ static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info, { unsigned short StandTableIndex, RefreshRateTableIndex, temp; - StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo); XGI_SetSeqRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo); - outb(pVBInfo->StandTable[StandTableIndex].MISC, pVBInfo->P3c2); + outb(pVBInfo->StandTable->MISC, pVBInfo->P3c2); XGI_SetCRTCRegs(HwDeviceExtension, StandTableIndex, pVBInfo); XGI_SetATTRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo); XGI_SetGRCRegs(StandTableIndex, pVBInfo); diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 6103574..d515506 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -266,441 +266,20 @@ static struct XGI_ExtStruct XGI330_EModeIDTable[] = { 0x00, 0x00, 0x00, 0x00, 0x00} }; -static struct SiS_StandTable_S XGI330_StandTable[] = { -/* MD_0_200 */ - { - 0x28, 0x18, 0x08, 0x0800, - {0x09, 0x03, 0x00, 0x02}, - 0x63, - {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f, - 0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x08, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, - 0xff} - }, -/* MD_1_200 */ - { - 0x28, 0x18, 0x08, 0x0800, - {0x09, 0x03, 0x00, 0x02}, - 0x63, - {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f, - 0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x08, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, - 0xff} - }, -/* MD_2_200 */ - { - 0x50, 0x18, 0x08, 0x1000, - {0x01, 0x03, 0x00, 0x02}, - 0x63, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x08, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, - 0xff} - }, -/* MD_3_200 */ - { - 0x50, 0x18, 0x08, 0x1000, - {0x01, 0x03, 0x00, 0x02}, - 0x63, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x08, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, - 0xff} - }, -/* MD_4 */ - { - 0x28, 0x18, 0x08, 0x4000, - {0x09, 0x03, 0x00, 0x02}, - 0x63, - {0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f, - 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, - 0xff}, - {0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x01, 0x00, 0x03, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x00, - 0xff} - }, -/* MD_5 */ - { - 0x28, 0x18, 0x08, 0x4000, - {0x09, 0x03, 0x00, 0x02}, - 0x63, - {0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f, - 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, - 0xff}, - {0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x01, 0x00, 0x03, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x00, - 0xff} - }, -/* MD_6 */ - { - 0x50, 0x18, 0x08, 0x4000, - {0x01, 0x01, 0x00, 0x06}, - 0x63, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2, - 0xff}, - {0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, - 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, - 0x01, 0x00, 0x01, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, - 0xff} - }, -/* MD_7 */ - { - 0x50, 0x18, 0x0e, 0x1000, - {0x00, 0x03, 0x00, 0x03}, - 0xa6, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0x83, 0x85, 0x5d, 0x28, 0x0d, 0x63, 0xba, 0xa3, - 0xff}, - {0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x0e, 0x00, 0x0f, 0x08}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x00, - 0xff} - }, -/* MDA_DAC */ - { - 0x00, 0x00, 0x00, 0x0000, - {0x00, 0x00, 0x00, 0x15}, - 0x15, - {0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, - 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x00, - 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x15, 0x15, - 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, - 0x15, 0x15, 0x15, 0x15}, - {0x15, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f} - }, -/* CGA_DAC */ - { - 0x00, 0x10, 0x04, 0x0114, - {0x11, 0x09, 0x15, 0x00}, - 0x10, - {0x04, 0x14, 0x01, 0x11, 0x09, 0x15, 0x2a, 0x3a, - 0x2e, 0x3e, 0x2b, 0x3b, 0x2f, 0x3f, 0x2a, 0x3a, - 0x2e, 0x3e, 0x2b, 0x3b, 0x2f, 0x3f, 0x00, 0x10, - 0x04}, - {0x14, 0x01, 0x11, 0x09, 0x15, 0x00, 0x10, 0x04, - 0x14, 0x01, 0x11, 0x09, 0x15, 0x2a, 0x3a, 0x2e, - 0x3e, 0x2b, 0x3b, 0x2f}, - {0x3f, 0x2a, 0x3a, 0x2e, 0x3e, 0x2b, 0x3b, 0x2f, - 0x3f} - }, -/* EGA_DAC */ - { - 0x00, 0x10, 0x04, 0x0114, - {0x11, 0x05, 0x15, 0x20}, - 0x30, - {0x24, 0x34, 0x21, 0x31, 0x25, 0x35, 0x08, 0x18, - 0x0c, 0x1c, 0x09, 0x19, 0x0d, 0x1d, 0x28, 0x38, - 0x2c, 0x3c, 0x29, 0x39, 0x2d, 0x3d, 0x02, 0x12, - 0x06}, - {0x16, 0x03, 0x13, 0x07, 0x17, 0x22, 0x32, 0x26, - 0x36, 0x23, 0x33, 0x27, 0x37, 0x0a, 0x1a, 0x0e, - 0x1e, 0x0b, 0x1b, 0x0f}, - {0x1f, 0x2a, 0x3a, 0x2e, 0x3e, 0x2b, 0x3b, 0x2f, - 0x3f} - }, -/* VGA_DAC */ - { - 0x00, 0x10, 0x04, 0x0114, - {0x11, 0x09, 0x15, 0x2a}, - 0x3a, - {0x2e, 0x3e, 0x2b, 0x3b, 0x2f, 0x3f, 0x00, 0x05, - 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x18, 0x1c, 0x20, - 0x24, 0x28, 0x2d, 0x32, 0x38, 0x3f, 0x00, 0x10, - 0x1f}, - {0x2f, 0x3f, 0x1f, 0x27, 0x2f, 0x37, 0x3f, 0x2d, - 0x31, 0x36, 0x3a, 0x3f, 0x00, 0x07, 0x0e, 0x15, - 0x1c, 0x0e, 0x11, 0x15}, - {0x18, 0x1c, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x00, - 0x04} - }, - { - 0x08, 0x0c, 0x10, 0x0a08, - {0x0c, 0x0e, 0x10, 0x0b}, - 0x0c, - {0x0d, 0x0f, 0x10, 0x10, 0x01, 0x08, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x01, 0x00, - 0x04, 0x04, 0x01, 0x00, 0x05, 0x02, 0x05, 0x00, - 0x06}, - {0x01, 0x06, 0x05, 0x06, 0x00, 0x08, 0x01, 0x08, - 0x00, 0x07, 0x02, 0x07, 0x06, 0x07, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00} - }, -/* MD_D */ - { - 0x28, 0x18, 0x08, 0x2000, - {0x09, 0x0f, 0x00, 0x06}, - 0x63, - {0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f, - 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x01, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, - 0xff} - }, -/* MD_E */ - { - 0x50, 0x18, 0x08, 0x4000, - {0x01, 0x0f, 0x00, 0x06}, - 0x63, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x01, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, - 0xff} - }, +static struct SiS_StandTable_S XGI330_StandTable = { /* ExtVGATable */ - { - 0x00, 0x00, 0x00, 0x0000, - {0x01, 0x0f, 0x00, 0x0e}, - 0x23, - {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xea, 0x8c, 0xdf, 0x28, 0x40, 0xe7, 0x04, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x01, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, - 0xff} - }, -/* ROM_SAVEPTR */ - { - 0x9f, 0x3b, 0x00, 0x00c0, - {0x00, 0x00, 0x00, 0x00}, - 0x00, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x3f, - 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1a, 0x00, 0xac, 0x3e, 0x00, 0xc0, - 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00} - }, -/* MD_F */ - { - 0x50, 0x18, 0x0e, 0x8000, - {0x01, 0x0f, 0x00, 0x06}, - 0xa2, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x82, 0x84, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, - 0xff}, - {0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x0b, 0x00, 0x05, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05, - 0xff} - }, -/* MD_10 */ - { - 0x50, 0x18, 0x0e, 0x8000, - {0x01, 0x0f, 0x00, 0x06}, - 0xa3, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x82, 0x84, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x01, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, - 0xff} - }, -/* MD_0_350 */ - { - 0x28, 0x18, 0x0e, 0x0800, - {0x09, 0x03, 0x00, 0x02}, - 0xa3, - {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xb1, 0xbf, 0x1f, - 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0x83, 0x85, 0x5d, 0x14, 0x1f, 0x63, 0xba, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x08, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, - 0xff} - }, -/* MD_1_350 */ - { - 0x28, 0x18, 0x0e, 0x0800, - {0x09, 0x03, 0x00, 0x02}, - 0xa3, - {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f, - 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0x83, 0x85, 0x5d, 0x14, 0x1f, 0x63, 0xba, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x08, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, - 0xff} - }, -/* MD_2_350 */ - { - 0x50, 0x18, 0x0e, 0x1000, - {0x01, 0x03, 0x00, 0x02}, - 0xa3, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0x83, 0x85, 0x5d, 0x28, 0x1f, 0x63, 0xba, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x08, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, - 0xff} - }, -/* MD_3_350 */ - { - 0x50, 0x18, 0x0e, 0x1000, - {0x01, 0x03, 0x00, 0x02}, - 0xa3, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0x83, 0x85, 0x5d, 0x28, 0x1f, 0x63, 0xba, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x08, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, - 0xff} - }, -/* MD_0_1_400 */ - { - 0x28, 0x18, 0x10, 0x0800, - {0x08, 0x03, 0x00, 0x02}, - 0x67, - {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xb1, 0xbf, 0x1f, - 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x0c, 0x00, 0x0f, 0x08}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, - 0xff} - }, -/* MD_2_3_400 */ - { - 0x50, 0x18, 0x10, 0x1000, - {0x00, 0x03, 0x00, 0x02}, - 0x67, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x0c, 0x00, 0x0f, 0x08}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, - 0xff} - }, -/* MD_7_400 */ - { - 0x50, 0x18, 0x10, 0x1000, - {0x00, 0x03, 0x00, 0x02}, - 0x66, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3, - 0xff}, - {0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x0e, 0x00, 0x0f, 0x08}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x00, - 0xff} - }, -/* MD_11 */ - { - 0x50, 0x1d, 0x10, 0xa000, - {0x01, 0x0f, 0x00, 0x06}, - 0xe3, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0x0b, 0x3e, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe9, 0x8b, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xc3, - 0xff}, - {0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x01, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01, - 0xff} - }, -/* ExtEGATable */ - { - 0x50, 0x1d, 0x10, 0xa000, - {0x01, 0x0f, 0x00, 0x06}, - 0xe3, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0x0b, 0x3e, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe9, 0x8b, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x01, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, - 0xff} - }, -/* MD_13 */ - { - 0x28, 0x18, 0x08, 0x2000, - {0x01, 0x0f, 0x00, 0x0e}, - 0x63, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x41, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, - 0xff} - } + 0x00, 0x00, 0x00, 0x0000, + {0x01, 0x0f, 0x00, 0x0e}, + 0x23, + {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xea, 0x8c, 0xdf, 0x28, 0x40, 0xe7, 0x04, 0xa3, + 0xff}, + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x01, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, + 0xff} }; static struct XGI_TimingHStruct XGI_TimingH[1]; -- cgit v0.10.2 From a157961ca422f7856c7d9ea4370d3720249025f3 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:14:05 +0300 Subject: staging: xgifb: delete StandTableIndex parameters Delete unused function parameters. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index c71e9dc..109d75d 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -175,7 +175,6 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) } static void XGI_SetSeqRegs(unsigned short ModeNo, - unsigned short StandTableIndex, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { @@ -208,7 +207,6 @@ static void XGI_SetSeqRegs(unsigned short ModeNo, } static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension, - unsigned short StandTableIndex, struct vb_device_info *pVBInfo) { unsigned char CRTCdata; @@ -226,7 +224,6 @@ static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension, } static void XGI_SetATTRegs(unsigned short ModeNo, - unsigned short StandTableIndex, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { @@ -264,8 +261,7 @@ static void XGI_SetATTRegs(unsigned short ModeNo, outb(0x20, pVBInfo->P3c0); } -static void XGI_SetGRCRegs(unsigned short StandTableIndex, - struct vb_device_info *pVBInfo) +static void XGI_SetGRCRegs(struct vb_device_info *pVBInfo) { unsigned char GRdata; unsigned short i; @@ -6745,13 +6741,13 @@ static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { - unsigned short StandTableIndex, RefreshRateTableIndex, temp; + unsigned short RefreshRateTableIndex, temp; - XGI_SetSeqRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo); + XGI_SetSeqRegs(ModeNo, ModeIdIndex, pVBInfo); outb(pVBInfo->StandTable->MISC, pVBInfo->P3c2); - XGI_SetCRTCRegs(HwDeviceExtension, StandTableIndex, pVBInfo); - XGI_SetATTRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo); - XGI_SetGRCRegs(StandTableIndex, pVBInfo); + XGI_SetCRTCRegs(HwDeviceExtension, pVBInfo); + XGI_SetATTRegs(ModeNo, ModeIdIndex, pVBInfo); + XGI_SetGRCRegs(pVBInfo); XGI_ClearExt1Regs(pVBInfo); if (HwDeviceExtension->jChipType == XG27) { -- cgit v0.10.2 From 1bb52cc9d590a4ba61b716db81643d0c89b8e810 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:14:06 +0300 Subject: staging: xgifb: delete legacy DAC data Delete DAC data for unsupported legacy modes. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 109d75d..c892e0f 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -16,36 +16,6 @@ #define IndexMask 0xff -static const unsigned short XGINew_MDA_DAC[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, - 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, - 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F}; - -static const unsigned short XGINew_CGA_DAC[] = { - 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, - 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, - 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F, - 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F, - 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, - 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, - 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F, - 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F}; - -static const unsigned short XGINew_EGA_DAC[] = { - 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x05, 0x15, - 0x20, 0x30, 0x24, 0x34, 0x21, 0x31, 0x25, 0x35, - 0x08, 0x18, 0x0C, 0x1C, 0x09, 0x19, 0x0D, 0x1D, - 0x28, 0x38, 0x2C, 0x3C, 0x29, 0x39, 0x2D, 0x3D, - 0x02, 0x12, 0x06, 0x16, 0x03, 0x13, 0x07, 0x17, - 0x22, 0x32, 0x26, 0x36, 0x23, 0x33, 0x27, 0x37, - 0x0A, 0x1A, 0x0E, 0x1E, 0x0B, 0x1B, 0x0F, 0x1F, - 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F}; - static const unsigned short XGINew_VGA_DAC[] = { 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F, @@ -1393,34 +1363,13 @@ static void XGI_WriteDAC(unsigned short dl, static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { - unsigned short data, data2, time, i, j, k, m, n, o, si, di, bx, dl, al, - ah, dh; - const unsigned short *table = NULL; - - data = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - data &= DACInfoFlag; - time = 64; - - if (data == 0x00) - table = XGINew_MDA_DAC; - else if (data == 0x08) - table = XGINew_CGA_DAC; - else if (data == 0x10) - table = XGINew_EGA_DAC; - else if (data == 0x18) { - time = 256; - table = XGINew_VGA_DAC; - } - - if (time == 256) - j = 16; - else - j = time; + unsigned short data, data2, i, k, m, n, o, si, di, bx, dl, al, ah, dh; + const unsigned short *table = XGINew_VGA_DAC; outb(0xFF, pVBInfo->P3c6); outb(0x00, pVBInfo->P3c8); - for (i = 0; i < j; i++) { + for (i = 0; i < 16; i++) { data = table[i]; for (k = 0; k < 3; k++) { @@ -1437,45 +1386,43 @@ static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex, } } - if (time == 256) { - for (i = 16; i < 32; i++) { - data = table[i]; - - for (k = 0; k < 3; k++) - outb(data, pVBInfo->P3c9); - } + for (i = 16; i < 32; i++) { + data = table[i]; - si = 32; + for (k = 0; k < 3; k++) + outb(data, pVBInfo->P3c9); + } - for (m = 0; m < 9; m++) { - di = si; - bx = si + 0x04; - dl = 0; + si = 32; - for (n = 0; n < 3; n++) { - for (o = 0; o < 5; o++) { - dh = table[si]; - ah = table[di]; - al = table[bx]; - si++; - XGI_WriteDAC(dl, ah, al, dh, pVBInfo); - } + for (m = 0; m < 9; m++) { + di = si; + bx = si + 0x04; + dl = 0; - si -= 2; + for (n = 0; n < 3; n++) { + for (o = 0; o < 5; o++) { + dh = table[si]; + ah = table[di]; + al = table[bx]; + si++; + XGI_WriteDAC(dl, ah, al, dh, pVBInfo); + } - for (o = 0; o < 3; o++) { - dh = table[bx]; - ah = table[di]; - al = table[si]; - si--; - XGI_WriteDAC(dl, ah, al, dh, pVBInfo); - } + si -= 2; - dl++; + for (o = 0; o < 3; o++) { + dh = table[bx]; + ah = table[di]; + al = table[si]; + si--; + XGI_WriteDAC(dl, ah, al, dh, pVBInfo); } - si += 5; + dl++; } + + si += 5; } } -- cgit v0.10.2 From 66f38592a0f38c0b731f91d2f62890f2015e8dfd Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:14:07 +0300 Subject: staging: xgifb: XGI_ExtStruct: delete unused fields Delete unused struct fields. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 5dbc8bc..91dba2f 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -14,9 +14,6 @@ struct XGI_ExtStruct { unsigned char Ext_ModeID; unsigned short Ext_ModeFlag; unsigned short Ext_ModeInfo; - unsigned short Ext_Point; - unsigned short Ext_VESAID; - unsigned char Ext_VESAMEMSize; unsigned char Ext_RESINFO; unsigned char VB_ExtTVFlickerIndex; unsigned char VB_ExtTVEdgeIndex; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index d515506..e9d6e7b 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -129,141 +129,75 @@ static unsigned char XG40_CRCF = 0x13; static unsigned char XG40_DRAMTypeDefinition = 0xFF ; static struct XGI_ExtStruct XGI330_EModeIDTable[] = { - {0x2e, 0x0a1b, 0x0306, 0x3a57, 0x0101, 0x08, - 0x06, 0x00, 0x00, 0x05, 0x06}, - {0x2f, 0x0a1b, 0x0305, 0x3a50, 0x0100, 0x08, - 0x05, 0x00, 0x00, 0x05, 0x05}, - {0x30, 0x2a1b, 0x0407, 0x3a81, 0x0103, 0x08, - 0x07, 0x00, 0x00, 0x07, 0x0e}, - {0x31, 0x0a1b, 0x030d, 0x3b85, 0x0000, 0x08, - 0x0d, 0x00, 0x00, 0x06, 0x3d}, - {0x32, 0x0a1b, 0x0a0e, 0x3b8c, 0x0000, 0x08, - 0x0e, 0x00, 0x00, 0x06, 0x3e}, - {0x33, 0x0a1d, 0x0a0d, 0x3b85, 0x0000, 0x08, - 0x0d, 0x00, 0x00, 0x06, 0x3d}, - {0x34, 0x2a1d, 0x0a0e, 0x3b8c, 0x0000, 0x08, - 0x0e, 0x00, 0x00, 0x06, 0x3e}, - {0x35, 0x0a1f, 0x0a0d, 0x3b85, 0x0000, 0x08, - 0x0d, 0x00, 0x00, 0x06, 0x3d}, - {0x36, 0x2a1f, 0x0a0e, 0x3b8c, 0x0000, 0x08, - 0x0e, 0x00, 0x00, 0x06, 0x3e}, - {0x38, 0x0a1b, 0x0508, 0x3aab, 0x0105, 0x08, - 0x08, 0x00, 0x00, 0x00, 0x16}, - {0x3a, 0x0e3b, 0x0609, 0x3adc, 0x0107, 0x08, - 0x09, 0x00, 0x00, 0x00, 0x1e}, - {0x3c, 0x0e3b, 0x070a, 0x3af2, 0x0130, 0x08, - 0x0a, 0x00, 0x00, 0x00, 0x22}, /* mode 1600x1200 + {0x2e, 0x0a1b, 0x0306, 0x06, 0x00, 0x00, 0x05, 0x06}, + {0x2f, 0x0a1b, 0x0305, 0x05, 0x00, 0x00, 0x05, 0x05}, + {0x30, 0x2a1b, 0x0407, 0x07, 0x00, 0x00, 0x07, 0x0e}, + {0x31, 0x0a1b, 0x030d, 0x0d, 0x00, 0x00, 0x06, 0x3d}, + {0x32, 0x0a1b, 0x0a0e, 0x0e, 0x00, 0x00, 0x06, 0x3e}, + {0x33, 0x0a1d, 0x0a0d, 0x0d, 0x00, 0x00, 0x06, 0x3d}, + {0x34, 0x2a1d, 0x0a0e, 0x0e, 0x00, 0x00, 0x06, 0x3e}, + {0x35, 0x0a1f, 0x0a0d, 0x0d, 0x00, 0x00, 0x06, 0x3d}, + {0x36, 0x2a1f, 0x0a0e, 0x0e, 0x00, 0x00, 0x06, 0x3e}, + {0x38, 0x0a1b, 0x0508, 0x08, 0x00, 0x00, 0x00, 0x16}, + {0x3a, 0x0e3b, 0x0609, 0x09, 0x00, 0x00, 0x00, 0x1e}, + {0x3c, 0x0e3b, 0x070a, 0x0a, 0x00, 0x00, 0x00, 0x22}, /* mode 1600x1200 add CRT2MODE [2003/10/07] */ - {0x3d, 0x0e7d, 0x070a, 0x3af2, 0x0131, 0x08, - 0x0a, 0x00, 0x00, 0x00, 0x22}, /* mode 1600x1200 + {0x3d, 0x0e7d, 0x070a, 0x0a, 0x00, 0x00, 0x00, 0x22}, /* mode 1600x1200 add CRT2MODE */ - {0x40, 0x9a1c, 0x0000, 0x3a34, 0x010d, 0x08, - 0x00, 0x00, 0x00, 0x04, 0x00}, - {0x41, 0x9a1d, 0x0000, 0x3a34, 0x010e, 0x08, - 0x00, 0x00, 0x00, 0x04, 0x00}, /* ModeIdIndex = 0x10 */ - {0x43, 0x0a1c, 0x0306, 0x3a57, 0x0110, 0x08, - 0x06, 0x00, 0x00, 0x05, 0x06}, - {0x44, 0x0a1d, 0x0306, 0x3a57, 0x0111, 0x08, - 0x06, 0x00, 0x00, 0x05, 0x06}, - {0x46, 0x2a1c, 0x0407, 0x3a81, 0x0113, 0x08, - 0x07, 0x00, 0x00, 0x07, 0x0e}, - {0x47, 0x2a1d, 0x0407, 0x3a81, 0x0114, 0x08, - 0x07, 0x00, 0x00, 0x07, 0x0e}, - {0x49, 0x0a3c, 0x0508, 0x3aab, 0x0116, 0x08, - 0x08, 0x00, 0x00, 0x00, 0x16}, - {0x4a, 0x0a3d, 0x0508, 0x3aab, 0x0117, 0x08, - 0x08, 0x00, 0x00, 0x00, 0x16}, - {0x4c, 0x0e7c, 0x0609, 0x3adc, 0x0119, 0x08, - 0x09, 0x00, 0x00, 0x00, 0x1e}, - {0x4d, 0x0e7d, 0x0609, 0x3adc, 0x011a, 0x08, - 0x09, 0x00, 0x00, 0x00, 0x1e}, - {0x50, 0x9a1b, 0x0001, 0x3a3b, 0x0132, 0x08, - 0x01, 0x00, 0x00, 0x04, 0x02}, - {0x51, 0xba1b, 0x0103, 0x3a42, 0x0133, 0x08, - 0x03, 0x00, 0x00, 0x07, 0x03}, - {0x52, 0x9a1b, 0x0204, 0x3a49, 0x0134, 0x08, - 0x04, 0x00, 0x00, 0x00, 0x04}, - {0x56, 0x9a1d, 0x0001, 0x3a3b, 0x0135, 0x08, - 0x01, 0x00, 0x00, 0x04, 0x02}, - {0x57, 0xba1d, 0x0103, 0x3a42, 0x0136, 0x08, - 0x03, 0x00, 0x00, 0x07, 0x03}, - {0x58, 0x9a1d, 0x0204, 0x3a49, 0x0137, 0x08, - 0x04, 0x00, 0x00, 0x00, 0x04}, - {0x59, 0x9a1b, 0x0000, 0x3a34, 0x0138, 0x08, - 0x00, 0x00, 0x00, 0x04, 0x00}, - {0x5A, 0x021b, 0x0014, 0x3b83, 0x0138, 0x08, - 0x01, 0x00, 0x00, 0x04, 0x3f}, /* ModeIdIndex = 0x20 */ - {0x5B, 0x0a1d, 0x0014, 0x3b83, 0x0135, 0x08, - 0x01, 0x00, 0x00, 0x04, 0x3f}, - {0x5d, 0x0a1d, 0x0305, 0x3a50, 0x0139, 0x08, - 0x05, 0x00, 0x00, 0x07, 0x05}, - {0x62, 0x0a3f, 0x0306, 0x3a57, 0x013a, 0x08, - 0x06, 0x00, 0x00, 0x05, 0x06}, - {0x63, 0x2a3f, 0x0407, 0x3a81, 0x013b, 0x08, - 0x07, 0x00, 0x00, 0x07, 0x0e}, - {0x64, 0x0a7f, 0x0508, 0x3aab, 0x013c, 0x08, - 0x08, 0x00, 0x00, 0x00, 0x16}, - {0x65, 0x0eff, 0x0609, 0x3adc, 0x013d, 0x08, - 0x09, 0x00, 0x00, 0x00, 0x1e}, - {0x66, 0x0eff, 0x070a, 0x3af2, 0x013e, 0x08, - 0x0a, 0x00, 0x00, 0x00, 0x22}, /* mode 1600x1200 + {0x40, 0x9a1c, 0x0000, 0x00, 0x00, 0x00, 0x04, 0x00}, + {0x41, 0x9a1d, 0x0000, 0x00, 0x00, 0x00, 0x04, 0x00}, + {0x43, 0x0a1c, 0x0306, 0x06, 0x00, 0x00, 0x05, 0x06}, + {0x44, 0x0a1d, 0x0306, 0x06, 0x00, 0x00, 0x05, 0x06}, + {0x46, 0x2a1c, 0x0407, 0x07, 0x00, 0x00, 0x07, 0x0e}, + {0x47, 0x2a1d, 0x0407, 0x07, 0x00, 0x00, 0x07, 0x0e}, + {0x49, 0x0a3c, 0x0508, 0x08, 0x00, 0x00, 0x00, 0x16}, + {0x4a, 0x0a3d, 0x0508, 0x08, 0x00, 0x00, 0x00, 0x16}, + {0x4c, 0x0e7c, 0x0609, 0x09, 0x00, 0x00, 0x00, 0x1e}, + {0x4d, 0x0e7d, 0x0609, 0x09, 0x00, 0x00, 0x00, 0x1e}, + {0x50, 0x9a1b, 0x0001, 0x01, 0x00, 0x00, 0x04, 0x02}, + {0x51, 0xba1b, 0x0103, 0x03, 0x00, 0x00, 0x07, 0x03}, + {0x52, 0x9a1b, 0x0204, 0x04, 0x00, 0x00, 0x00, 0x04}, + {0x56, 0x9a1d, 0x0001, 0x01, 0x00, 0x00, 0x04, 0x02}, + {0x57, 0xba1d, 0x0103, 0x03, 0x00, 0x00, 0x07, 0x03}, + {0x58, 0x9a1d, 0x0204, 0x04, 0x00, 0x00, 0x00, 0x04}, + {0x59, 0x9a1b, 0x0000, 0x00, 0x00, 0x00, 0x04, 0x00}, + {0x5A, 0x021b, 0x0014, 0x01, 0x00, 0x00, 0x04, 0x3f}, + {0x5B, 0x0a1d, 0x0014, 0x01, 0x00, 0x00, 0x04, 0x3f}, + {0x5d, 0x0a1d, 0x0305, 0x05, 0x00, 0x00, 0x07, 0x05}, + {0x62, 0x0a3f, 0x0306, 0x06, 0x00, 0x00, 0x05, 0x06}, + {0x63, 0x2a3f, 0x0407, 0x07, 0x00, 0x00, 0x07, 0x0e}, + {0x64, 0x0a7f, 0x0508, 0x08, 0x00, 0x00, 0x00, 0x16}, + {0x65, 0x0eff, 0x0609, 0x09, 0x00, 0x00, 0x00, 0x1e}, + {0x66, 0x0eff, 0x070a, 0x0a, 0x00, 0x00, 0x00, 0x22}, /* mode 1600x1200 add CRT2MODE */ - {0x68, 0x067b, 0x080b, 0x3b17, 0x013f, 0x08, - 0x0b, 0x00, 0x00, 0x00, 0x29}, - {0x69, 0x06fd, 0x080b, 0x3b17, 0x0140, 0x08, - 0x0b, 0x00, 0x00, 0x00, 0x29}, - {0x6b, 0x07ff, 0x080b, 0x3b17, 0x0141, 0x10, - 0x0b, 0x00, 0x00, 0x00, 0x29}, - {0x6c, 0x067b, 0x090c, 0x3b37, 0x0000, 0x08, - 0x0c, 0x00, 0x00, 0x00, 0x2f}, - {0x6d, 0x06fd, 0x090c, 0x3b37, 0x0000, 0x10, - 0x0c, 0x00, 0x00, 0x00, 0x2f}, - {0x6e, 0x07ff, 0x090c, 0x3b37, 0x0000, 0x10, - 0x0c, 0x00, 0x00, 0x00, 0x2f}, - {0x70, 0x2a1b, 0x0410, 0x3b52, 0x0000, 0x08, - 0x10, 0x00, 0x00, 0x07, 0x34}, - {0x71, 0x0a1b, 0x0511, 0x3b63, 0x0000, 0x08, - 0x11, 0x00, 0x00, 0x00, 0x37}, - {0x74, 0x0a1d, 0x0511, 0x3b63, 0x0000, 0x08, - 0x11, 0x00, 0x00, 0x00, 0x37}, /* ModeIdIndex = 0x30 */ - {0x75, 0x0a3d, 0x0612, 0x3b74, 0x0000, 0x08, - 0x12, 0x00, 0x00, 0x00, 0x3a}, - {0x76, 0x2a1f, 0x0410, 0x3b52, 0x0000, 0x08, - 0x10, 0x00, 0x00, 0x07, 0x34}, - {0x77, 0x0a1f, 0x0511, 0x3b63, 0x0000, 0x08, - 0x11, 0x00, 0x00, 0x00, 0x37}, - {0x78, 0x0a3f, 0x0612, 0x3b74, 0x0000, 0x08, - 0x12, 0x00, 0x00, 0x00, 0x3a}, - {0x79, 0x0a3b, 0x0612, 0x3b74, 0x0000, 0x08, - 0x12, 0x00, 0x00, 0x00, 0x3a}, - {0x7a, 0x2a1d, 0x0410, 0x3b52, 0x0000, 0x08, - 0x10, 0x00, 0x00, 0x07, 0x34}, - {0x7b, 0x0e3b, 0x060f, 0x3ad0, 0x0000, 0x08, - 0x0f, 0x00, 0x00, 0x00, 0x1d}, - {0x7c, 0x0e7d, 0x060f, 0x3ad0, 0x0000, 0x08, - 0x0f, 0x00, 0x00, 0x00, 0x1d}, - {0x7d, 0x0eff, 0x060f, 0x3ad0, 0x0000, 0x08, - 0x0f, 0x00, 0x00, 0x00, 0x1d}, - {0x20, 0x0e3b, 0x0D16, 0x49e0, 0x0000, 0x08, - 0x16, 0x00, 0x00, 0x00, 0x43}, - {0x21, 0x0e7d, 0x0D16, 0x49e0, 0x0000, 0x08, - 0x16, 0x00, 0x00, 0x00, 0x43}, - {0x22, 0x0eff, 0x0D16, 0x49e0, 0x0000, 0x08, - 0x16, 0x00, 0x00, 0x00, 0x43}, - {0x23, 0x0e3b, 0x0614, 0x49d5, 0x0000, 0x08, - 0x14, 0x00, 0x00, 0x00, 0x41}, - {0x24, 0x0e7d, 0x0614, 0x49d5, 0x0000, 0x08, - 0x14, 0x00, 0x00, 0x00, 0x41}, - {0x25, 0x0eff, 0x0614, 0x49d5, 0x0000, 0x08, - 0x14, 0x00, 0x00, 0x00, 0x41}, - {0x26, 0x063b, 0x0c15, 0x49dc, 0x0000, 0x08, - 0x15, 0x00, 0x00, 0x00, 0x42}, /* ModeIdIndex = 0x40 */ - {0x27, 0x067d, 0x0c15, 0x49dc, 0x0000, 0x08, - 0x15, 0x00, 0x00, 0x00, 0x42}, - {0x28, 0x06ff, 0x0c15, 0x49dc, 0x0000, 0x08, - 0x15, 0x00, 0x00, 0x00, 0x42}, - {0xff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00} + {0x68, 0x067b, 0x080b, 0x0b, 0x00, 0x00, 0x00, 0x29}, + {0x69, 0x06fd, 0x080b, 0x0b, 0x00, 0x00, 0x00, 0x29}, + {0x6b, 0x07ff, 0x080b, 0x0b, 0x00, 0x00, 0x00, 0x29}, + {0x6c, 0x067b, 0x090c, 0x0c, 0x00, 0x00, 0x00, 0x2f}, + {0x6d, 0x06fd, 0x090c, 0x0c, 0x00, 0x00, 0x00, 0x2f}, + {0x6e, 0x07ff, 0x090c, 0x0c, 0x00, 0x00, 0x00, 0x2f}, + {0x70, 0x2a1b, 0x0410, 0x10, 0x00, 0x00, 0x07, 0x34}, + {0x71, 0x0a1b, 0x0511, 0x11, 0x00, 0x00, 0x00, 0x37}, + {0x74, 0x0a1d, 0x0511, 0x11, 0x00, 0x00, 0x00, 0x37}, + {0x75, 0x0a3d, 0x0612, 0x12, 0x00, 0x00, 0x00, 0x3a}, + {0x76, 0x2a1f, 0x0410, 0x10, 0x00, 0x00, 0x07, 0x34}, + {0x77, 0x0a1f, 0x0511, 0x11, 0x00, 0x00, 0x00, 0x37}, + {0x78, 0x0a3f, 0x0612, 0x12, 0x00, 0x00, 0x00, 0x3a}, + {0x79, 0x0a3b, 0x0612, 0x12, 0x00, 0x00, 0x00, 0x3a}, + {0x7a, 0x2a1d, 0x0410, 0x10, 0x00, 0x00, 0x07, 0x34}, + {0x7b, 0x0e3b, 0x060f, 0x0f, 0x00, 0x00, 0x00, 0x1d}, + {0x7c, 0x0e7d, 0x060f, 0x0f, 0x00, 0x00, 0x00, 0x1d}, + {0x7d, 0x0eff, 0x060f, 0x0f, 0x00, 0x00, 0x00, 0x1d}, + {0x20, 0x0e3b, 0x0D16, 0x16, 0x00, 0x00, 0x00, 0x43}, + {0x21, 0x0e7d, 0x0D16, 0x16, 0x00, 0x00, 0x00, 0x43}, + {0x22, 0x0eff, 0x0D16, 0x16, 0x00, 0x00, 0x00, 0x43}, + {0x23, 0x0e3b, 0x0614, 0x14, 0x00, 0x00, 0x00, 0x41}, + {0x24, 0x0e7d, 0x0614, 0x14, 0x00, 0x00, 0x00, 0x41}, + {0x25, 0x0eff, 0x0614, 0x14, 0x00, 0x00, 0x00, 0x41}, + {0x26, 0x063b, 0x0c15, 0x15, 0x00, 0x00, 0x00, 0x42}, + {0x27, 0x067d, 0x0c15, 0x15, 0x00, 0x00, 0x00, 0x42}, + {0x28, 0x06ff, 0x0c15, 0x15, 0x00, 0x00, 0x00, 0x42}, + {0xff, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00} }; static struct SiS_StandTable_S XGI330_StandTable = { -- cgit v0.10.2 From 36ae035b456f0aa7f3bfc8107f8f6f114b5da418 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:14:08 +0300 Subject: staging: xgifb: delete VB_ExtTVFlickerIndex Delete VB_ExtTVFlickerIndex. It's 0 for all video modes. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index c892e0f..a93eec2 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -5944,7 +5944,7 @@ static void XGI_SetAntiFlicker(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { - unsigned short tempbx, index; + unsigned short tempbx; unsigned char tempah; @@ -5953,8 +5953,6 @@ static void XGI_SetAntiFlicker(unsigned short ModeNo, tempbx = XGI_GetTVPtrIndex(pVBInfo); tempbx &= 0xFE; - index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex; - tempbx += index; tempah = TVAntiFlickList[tempbx]; tempah = tempah << 4; diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 91dba2f..65c7989 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -15,7 +15,6 @@ struct XGI_ExtStruct { unsigned short Ext_ModeFlag; unsigned short Ext_ModeInfo; unsigned char Ext_RESINFO; - unsigned char VB_ExtTVFlickerIndex; unsigned char VB_ExtTVEdgeIndex; unsigned char VB_ExtTVYFilterIndex; unsigned char REFindex; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index e9d6e7b..2756aef 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -129,75 +129,75 @@ static unsigned char XG40_CRCF = 0x13; static unsigned char XG40_DRAMTypeDefinition = 0xFF ; static struct XGI_ExtStruct XGI330_EModeIDTable[] = { - {0x2e, 0x0a1b, 0x0306, 0x06, 0x00, 0x00, 0x05, 0x06}, - {0x2f, 0x0a1b, 0x0305, 0x05, 0x00, 0x00, 0x05, 0x05}, - {0x30, 0x2a1b, 0x0407, 0x07, 0x00, 0x00, 0x07, 0x0e}, - {0x31, 0x0a1b, 0x030d, 0x0d, 0x00, 0x00, 0x06, 0x3d}, - {0x32, 0x0a1b, 0x0a0e, 0x0e, 0x00, 0x00, 0x06, 0x3e}, - {0x33, 0x0a1d, 0x0a0d, 0x0d, 0x00, 0x00, 0x06, 0x3d}, - {0x34, 0x2a1d, 0x0a0e, 0x0e, 0x00, 0x00, 0x06, 0x3e}, - {0x35, 0x0a1f, 0x0a0d, 0x0d, 0x00, 0x00, 0x06, 0x3d}, - {0x36, 0x2a1f, 0x0a0e, 0x0e, 0x00, 0x00, 0x06, 0x3e}, - {0x38, 0x0a1b, 0x0508, 0x08, 0x00, 0x00, 0x00, 0x16}, - {0x3a, 0x0e3b, 0x0609, 0x09, 0x00, 0x00, 0x00, 0x1e}, - {0x3c, 0x0e3b, 0x070a, 0x0a, 0x00, 0x00, 0x00, 0x22}, /* mode 1600x1200 + {0x2e, 0x0a1b, 0x0306, 0x06, 0x00, 0x05, 0x06}, + {0x2f, 0x0a1b, 0x0305, 0x05, 0x00, 0x05, 0x05}, + {0x30, 0x2a1b, 0x0407, 0x07, 0x00, 0x07, 0x0e}, + {0x31, 0x0a1b, 0x030d, 0x0d, 0x00, 0x06, 0x3d}, + {0x32, 0x0a1b, 0x0a0e, 0x0e, 0x00, 0x06, 0x3e}, + {0x33, 0x0a1d, 0x0a0d, 0x0d, 0x00, 0x06, 0x3d}, + {0x34, 0x2a1d, 0x0a0e, 0x0e, 0x00, 0x06, 0x3e}, + {0x35, 0x0a1f, 0x0a0d, 0x0d, 0x00, 0x06, 0x3d}, + {0x36, 0x2a1f, 0x0a0e, 0x0e, 0x00, 0x06, 0x3e}, + {0x38, 0x0a1b, 0x0508, 0x08, 0x00, 0x00, 0x16}, + {0x3a, 0x0e3b, 0x0609, 0x09, 0x00, 0x00, 0x1e}, + {0x3c, 0x0e3b, 0x070a, 0x0a, 0x00, 0x00, 0x22}, /* mode 1600x1200 add CRT2MODE [2003/10/07] */ - {0x3d, 0x0e7d, 0x070a, 0x0a, 0x00, 0x00, 0x00, 0x22}, /* mode 1600x1200 + {0x3d, 0x0e7d, 0x070a, 0x0a, 0x00, 0x00, 0x22}, /* mode 1600x1200 add CRT2MODE */ - {0x40, 0x9a1c, 0x0000, 0x00, 0x00, 0x00, 0x04, 0x00}, - {0x41, 0x9a1d, 0x0000, 0x00, 0x00, 0x00, 0x04, 0x00}, - {0x43, 0x0a1c, 0x0306, 0x06, 0x00, 0x00, 0x05, 0x06}, - {0x44, 0x0a1d, 0x0306, 0x06, 0x00, 0x00, 0x05, 0x06}, - {0x46, 0x2a1c, 0x0407, 0x07, 0x00, 0x00, 0x07, 0x0e}, - {0x47, 0x2a1d, 0x0407, 0x07, 0x00, 0x00, 0x07, 0x0e}, - {0x49, 0x0a3c, 0x0508, 0x08, 0x00, 0x00, 0x00, 0x16}, - {0x4a, 0x0a3d, 0x0508, 0x08, 0x00, 0x00, 0x00, 0x16}, - {0x4c, 0x0e7c, 0x0609, 0x09, 0x00, 0x00, 0x00, 0x1e}, - {0x4d, 0x0e7d, 0x0609, 0x09, 0x00, 0x00, 0x00, 0x1e}, - {0x50, 0x9a1b, 0x0001, 0x01, 0x00, 0x00, 0x04, 0x02}, - {0x51, 0xba1b, 0x0103, 0x03, 0x00, 0x00, 0x07, 0x03}, - {0x52, 0x9a1b, 0x0204, 0x04, 0x00, 0x00, 0x00, 0x04}, - {0x56, 0x9a1d, 0x0001, 0x01, 0x00, 0x00, 0x04, 0x02}, - {0x57, 0xba1d, 0x0103, 0x03, 0x00, 0x00, 0x07, 0x03}, - {0x58, 0x9a1d, 0x0204, 0x04, 0x00, 0x00, 0x00, 0x04}, - {0x59, 0x9a1b, 0x0000, 0x00, 0x00, 0x00, 0x04, 0x00}, - {0x5A, 0x021b, 0x0014, 0x01, 0x00, 0x00, 0x04, 0x3f}, - {0x5B, 0x0a1d, 0x0014, 0x01, 0x00, 0x00, 0x04, 0x3f}, - {0x5d, 0x0a1d, 0x0305, 0x05, 0x00, 0x00, 0x07, 0x05}, - {0x62, 0x0a3f, 0x0306, 0x06, 0x00, 0x00, 0x05, 0x06}, - {0x63, 0x2a3f, 0x0407, 0x07, 0x00, 0x00, 0x07, 0x0e}, - {0x64, 0x0a7f, 0x0508, 0x08, 0x00, 0x00, 0x00, 0x16}, - {0x65, 0x0eff, 0x0609, 0x09, 0x00, 0x00, 0x00, 0x1e}, - {0x66, 0x0eff, 0x070a, 0x0a, 0x00, 0x00, 0x00, 0x22}, /* mode 1600x1200 + {0x40, 0x9a1c, 0x0000, 0x00, 0x00, 0x04, 0x00}, + {0x41, 0x9a1d, 0x0000, 0x00, 0x00, 0x04, 0x00}, + {0x43, 0x0a1c, 0x0306, 0x06, 0x00, 0x05, 0x06}, + {0x44, 0x0a1d, 0x0306, 0x06, 0x00, 0x05, 0x06}, + {0x46, 0x2a1c, 0x0407, 0x07, 0x00, 0x07, 0x0e}, + {0x47, 0x2a1d, 0x0407, 0x07, 0x00, 0x07, 0x0e}, + {0x49, 0x0a3c, 0x0508, 0x08, 0x00, 0x00, 0x16}, + {0x4a, 0x0a3d, 0x0508, 0x08, 0x00, 0x00, 0x16}, + {0x4c, 0x0e7c, 0x0609, 0x09, 0x00, 0x00, 0x1e}, + {0x4d, 0x0e7d, 0x0609, 0x09, 0x00, 0x00, 0x1e}, + {0x50, 0x9a1b, 0x0001, 0x01, 0x00, 0x04, 0x02}, + {0x51, 0xba1b, 0x0103, 0x03, 0x00, 0x07, 0x03}, + {0x52, 0x9a1b, 0x0204, 0x04, 0x00, 0x00, 0x04}, + {0x56, 0x9a1d, 0x0001, 0x01, 0x00, 0x04, 0x02}, + {0x57, 0xba1d, 0x0103, 0x03, 0x00, 0x07, 0x03}, + {0x58, 0x9a1d, 0x0204, 0x04, 0x00, 0x00, 0x04}, + {0x59, 0x9a1b, 0x0000, 0x00, 0x00, 0x04, 0x00}, + {0x5A, 0x021b, 0x0014, 0x01, 0x00, 0x04, 0x3f}, + {0x5B, 0x0a1d, 0x0014, 0x01, 0x00, 0x04, 0x3f}, + {0x5d, 0x0a1d, 0x0305, 0x05, 0x00, 0x07, 0x05}, + {0x62, 0x0a3f, 0x0306, 0x06, 0x00, 0x05, 0x06}, + {0x63, 0x2a3f, 0x0407, 0x07, 0x00, 0x07, 0x0e}, + {0x64, 0x0a7f, 0x0508, 0x08, 0x00, 0x00, 0x16}, + {0x65, 0x0eff, 0x0609, 0x09, 0x00, 0x00, 0x1e}, + {0x66, 0x0eff, 0x070a, 0x0a, 0x00, 0x00, 0x22}, /* mode 1600x1200 add CRT2MODE */ - {0x68, 0x067b, 0x080b, 0x0b, 0x00, 0x00, 0x00, 0x29}, - {0x69, 0x06fd, 0x080b, 0x0b, 0x00, 0x00, 0x00, 0x29}, - {0x6b, 0x07ff, 0x080b, 0x0b, 0x00, 0x00, 0x00, 0x29}, - {0x6c, 0x067b, 0x090c, 0x0c, 0x00, 0x00, 0x00, 0x2f}, - {0x6d, 0x06fd, 0x090c, 0x0c, 0x00, 0x00, 0x00, 0x2f}, - {0x6e, 0x07ff, 0x090c, 0x0c, 0x00, 0x00, 0x00, 0x2f}, - {0x70, 0x2a1b, 0x0410, 0x10, 0x00, 0x00, 0x07, 0x34}, - {0x71, 0x0a1b, 0x0511, 0x11, 0x00, 0x00, 0x00, 0x37}, - {0x74, 0x0a1d, 0x0511, 0x11, 0x00, 0x00, 0x00, 0x37}, - {0x75, 0x0a3d, 0x0612, 0x12, 0x00, 0x00, 0x00, 0x3a}, - {0x76, 0x2a1f, 0x0410, 0x10, 0x00, 0x00, 0x07, 0x34}, - {0x77, 0x0a1f, 0x0511, 0x11, 0x00, 0x00, 0x00, 0x37}, - {0x78, 0x0a3f, 0x0612, 0x12, 0x00, 0x00, 0x00, 0x3a}, - {0x79, 0x0a3b, 0x0612, 0x12, 0x00, 0x00, 0x00, 0x3a}, - {0x7a, 0x2a1d, 0x0410, 0x10, 0x00, 0x00, 0x07, 0x34}, - {0x7b, 0x0e3b, 0x060f, 0x0f, 0x00, 0x00, 0x00, 0x1d}, - {0x7c, 0x0e7d, 0x060f, 0x0f, 0x00, 0x00, 0x00, 0x1d}, - {0x7d, 0x0eff, 0x060f, 0x0f, 0x00, 0x00, 0x00, 0x1d}, - {0x20, 0x0e3b, 0x0D16, 0x16, 0x00, 0x00, 0x00, 0x43}, - {0x21, 0x0e7d, 0x0D16, 0x16, 0x00, 0x00, 0x00, 0x43}, - {0x22, 0x0eff, 0x0D16, 0x16, 0x00, 0x00, 0x00, 0x43}, - {0x23, 0x0e3b, 0x0614, 0x14, 0x00, 0x00, 0x00, 0x41}, - {0x24, 0x0e7d, 0x0614, 0x14, 0x00, 0x00, 0x00, 0x41}, - {0x25, 0x0eff, 0x0614, 0x14, 0x00, 0x00, 0x00, 0x41}, - {0x26, 0x063b, 0x0c15, 0x15, 0x00, 0x00, 0x00, 0x42}, - {0x27, 0x067d, 0x0c15, 0x15, 0x00, 0x00, 0x00, 0x42}, - {0x28, 0x06ff, 0x0c15, 0x15, 0x00, 0x00, 0x00, 0x42}, - {0xff, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00} + {0x68, 0x067b, 0x080b, 0x0b, 0x00, 0x00, 0x29}, + {0x69, 0x06fd, 0x080b, 0x0b, 0x00, 0x00, 0x29}, + {0x6b, 0x07ff, 0x080b, 0x0b, 0x00, 0x00, 0x29}, + {0x6c, 0x067b, 0x090c, 0x0c, 0x00, 0x00, 0x2f}, + {0x6d, 0x06fd, 0x090c, 0x0c, 0x00, 0x00, 0x2f}, + {0x6e, 0x07ff, 0x090c, 0x0c, 0x00, 0x00, 0x2f}, + {0x70, 0x2a1b, 0x0410, 0x10, 0x00, 0x07, 0x34}, + {0x71, 0x0a1b, 0x0511, 0x11, 0x00, 0x00, 0x37}, + {0x74, 0x0a1d, 0x0511, 0x11, 0x00, 0x00, 0x37}, + {0x75, 0x0a3d, 0x0612, 0x12, 0x00, 0x00, 0x3a}, + {0x76, 0x2a1f, 0x0410, 0x10, 0x00, 0x07, 0x34}, + {0x77, 0x0a1f, 0x0511, 0x11, 0x00, 0x00, 0x37}, + {0x78, 0x0a3f, 0x0612, 0x12, 0x00, 0x00, 0x3a}, + {0x79, 0x0a3b, 0x0612, 0x12, 0x00, 0x00, 0x3a}, + {0x7a, 0x2a1d, 0x0410, 0x10, 0x00, 0x07, 0x34}, + {0x7b, 0x0e3b, 0x060f, 0x0f, 0x00, 0x00, 0x1d}, + {0x7c, 0x0e7d, 0x060f, 0x0f, 0x00, 0x00, 0x1d}, + {0x7d, 0x0eff, 0x060f, 0x0f, 0x00, 0x00, 0x1d}, + {0x20, 0x0e3b, 0x0D16, 0x16, 0x00, 0x00, 0x43}, + {0x21, 0x0e7d, 0x0D16, 0x16, 0x00, 0x00, 0x43}, + {0x22, 0x0eff, 0x0D16, 0x16, 0x00, 0x00, 0x43}, + {0x23, 0x0e3b, 0x0614, 0x14, 0x00, 0x00, 0x41}, + {0x24, 0x0e7d, 0x0614, 0x14, 0x00, 0x00, 0x41}, + {0x25, 0x0eff, 0x0614, 0x14, 0x00, 0x00, 0x41}, + {0x26, 0x063b, 0x0c15, 0x15, 0x00, 0x00, 0x42}, + {0x27, 0x067d, 0x0c15, 0x15, 0x00, 0x00, 0x42}, + {0x28, 0x06ff, 0x0c15, 0x15, 0x00, 0x00, 0x42}, + {0xff, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00} }; static struct SiS_StandTable_S XGI330_StandTable = { -- cgit v0.10.2 From 354f49fa120b6aab10f96389849bd8a5d6a943c4 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:14:09 +0300 Subject: staging: xgifb: delete VB_ExtTVEdgeIndex Delete VB_ExtTVEdgeIndex. It's 0 for all video modes. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index a93eec2..da4541c 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -5963,14 +5963,12 @@ static void XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { - unsigned short tempbx, index; + unsigned short tempbx; unsigned char tempah; tempbx = XGI_GetTVPtrIndex(pVBInfo); tempbx &= 0xFE; - index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex; - tempbx += index; tempah = TVEdgeList[tempbx]; tempah = tempah << 5; diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 65c7989..09daeeb 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -15,7 +15,6 @@ struct XGI_ExtStruct { unsigned short Ext_ModeFlag; unsigned short Ext_ModeInfo; unsigned char Ext_RESINFO; - unsigned char VB_ExtTVEdgeIndex; unsigned char VB_ExtTVYFilterIndex; unsigned char REFindex; }; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 2756aef..d241790 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -129,75 +129,75 @@ static unsigned char XG40_CRCF = 0x13; static unsigned char XG40_DRAMTypeDefinition = 0xFF ; static struct XGI_ExtStruct XGI330_EModeIDTable[] = { - {0x2e, 0x0a1b, 0x0306, 0x06, 0x00, 0x05, 0x06}, - {0x2f, 0x0a1b, 0x0305, 0x05, 0x00, 0x05, 0x05}, - {0x30, 0x2a1b, 0x0407, 0x07, 0x00, 0x07, 0x0e}, - {0x31, 0x0a1b, 0x030d, 0x0d, 0x00, 0x06, 0x3d}, - {0x32, 0x0a1b, 0x0a0e, 0x0e, 0x00, 0x06, 0x3e}, - {0x33, 0x0a1d, 0x0a0d, 0x0d, 0x00, 0x06, 0x3d}, - {0x34, 0x2a1d, 0x0a0e, 0x0e, 0x00, 0x06, 0x3e}, - {0x35, 0x0a1f, 0x0a0d, 0x0d, 0x00, 0x06, 0x3d}, - {0x36, 0x2a1f, 0x0a0e, 0x0e, 0x00, 0x06, 0x3e}, - {0x38, 0x0a1b, 0x0508, 0x08, 0x00, 0x00, 0x16}, - {0x3a, 0x0e3b, 0x0609, 0x09, 0x00, 0x00, 0x1e}, - {0x3c, 0x0e3b, 0x070a, 0x0a, 0x00, 0x00, 0x22}, /* mode 1600x1200 + {0x2e, 0x0a1b, 0x0306, 0x06, 0x05, 0x06}, + {0x2f, 0x0a1b, 0x0305, 0x05, 0x05, 0x05}, + {0x30, 0x2a1b, 0x0407, 0x07, 0x07, 0x0e}, + {0x31, 0x0a1b, 0x030d, 0x0d, 0x06, 0x3d}, + {0x32, 0x0a1b, 0x0a0e, 0x0e, 0x06, 0x3e}, + {0x33, 0x0a1d, 0x0a0d, 0x0d, 0x06, 0x3d}, + {0x34, 0x2a1d, 0x0a0e, 0x0e, 0x06, 0x3e}, + {0x35, 0x0a1f, 0x0a0d, 0x0d, 0x06, 0x3d}, + {0x36, 0x2a1f, 0x0a0e, 0x0e, 0x06, 0x3e}, + {0x38, 0x0a1b, 0x0508, 0x08, 0x00, 0x16}, + {0x3a, 0x0e3b, 0x0609, 0x09, 0x00, 0x1e}, + {0x3c, 0x0e3b, 0x070a, 0x0a, 0x00, 0x22}, /* mode 1600x1200 add CRT2MODE [2003/10/07] */ - {0x3d, 0x0e7d, 0x070a, 0x0a, 0x00, 0x00, 0x22}, /* mode 1600x1200 + {0x3d, 0x0e7d, 0x070a, 0x0a, 0x00, 0x22}, /* mode 1600x1200 add CRT2MODE */ - {0x40, 0x9a1c, 0x0000, 0x00, 0x00, 0x04, 0x00}, - {0x41, 0x9a1d, 0x0000, 0x00, 0x00, 0x04, 0x00}, - {0x43, 0x0a1c, 0x0306, 0x06, 0x00, 0x05, 0x06}, - {0x44, 0x0a1d, 0x0306, 0x06, 0x00, 0x05, 0x06}, - {0x46, 0x2a1c, 0x0407, 0x07, 0x00, 0x07, 0x0e}, - {0x47, 0x2a1d, 0x0407, 0x07, 0x00, 0x07, 0x0e}, - {0x49, 0x0a3c, 0x0508, 0x08, 0x00, 0x00, 0x16}, - {0x4a, 0x0a3d, 0x0508, 0x08, 0x00, 0x00, 0x16}, - {0x4c, 0x0e7c, 0x0609, 0x09, 0x00, 0x00, 0x1e}, - {0x4d, 0x0e7d, 0x0609, 0x09, 0x00, 0x00, 0x1e}, - {0x50, 0x9a1b, 0x0001, 0x01, 0x00, 0x04, 0x02}, - {0x51, 0xba1b, 0x0103, 0x03, 0x00, 0x07, 0x03}, - {0x52, 0x9a1b, 0x0204, 0x04, 0x00, 0x00, 0x04}, - {0x56, 0x9a1d, 0x0001, 0x01, 0x00, 0x04, 0x02}, - {0x57, 0xba1d, 0x0103, 0x03, 0x00, 0x07, 0x03}, - {0x58, 0x9a1d, 0x0204, 0x04, 0x00, 0x00, 0x04}, - {0x59, 0x9a1b, 0x0000, 0x00, 0x00, 0x04, 0x00}, - {0x5A, 0x021b, 0x0014, 0x01, 0x00, 0x04, 0x3f}, - {0x5B, 0x0a1d, 0x0014, 0x01, 0x00, 0x04, 0x3f}, - {0x5d, 0x0a1d, 0x0305, 0x05, 0x00, 0x07, 0x05}, - {0x62, 0x0a3f, 0x0306, 0x06, 0x00, 0x05, 0x06}, - {0x63, 0x2a3f, 0x0407, 0x07, 0x00, 0x07, 0x0e}, - {0x64, 0x0a7f, 0x0508, 0x08, 0x00, 0x00, 0x16}, - {0x65, 0x0eff, 0x0609, 0x09, 0x00, 0x00, 0x1e}, - {0x66, 0x0eff, 0x070a, 0x0a, 0x00, 0x00, 0x22}, /* mode 1600x1200 + {0x40, 0x9a1c, 0x0000, 0x00, 0x04, 0x00}, + {0x41, 0x9a1d, 0x0000, 0x00, 0x04, 0x00}, + {0x43, 0x0a1c, 0x0306, 0x06, 0x05, 0x06}, + {0x44, 0x0a1d, 0x0306, 0x06, 0x05, 0x06}, + {0x46, 0x2a1c, 0x0407, 0x07, 0x07, 0x0e}, + {0x47, 0x2a1d, 0x0407, 0x07, 0x07, 0x0e}, + {0x49, 0x0a3c, 0x0508, 0x08, 0x00, 0x16}, + {0x4a, 0x0a3d, 0x0508, 0x08, 0x00, 0x16}, + {0x4c, 0x0e7c, 0x0609, 0x09, 0x00, 0x1e}, + {0x4d, 0x0e7d, 0x0609, 0x09, 0x00, 0x1e}, + {0x50, 0x9a1b, 0x0001, 0x01, 0x04, 0x02}, + {0x51, 0xba1b, 0x0103, 0x03, 0x07, 0x03}, + {0x52, 0x9a1b, 0x0204, 0x04, 0x00, 0x04}, + {0x56, 0x9a1d, 0x0001, 0x01, 0x04, 0x02}, + {0x57, 0xba1d, 0x0103, 0x03, 0x07, 0x03}, + {0x58, 0x9a1d, 0x0204, 0x04, 0x00, 0x04}, + {0x59, 0x9a1b, 0x0000, 0x00, 0x04, 0x00}, + {0x5A, 0x021b, 0x0014, 0x01, 0x04, 0x3f}, + {0x5B, 0x0a1d, 0x0014, 0x01, 0x04, 0x3f}, + {0x5d, 0x0a1d, 0x0305, 0x05, 0x07, 0x05}, + {0x62, 0x0a3f, 0x0306, 0x06, 0x05, 0x06}, + {0x63, 0x2a3f, 0x0407, 0x07, 0x07, 0x0e}, + {0x64, 0x0a7f, 0x0508, 0x08, 0x00, 0x16}, + {0x65, 0x0eff, 0x0609, 0x09, 0x00, 0x1e}, + {0x66, 0x0eff, 0x070a, 0x0a, 0x00, 0x22}, /* mode 1600x1200 add CRT2MODE */ - {0x68, 0x067b, 0x080b, 0x0b, 0x00, 0x00, 0x29}, - {0x69, 0x06fd, 0x080b, 0x0b, 0x00, 0x00, 0x29}, - {0x6b, 0x07ff, 0x080b, 0x0b, 0x00, 0x00, 0x29}, - {0x6c, 0x067b, 0x090c, 0x0c, 0x00, 0x00, 0x2f}, - {0x6d, 0x06fd, 0x090c, 0x0c, 0x00, 0x00, 0x2f}, - {0x6e, 0x07ff, 0x090c, 0x0c, 0x00, 0x00, 0x2f}, - {0x70, 0x2a1b, 0x0410, 0x10, 0x00, 0x07, 0x34}, - {0x71, 0x0a1b, 0x0511, 0x11, 0x00, 0x00, 0x37}, - {0x74, 0x0a1d, 0x0511, 0x11, 0x00, 0x00, 0x37}, - {0x75, 0x0a3d, 0x0612, 0x12, 0x00, 0x00, 0x3a}, - {0x76, 0x2a1f, 0x0410, 0x10, 0x00, 0x07, 0x34}, - {0x77, 0x0a1f, 0x0511, 0x11, 0x00, 0x00, 0x37}, - {0x78, 0x0a3f, 0x0612, 0x12, 0x00, 0x00, 0x3a}, - {0x79, 0x0a3b, 0x0612, 0x12, 0x00, 0x00, 0x3a}, - {0x7a, 0x2a1d, 0x0410, 0x10, 0x00, 0x07, 0x34}, - {0x7b, 0x0e3b, 0x060f, 0x0f, 0x00, 0x00, 0x1d}, - {0x7c, 0x0e7d, 0x060f, 0x0f, 0x00, 0x00, 0x1d}, - {0x7d, 0x0eff, 0x060f, 0x0f, 0x00, 0x00, 0x1d}, - {0x20, 0x0e3b, 0x0D16, 0x16, 0x00, 0x00, 0x43}, - {0x21, 0x0e7d, 0x0D16, 0x16, 0x00, 0x00, 0x43}, - {0x22, 0x0eff, 0x0D16, 0x16, 0x00, 0x00, 0x43}, - {0x23, 0x0e3b, 0x0614, 0x14, 0x00, 0x00, 0x41}, - {0x24, 0x0e7d, 0x0614, 0x14, 0x00, 0x00, 0x41}, - {0x25, 0x0eff, 0x0614, 0x14, 0x00, 0x00, 0x41}, - {0x26, 0x063b, 0x0c15, 0x15, 0x00, 0x00, 0x42}, - {0x27, 0x067d, 0x0c15, 0x15, 0x00, 0x00, 0x42}, - {0x28, 0x06ff, 0x0c15, 0x15, 0x00, 0x00, 0x42}, - {0xff, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00} + {0x68, 0x067b, 0x080b, 0x0b, 0x00, 0x29}, + {0x69, 0x06fd, 0x080b, 0x0b, 0x00, 0x29}, + {0x6b, 0x07ff, 0x080b, 0x0b, 0x00, 0x29}, + {0x6c, 0x067b, 0x090c, 0x0c, 0x00, 0x2f}, + {0x6d, 0x06fd, 0x090c, 0x0c, 0x00, 0x2f}, + {0x6e, 0x07ff, 0x090c, 0x0c, 0x00, 0x2f}, + {0x70, 0x2a1b, 0x0410, 0x10, 0x07, 0x34}, + {0x71, 0x0a1b, 0x0511, 0x11, 0x00, 0x37}, + {0x74, 0x0a1d, 0x0511, 0x11, 0x00, 0x37}, + {0x75, 0x0a3d, 0x0612, 0x12, 0x00, 0x3a}, + {0x76, 0x2a1f, 0x0410, 0x10, 0x07, 0x34}, + {0x77, 0x0a1f, 0x0511, 0x11, 0x00, 0x37}, + {0x78, 0x0a3f, 0x0612, 0x12, 0x00, 0x3a}, + {0x79, 0x0a3b, 0x0612, 0x12, 0x00, 0x3a}, + {0x7a, 0x2a1d, 0x0410, 0x10, 0x07, 0x34}, + {0x7b, 0x0e3b, 0x060f, 0x0f, 0x00, 0x1d}, + {0x7c, 0x0e7d, 0x060f, 0x0f, 0x00, 0x1d}, + {0x7d, 0x0eff, 0x060f, 0x0f, 0x00, 0x1d}, + {0x20, 0x0e3b, 0x0D16, 0x16, 0x00, 0x43}, + {0x21, 0x0e7d, 0x0D16, 0x16, 0x00, 0x43}, + {0x22, 0x0eff, 0x0D16, 0x16, 0x00, 0x43}, + {0x23, 0x0e3b, 0x0614, 0x14, 0x00, 0x41}, + {0x24, 0x0e7d, 0x0614, 0x14, 0x00, 0x41}, + {0x25, 0x0eff, 0x0614, 0x14, 0x00, 0x41}, + {0x26, 0x063b, 0x0c15, 0x15, 0x00, 0x42}, + {0x27, 0x067d, 0x0c15, 0x15, 0x00, 0x42}, + {0x28, 0x06ff, 0x0c15, 0x15, 0x00, 0x42}, + {0xff, 0x0000, 0x0000, 0x00, 0x00, 0x00} }; static struct SiS_StandTable_S XGI330_StandTable = { -- cgit v0.10.2 From d00d12f87a558e55b5a48cf7925ac48bf26a613d Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:14:10 +0300 Subject: staging: xgifb: eliminate redundant struct definition Replace XGI330_LCDDataDesStruct with identical XGI_LCDDesStruct. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index da4541c..8f0be88 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -2178,7 +2178,7 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, { unsigned short tempbx, tempax, tempcx, tempdx, push1, push2, modeflag; unsigned long temp, temp1, temp2, temp3, push3; - struct XGI330_LCDDataDesStruct *LCDPtr = NULL; + struct XGI_LCDDesStruct *LCDPtr = NULL; struct XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL; modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; @@ -2194,7 +2194,7 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, pVBInfo); else LCDPtr = - (struct XGI330_LCDDataDesStruct *) + (struct XGI_LCDDesStruct *) XGI_GetLcdPtr( tempbx, ModeNo, diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 09daeeb..38f47ff 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -51,14 +51,6 @@ struct XGI_LCDDataTablStruct { unsigned short DATAPTR; }; -struct XGI330_LCDDataDesStruct { - unsigned short LCDHDES; - unsigned short LCDHRS; - unsigned short LCDVDES; - unsigned short LCDVRS; -}; - - struct XGI330_LVDSDataStruct { unsigned short VGAHT; unsigned short VGAVT; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index d241790..d7ca4d1 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -619,7 +619,7 @@ static struct XGI330_LCDDataStruct XGI_NoScalingDatax75[] = { {1, 1, 1688, 806, 1688, 806} /* ; 0A (1280x768x75Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1024x768Data[] = { +static struct XGI_LCDDesStruct XGI_ExtLCDDes1024x768Data[] = { {9, 1057, 0, 771}, /* ; 00 (320x200,320x400,640x200,640x400) */ {9, 1057, 0, 771}, /* ; 01 (320x350,640x350) */ {9, 1057, 0, 771}, /* ; 02 (360x400,720x400) */ @@ -629,7 +629,7 @@ static struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1024x768Data[] = { {9, 1057, 805, 770} /* ; 06 (1024x768x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_StLCDDes1024x768Data[] = { +static struct XGI_LCDDesStruct XGI_StLCDDes1024x768Data[] = { {9, 1057, 737, 703}, /* ; 00 (320x200,320x400,640x200,640x400) */ {9, 1057, 686, 651}, /* ; 01 (320x350,640x350) */ {9, 1057, 737, 703}, /* ; 02 (360x400,720x400) */ @@ -639,7 +639,7 @@ static struct XGI330_LCDDataDesStruct XGI_StLCDDes1024x768Data[] = { {9, 1057, 805, 770} /* ; 06 (1024x768x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1024x768Data[] = { +static struct XGI_LCDDesStruct XGI_CetLCDDes1024x768Data[] = { {1152, 856, 622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */ {1152, 856, 597, 562}, /* ; 01 (320x350,640x350) */ {1152, 856, 622, 587}, /* ; 02 (360x400,720x400) */ @@ -649,7 +649,7 @@ static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1024x768Data[] = { {0, 1048, 805, 770} /* ; 06 (1024x768x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1280x1024Data[] = { +static struct XGI_LCDDesStruct XGI_ExtLCDDLDes1280x1024Data[] = { {18, 1346, 981, 940}, /* 00 (320x200,320x400,640x200,640x400) */ {18, 1346, 926, 865}, /* 01 (320x350,640x350) */ {18, 1346, 981, 940}, /* 02 (360x400,720x400) */ @@ -660,7 +660,7 @@ static struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1280x1024Data[] = { {18, 1346, 1065, 1024} /* 07 (1280x1024x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1280x1024Data[] = { +static struct XGI_LCDDesStruct XGI_StLCDDLDes1280x1024Data[] = { {18, 1346, 970, 907}, /* 00 (320x200,320x400,640x200,640x400) */ {18, 1346, 917, 854}, /* 01 (320x350,640x350) */ {18, 1346, 970, 907}, /* 02 (360x400,720x400) */ @@ -671,7 +671,7 @@ static struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1280x1024Data[] = { {18, 1346, 1065, 1024} /* 07 (1280x1024x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_CetLCDDLDes1280x1024Data[] = { +static struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024Data[] = { {1368, 1008, 752, 711}, /* 00 (320x200,320x400,640x200,640x400) */ {1368, 1008, 729, 688}, /* 01 (320x350,640x350) */ {1368, 1008, 752, 711}, /* 02 (360x400,720x400) */ @@ -682,7 +682,7 @@ static struct XGI330_LCDDataDesStruct XGI_CetLCDDLDes1280x1024Data[] = { {18, 1346, 1065, 1024} /* 07 (1280x1024x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1280x1024Data[] = { +static struct XGI_LCDDesStruct XGI_ExtLCDDes1280x1024Data[] = { {9, 1337, 981, 940}, /* ; 00 (320x200,320x400,640x200,640x400) */ {9, 1337, 926, 884}, /* ; 01 (320x350,640x350) alan, 2003/09/30 */ {9, 1337, 981, 940}, /* ; 02 (360x400,720x400) */ @@ -693,7 +693,7 @@ static struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1280x1024Data[] = { {9, 1337, 1065, 1024} /* ; 07 (1280x1024x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_StLCDDes1280x1024Data[] = { +static struct XGI_LCDDesStruct XGI_StLCDDes1280x1024Data[] = { {9, 1337, 970, 907}, /* ; 00 (320x200,320x400,640x200,640x400) */ {9, 1337, 917, 854}, /* ; 01 (320x350,640x350) */ {9, 1337, 970, 907}, /* ; 02 (360x400,720x400) */ @@ -704,7 +704,7 @@ static struct XGI330_LCDDataDesStruct XGI_StLCDDes1280x1024Data[] = { {9, 1337, 1065, 1024} /* ; 07 (1280x1024x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1280x1024Data[] = { +static struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024Data[] = { {1368, 1008, 752, 711}, /* 00 (320x200,320x400,640x200,640x400) */ {1368, 1008, 729, 688}, /* 01 (320x350,640x350) */ {1368, 1008, 752, 711}, /* 02 (360x400,720x400) */ @@ -715,7 +715,7 @@ static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1280x1024Data[] = { {9, 1337, 1065, 1024} /* 07 (1280x1024x60Hz) */ }; -static struct XGI330_LCDDataDesStruct xgifb_lcddldes_1400x1050[] = { +static struct XGI_LCDDesStruct xgifb_lcddldes_1400x1050[] = { {18, 1464, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */ {18, 1464, 0, 1051}, /* 01 (320x350,640x350) */ {18, 1464, 0, 1051}, /* 02 (360x400,720x400) */ @@ -727,7 +727,7 @@ static struct XGI330_LCDDataDesStruct xgifb_lcddldes_1400x1050[] = { {18, 1464, 0, 1051} /* 08 (1400x1050x60Hz) */ }; -static struct XGI330_LCDDataDesStruct xgifb_lcddes_1400x1050[] = { +static struct XGI_LCDDesStruct xgifb_lcddes_1400x1050[] = { {9, 1455, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */ {9, 1455, 0, 1051}, /* 01 (320x350,640x350) */ {9, 1455, 0, 1051}, /* 02 (360x400,720x400) */ @@ -739,7 +739,7 @@ static struct XGI330_LCDDataDesStruct xgifb_lcddes_1400x1050[] = { {9, 1455, 0, 1051} /* 08 (1400x1050x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1400x1050Data[] = { +static struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data[] = { {1308, 1068, 781, 766}, /* 00 (320x200,320x400,640x200,640x400) */ {1308, 1068, 781, 766}, /* 01 (320x350,640x350) */ {1308, 1068, 781, 766}, /* 02 (360x400,720x400) */ @@ -751,7 +751,7 @@ static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1400x1050Data[] = { {18, 1464, 0, 1051} /* 08 (1400x1050x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1400x1050Data2[] = { +static struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data2[] = { {0, 1448, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */ {0, 1448, 0, 1051}, /* 01 (320x350,640x350) */ {0, 1448, 0, 1051}, /* 02 (360x400,720x400) */ @@ -759,7 +759,7 @@ static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1400x1050Data2[] = { {0, 1448, 0, 1051} /* 04 (640x480x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1600x1200Data[] = { +static struct XGI_LCDDesStruct XGI_ExtLCDDLDes1600x1200Data[] = { {18, 1682, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */ {18, 1682, 0, 1201}, /* 01 (320x350,640x350) */ {18, 1682, 0, 1201}, /* 02 (360x400,720x400) */ @@ -772,7 +772,7 @@ static struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1600x1200Data[] = { {18, 1682, 0, 1201} /* 09 (1600x1200x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1600x1200Data[] = { +static struct XGI_LCDDesStruct XGI_StLCDDLDes1600x1200Data[] = { {18, 1682, 1150, 1101}, /* 00 (320x200,320x400,640x200,640x400) */ {18, 1682, 1083, 1034}, /* 01 (320x350,640x350) */ {18, 1682, 1150, 1101}, /* 02 (360x400,720x400) */ @@ -785,7 +785,7 @@ static struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1600x1200Data[] = { {18, 1682, 0, 1201} /* 09 (1600x1200x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1600x1200Data[] = { +static struct XGI_LCDDesStruct XGI_ExtLCDDes1600x1200Data[] = { {9, 1673, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */ {9, 1673, 0, 1201}, /* 01 (320x350,640x350) */ {9, 1673, 0, 1201}, /* 02 (360x400,720x400) */ @@ -798,7 +798,7 @@ static struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1600x1200Data[] = { {9, 1673, 0, 1201} /* 09 (1600x1200x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_StLCDDes1600x1200Data[] = { +static struct XGI_LCDDesStruct XGI_StLCDDes1600x1200Data[] = { {9, 1673, 1150, 1101}, /* 00 (320x200,320x400,640x200,640x400) */ {9, 1673, 1083, 1034}, /* 01 (320x350,640x350) */ {9, 1673, 1150, 1101}, /* 02 (360x400,720x400) */ @@ -828,7 +828,7 @@ static struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesData[] = { }; /* ;;1024x768x75Hz */ -static struct XGI330_LCDDataDesStruct xgifb_lcddes_1024x768x75[] = { +static struct XGI_LCDDesStruct xgifb_lcddes_1024x768x75[] = { {9, 1049, 0, 769}, /* ; 00 (320x200,320x400,640x200,640x400) */ {9, 1049, 0, 769}, /* ; 01 (320x350,640x350) */ {9, 1049, 0, 769}, /* ; 02 (360x400,720x400) */ @@ -839,7 +839,7 @@ static struct XGI330_LCDDataDesStruct xgifb_lcddes_1024x768x75[] = { }; /* ;;1024x768x75Hz */ -static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1024x768x75Data[] = { +static struct XGI_LCDDesStruct XGI_CetLCDDes1024x768x75Data[] = { {1152, 856, 622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */ {1152, 856, 597, 562}, /* ; 01 (320x350,640x350) */ {1192, 896, 622, 587}, /* ; 02 (360x400,720x400) */ @@ -850,7 +850,7 @@ static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1024x768x75Data[] = { }; /* ;;1280x1024x75Hz */ -static struct XGI330_LCDDataDesStruct xgifb_lcddldes_1280x1024x75[] = { +static struct XGI_LCDDesStruct xgifb_lcddldes_1280x1024x75[] = { {18, 1314, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */ {18, 1314, 0, 1025}, /* ; 01 (320x350,640x350) */ {18, 1314, 0, 1025}, /* ; 02 (360x400,720x400) */ @@ -862,7 +862,7 @@ static struct XGI330_LCDDataDesStruct xgifb_lcddldes_1280x1024x75[] = { }; /* 1280x1024x75Hz */ -static struct XGI330_LCDDataDesStruct XGI_CetLCDDLDes1280x1024x75Data[] = { +static struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024x75Data[] = { {1368, 1008, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */ {1368, 1008, 729, 688}, /* ; 01 (320x350,640x350) */ {1408, 1048, 752, 711}, /* ; 02 (360x400,720x400) */ @@ -874,7 +874,7 @@ static struct XGI330_LCDDataDesStruct XGI_CetLCDDLDes1280x1024x75Data[] = { }; /* ;;1280x1024x75Hz */ -static struct XGI330_LCDDataDesStruct xgifb_lcddes_1280x1024x75[] = { +static struct XGI_LCDDesStruct xgifb_lcddes_1280x1024x75[] = { {9, 1305, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */ {9, 1305, 0, 1025}, /* ; 01 (320x350,640x350) */ {9, 1305, 0, 1025}, /* ; 02 (360x400,720x400) */ @@ -886,7 +886,7 @@ static struct XGI330_LCDDataDesStruct xgifb_lcddes_1280x1024x75[] = { }; /* 1280x1024x75Hz */ -static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1280x1024x75Data[] = { +static struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024x75Data[] = { {1368, 1008, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */ {1368, 1008, 729, 688}, /* ; 01 (320x350,640x350) */ {1408, 1048, 752, 711}, /* ; 02 (360x400,720x400) */ -- cgit v0.10.2 From 6c0965fd7b3f46f3b99e831d14e096b332c1ffbb Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 7 Apr 2012 01:14:11 +0300 Subject: staging: xgifb: inline XGI_GetResInfo() Inline a trivial function. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 8f0be88..abaf03a 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -857,13 +857,6 @@ static void XGI_UpdateXG21CRTC(unsigned short ModeNo, } } -static unsigned short XGI_GetResInfo(unsigned short ModeNo, - unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) -{ - /* si+Ext_ResInfo */ - return pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; -} - static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, @@ -873,7 +866,7 @@ static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, unsigned char data; - resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); + resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; tempax = pVBInfo->ModeResInfo[resindex].HTotal; @@ -1271,7 +1264,7 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, data2 |= 0x20; xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x3F, data2); - resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); + resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ data = 0x0000; @@ -3365,7 +3358,7 @@ static void XGI_GetCRT2ResInfo(unsigned short ModeNo, { unsigned short xres, yres, modeflag, resindex; - resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); + resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ /* si+St_ModeFlag */ @@ -5259,7 +5252,7 @@ static unsigned char XGI_XG21CheckLVDSMode(struct xgifb_video_info *xgifb_info, { unsigned short xres, yres, colordepth, modeflag, resindex; - resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); + resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ /* si+St_ModeFlag */ @@ -5321,7 +5314,7 @@ static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info, else XGI_SetXG21FPBits(pVBInfo); - resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); + resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ /* si+St_ModeFlag */ -- cgit v0.10.2 From fc44de0097b6eb05e1feb63d045bdafb8120784d Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Fri, 23 Mar 2012 00:21:06 +0100 Subject: staging/telephony/ixj.c: delete trailing whitespace There's a lot of trailing whitespace in drivers/telephony/ixj.c . This patch removes it. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/telephony/ixj.c b/drivers/staging/telephony/ixj.c index f960279..fd7757a 100644 --- a/drivers/staging/telephony/ixj.c +++ b/drivers/staging/telephony/ixj.c @@ -19,20 +19,20 @@ * David W. Erhart, * John Sellers, * Mike Preston, - * + * * Fixes: David Huggins-Daines, * Fabio Ferrari, * Artis Kugevics, * Daniele Bellucci, * - * More information about the hardware related to this driver can be found + * More information about the hardware related to this driver can be found * at our website: http://www.quicknet.net * * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET * TECHNOLOGIES, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS @@ -317,7 +317,7 @@ static IXJ *ixj[IXJMAX]; /* * Allocate a free IXJ device */ - + static IXJ *ixj_alloc() { for(cnt=0; cntboard, j->cadence_f[4].on3, j->cadence_f[4].on3min, j->cadence_f[4].on3dot, j->cadence_f[4].on3max); break; - case 6: + case 6: printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board, j->cadence_f[4].off3, j->cadence_f[4].off3min, j->cadence_f[4].off3dot, j->cadence_f[4].off3max); break; @@ -1109,7 +1109,7 @@ static void ixj_pstn_state(IXJ *j) } j->pstn_ring_stop = j->pstn_ring_int = 0; daa_set_mode(j, SOP_PU_SLEEP); - } + } outb_p(j->pld_scrw.byte, j->XILINXbase); if (j->pstn_cid_intr && time_after(jiffies, j->pstn_cid_received + hertz)) { ixj_daa_cid_read(j); @@ -1133,7 +1133,7 @@ static void ixj_pstn_state(IXJ *j) printk("IXJ DAA possible wink /dev/phone%d %ld\n", j->board, jiffies); } j->pstn_winkstart = jiffies; - } + } } else { if (j->pstn_winkstart) { if(ixjdebug & 0x0008) { @@ -1524,7 +1524,7 @@ static inline void LED_SetState(int state, IXJ *j) /********************************************************************* * GPIO Pins are configured as follows on the Quicknet Internet * PhoneJACK Telephony Cards -* +* * POTS Select GPIO_6=0 GPIO_7=0 * Mic/Speaker Select GPIO_6=0 GPIO_7=1 * Handset Select GPIO_6=1 GPIO_7=0 @@ -1932,7 +1932,7 @@ static int ixj_hookstate(IXJ *j) if(fOffHook != j->p_hook) { if(!j->checkwait) { j->checkwait = jiffies; - } + } if(time_before(jiffies, j->checkwait + 2)) { fOffHook ^= 1; } else { @@ -2342,8 +2342,8 @@ static int ixj_release(struct inode *inode, struct file *file_p) j->ixj_signals[cnt] = SIGIO; /* Set the excetion signal enable flags */ - j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring = - j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 = + j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring = + j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 = j->ex_sig.bits.f3 = j->ex_sig.bits.fc0 = j->ex_sig.bits.fc1 = j->ex_sig.bits.fc2 = j->ex_sig.bits.fc3 = 1; file_p->private_data = NULL; @@ -2506,7 +2506,7 @@ static int read_filters(IXJ *j) j->cadence_f[cnt].on1, j->cadence_f[cnt].on1min, j->cadence_f[cnt].on1dot, j->cadence_f[cnt].on1max); break; case 2: - printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off1min, + printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off1min, j->cadence_f[cnt].off1max); break; case 3: @@ -2521,12 +2521,12 @@ static int read_filters(IXJ *j) printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].on3min, j->cadence_f[cnt].on3max); break; - case 6: + case 6: printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off3min, j->cadence_f[cnt].off3max); break; } - } + } } if (j->cadence_f[cnt].state == 7) { j->cadence_f[cnt].state = 0; @@ -2656,37 +2656,37 @@ static void ulaw2alaw(unsigned char *buff, unsigned long len) { static unsigned char table_ulaw2alaw[] = { - 0x2A, 0x2B, 0x28, 0x29, 0x2E, 0x2F, 0x2C, 0x2D, - 0x22, 0x23, 0x20, 0x21, 0x26, 0x27, 0x24, 0x25, - 0x3A, 0x3B, 0x38, 0x39, 0x3E, 0x3F, 0x3C, 0x3D, - 0x32, 0x33, 0x30, 0x31, 0x36, 0x37, 0x34, 0x35, - 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, 0x02, - 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, 0x1A, - 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, 0x12, - 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, 0x6B, - 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, 0x62, 0x63, - 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, 0x7B, 0x79, - 0x7E, 0x7F, 0x7C, 0x7D, 0x72, 0x73, 0x70, 0x71, - 0x76, 0x77, 0x74, 0x75, 0x4B, 0x49, 0x4F, 0x4D, - 0x42, 0x43, 0x40, 0x41, 0x46, 0x47, 0x44, 0x45, - 0x5A, 0x5B, 0x58, 0x59, 0x5E, 0x5F, 0x5C, 0x5D, - 0x52, 0x52, 0x53, 0x53, 0x50, 0x50, 0x51, 0x51, - 0x56, 0x56, 0x57, 0x57, 0x54, 0x54, 0x55, 0xD5, - 0xAA, 0xAB, 0xA8, 0xA9, 0xAE, 0xAF, 0xAC, 0xAD, - 0xA2, 0xA3, 0xA0, 0xA1, 0xA6, 0xA7, 0xA4, 0xA5, - 0xBA, 0xBB, 0xB8, 0xB9, 0xBE, 0xBF, 0xBC, 0xBD, - 0xB2, 0xB3, 0xB0, 0xB1, 0xB6, 0xB7, 0xB4, 0xB5, - 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, 0x82, - 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, 0x9A, - 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, 0x92, - 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, 0xEB, - 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, 0xE2, 0xE3, - 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, 0xFB, 0xF9, - 0xFE, 0xFF, 0xFC, 0xFD, 0xF2, 0xF3, 0xF0, 0xF1, - 0xF6, 0xF7, 0xF4, 0xF5, 0xCB, 0xC9, 0xCF, 0xCD, - 0xC2, 0xC3, 0xC0, 0xC1, 0xC6, 0xC7, 0xC4, 0xC5, - 0xDA, 0xDB, 0xD8, 0xD9, 0xDE, 0xDF, 0xDC, 0xDD, - 0xD2, 0xD2, 0xD3, 0xD3, 0xD0, 0xD0, 0xD1, 0xD1, + 0x2A, 0x2B, 0x28, 0x29, 0x2E, 0x2F, 0x2C, 0x2D, + 0x22, 0x23, 0x20, 0x21, 0x26, 0x27, 0x24, 0x25, + 0x3A, 0x3B, 0x38, 0x39, 0x3E, 0x3F, 0x3C, 0x3D, + 0x32, 0x33, 0x30, 0x31, 0x36, 0x37, 0x34, 0x35, + 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, 0x02, + 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, 0x1A, + 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, 0x12, + 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, 0x6B, + 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, 0x62, 0x63, + 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, 0x7B, 0x79, + 0x7E, 0x7F, 0x7C, 0x7D, 0x72, 0x73, 0x70, 0x71, + 0x76, 0x77, 0x74, 0x75, 0x4B, 0x49, 0x4F, 0x4D, + 0x42, 0x43, 0x40, 0x41, 0x46, 0x47, 0x44, 0x45, + 0x5A, 0x5B, 0x58, 0x59, 0x5E, 0x5F, 0x5C, 0x5D, + 0x52, 0x52, 0x53, 0x53, 0x50, 0x50, 0x51, 0x51, + 0x56, 0x56, 0x57, 0x57, 0x54, 0x54, 0x55, 0xD5, + 0xAA, 0xAB, 0xA8, 0xA9, 0xAE, 0xAF, 0xAC, 0xAD, + 0xA2, 0xA3, 0xA0, 0xA1, 0xA6, 0xA7, 0xA4, 0xA5, + 0xBA, 0xBB, 0xB8, 0xB9, 0xBE, 0xBF, 0xBC, 0xBD, + 0xB2, 0xB3, 0xB0, 0xB1, 0xB6, 0xB7, 0xB4, 0xB5, + 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, 0x82, + 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, 0x9A, + 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, 0x92, + 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, 0xEB, + 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, 0xE2, 0xE3, + 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, 0xFB, 0xF9, + 0xFE, 0xFF, 0xFC, 0xFD, 0xF2, 0xF3, 0xF0, 0xF1, + 0xF6, 0xF7, 0xF4, 0xF5, 0xCB, 0xC9, 0xCF, 0xCD, + 0xC2, 0xC3, 0xC0, 0xC1, 0xC6, 0xC7, 0xC4, 0xC5, + 0xDA, 0xDB, 0xD8, 0xD9, 0xDE, 0xDF, 0xDC, 0xDD, + 0xD2, 0xD2, 0xD3, 0xD3, 0xD0, 0xD0, 0xD1, 0xD1, 0xD6, 0xD6, 0xD7, 0xD7, 0xD4, 0xD4, 0xD5, 0xD5 }; @@ -2701,37 +2701,37 @@ static void alaw2ulaw(unsigned char *buff, unsigned long len) { static unsigned char table_alaw2ulaw[] = { - 0x29, 0x2A, 0x27, 0x28, 0x2D, 0x2E, 0x2B, 0x2C, - 0x21, 0x22, 0x1F, 0x20, 0x25, 0x26, 0x23, 0x24, - 0x39, 0x3A, 0x37, 0x38, 0x3D, 0x3E, 0x3B, 0x3C, - 0x31, 0x32, 0x2F, 0x30, 0x35, 0x36, 0x33, 0x34, - 0x0A, 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, - 0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, - 0x1A, 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, - 0x12, 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, - 0x62, 0x63, 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, - 0x5D, 0x5D, 0x5C, 0x5C, 0x5F, 0x5F, 0x5E, 0x5E, - 0x74, 0x76, 0x70, 0x72, 0x7C, 0x7E, 0x78, 0x7A, - 0x6A, 0x6B, 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, - 0x48, 0x49, 0x46, 0x47, 0x4C, 0x4D, 0x4A, 0x4B, - 0x40, 0x41, 0x3F, 0x3F, 0x44, 0x45, 0x42, 0x43, - 0x56, 0x57, 0x54, 0x55, 0x5A, 0x5B, 0x58, 0x59, - 0x4F, 0x4F, 0x4E, 0x4E, 0x52, 0x53, 0x50, 0x51, - 0xA9, 0xAA, 0xA7, 0xA8, 0xAD, 0xAE, 0xAB, 0xAC, - 0xA1, 0xA2, 0x9F, 0xA0, 0xA5, 0xA6, 0xA3, 0xA4, - 0xB9, 0xBA, 0xB7, 0xB8, 0xBD, 0xBE, 0xBB, 0xBC, - 0xB1, 0xB2, 0xAF, 0xB0, 0xB5, 0xB6, 0xB3, 0xB4, - 0x8A, 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, - 0x82, 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, - 0x9A, 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, - 0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, - 0xE2, 0xE3, 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, - 0xDD, 0xDD, 0xDC, 0xDC, 0xDF, 0xDF, 0xDE, 0xDE, - 0xF4, 0xF6, 0xF0, 0xF2, 0xFC, 0xFE, 0xF8, 0xFA, - 0xEA, 0xEB, 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, - 0xC8, 0xC9, 0xC6, 0xC7, 0xCC, 0xCD, 0xCA, 0xCB, - 0xC0, 0xC1, 0xBF, 0xBF, 0xC4, 0xC5, 0xC2, 0xC3, - 0xD6, 0xD7, 0xD4, 0xD5, 0xDA, 0xDB, 0xD8, 0xD9, + 0x29, 0x2A, 0x27, 0x28, 0x2D, 0x2E, 0x2B, 0x2C, + 0x21, 0x22, 0x1F, 0x20, 0x25, 0x26, 0x23, 0x24, + 0x39, 0x3A, 0x37, 0x38, 0x3D, 0x3E, 0x3B, 0x3C, + 0x31, 0x32, 0x2F, 0x30, 0x35, 0x36, 0x33, 0x34, + 0x0A, 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, + 0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, + 0x1A, 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, + 0x12, 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, + 0x62, 0x63, 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, + 0x5D, 0x5D, 0x5C, 0x5C, 0x5F, 0x5F, 0x5E, 0x5E, + 0x74, 0x76, 0x70, 0x72, 0x7C, 0x7E, 0x78, 0x7A, + 0x6A, 0x6B, 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, + 0x48, 0x49, 0x46, 0x47, 0x4C, 0x4D, 0x4A, 0x4B, + 0x40, 0x41, 0x3F, 0x3F, 0x44, 0x45, 0x42, 0x43, + 0x56, 0x57, 0x54, 0x55, 0x5A, 0x5B, 0x58, 0x59, + 0x4F, 0x4F, 0x4E, 0x4E, 0x52, 0x53, 0x50, 0x51, + 0xA9, 0xAA, 0xA7, 0xA8, 0xAD, 0xAE, 0xAB, 0xAC, + 0xA1, 0xA2, 0x9F, 0xA0, 0xA5, 0xA6, 0xA3, 0xA4, + 0xB9, 0xBA, 0xB7, 0xB8, 0xBD, 0xBE, 0xBB, 0xBC, + 0xB1, 0xB2, 0xAF, 0xB0, 0xB5, 0xB6, 0xB3, 0xB4, + 0x8A, 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, + 0x82, 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, + 0x9A, 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, + 0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, + 0xE2, 0xE3, 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, + 0xDD, 0xDD, 0xDC, 0xDC, 0xDF, 0xDF, 0xDE, 0xDE, + 0xF4, 0xF6, 0xF0, 0xF2, 0xFC, 0xFE, 0xF8, 0xFA, + 0xEA, 0xEB, 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, + 0xC8, 0xC9, 0xC6, 0xC7, 0xCC, 0xCD, 0xCA, 0xCB, + 0xC0, 0xC1, 0xBF, 0xBF, 0xC4, 0xC5, 0xC2, 0xC3, + 0xD6, 0xD7, 0xD4, 0xD5, 0xDA, 0xDB, 0xD8, 0xD9, 0xCF, 0xCF, 0xCE, 0xCE, 0xD2, 0xD3, 0xD0, 0xD1 }; @@ -3090,7 +3090,7 @@ static int ixj_write_cid_string(IXJ *j, char *s, int checksum) static void ixj_pad_fsk(IXJ *j, int pad) { - int cnt; + int cnt; for (cnt = 0; cnt < pad; cnt++) { if(j->fskdcnt < (j->fsksize - 1)) @@ -3474,7 +3474,7 @@ static void ixj_write_frame(IXJ *j) ixj_post_cid(j); } /* This may seem rude, but if we just played one frame of FSK data for CallerID - and there is real audio data in the buffer, we need to throw it away because + and there is real audio data in the buffer, we need to throw it away because we just used it's time slot */ if (j->write_buffer_rp > j->write_buffer_wp) { j->write_buffer_rp += j->cid_play_frame_size * 2; @@ -3486,7 +3486,7 @@ static void ixj_write_frame(IXJ *j) wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */ } - } else if (j->write_buffer && j->write_buffers_empty < 1) { + } else if (j->write_buffer && j->write_buffers_empty < 1) { if (j->write_buffer_wp > j->write_buffer_rp) { frame_count = (j->write_buffer_wp - j->write_buffer_rp) / (j->play_frame_size * 2); @@ -4150,7 +4150,7 @@ static void ixj_aec_start(IXJ *j, int level) ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */ ixj_WriteDSPCommand(0x0000, j); /* to off */ - + break; case AEC_MED: @@ -4161,7 +4161,7 @@ static void ixj_aec_start(IXJ *j, int level) ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */ ixj_WriteDSPCommand(0x0000, j); /* to off */ - + break; case AEC_HIGH: @@ -4172,7 +4172,7 @@ static void ixj_aec_start(IXJ *j, int level) ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */ ixj_WriteDSPCommand(0x0000, j); /* to off */ - + break; case AEC_AGC: @@ -4197,28 +4197,28 @@ static void ixj_aec_start(IXJ *j, int level) /* Now we can set the AGC initial parameters and turn it on */ ixj_WriteDSPCommand(0xCF90, j); /* Set AGC Minimum gain */ ixj_WriteDSPCommand(0x0020, j); /* to 0.125 (-18dB) */ - + ixj_WriteDSPCommand(0xCF91, j); /* Set AGC Maximum gain */ ixj_WriteDSPCommand(0x1000, j); /* to 16 (24dB) */ - + ixj_WriteDSPCommand(0xCF92, j); /* Set AGC start gain */ ixj_WriteDSPCommand(0x0800, j); /* to 8 (+18dB) */ - + ixj_WriteDSPCommand(0xCF93, j); /* Set AGC hold time */ ixj_WriteDSPCommand(0x1F40, j); /* to 2 seconds (units are 250us) */ - + ixj_WriteDSPCommand(0xCF94, j); /* Set AGC Attack Time Constant */ ixj_WriteDSPCommand(0x0005, j); /* to 8ms */ - + ixj_WriteDSPCommand(0xCF95, j); /* Set AGC Decay Time Constant */ ixj_WriteDSPCommand(0x000D, j); /* to 4096ms */ - + ixj_WriteDSPCommand(0xCF96, j); /* Set AGC Attack Threshold */ ixj_WriteDSPCommand(0x1200, j); /* to 25% */ - + ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */ ixj_WriteDSPCommand(0x0001, j); /* to on */ - + break; case AEC_AUTO: @@ -4495,7 +4495,7 @@ static int ixj_play_start(IXJ *j) return -ENOMEM; } /* j->write_buffers_empty = 2; */ - j->write_buffers_empty = 1; + j->write_buffers_empty = 1; j->write_buffer_size = j->play_frame_size * 2; j->write_buffer_end = j->write_buffer + j->play_frame_size * 2; j->write_buffer_rp = j->write_buffer_wp = j->write_buffer; @@ -6465,9 +6465,9 @@ static long do_ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long ar ixj_ringback(j); break; case PHONE_WINK: - if(j->cardtype == QTI_PHONEJACK) + if(j->cardtype == QTI_PHONEJACK) retval = -1; - else + else retval = ixj_wink(j); break; case PHONE_CPT_STOP: @@ -6553,7 +6553,7 @@ static long do_ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long ar ixj_write_vmwi(j, arg); break; case IXJCTL_CID: - if (copy_to_user(argp, &j->cid, sizeof(PHONE_CID))) + if (copy_to_user(argp, &j->cid, sizeof(PHONE_CID))) retval = -EFAULT; j->ex.bits.caller_id = 0; break; @@ -6575,13 +6575,13 @@ static long do_ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long ar break; case PHONE_CAPABILITIES_LIST: add_caps(j); - if (copy_to_user(argp, j->caplist, sizeof(struct phone_capability) * j->caps)) + if (copy_to_user(argp, j->caplist, sizeof(struct phone_capability) * j->caps)) retval = -EFAULT; break; case PHONE_CAPABILITIES_CHECK: { struct phone_capability cap; - if (copy_from_user(&cap, argp, sizeof(cap))) + if (copy_from_user(&cap, argp, sizeof(cap))) retval = -EFAULT; else { add_caps(j); @@ -6597,13 +6597,13 @@ static long do_ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long ar j->ex.bits.pstn_ring = 0; break; case IXJCTL_SET_FILTER: - if (copy_from_user(&jf, argp, sizeof(jf))) + if (copy_from_user(&jf, argp, sizeof(jf))) retval = -EFAULT; else retval = ixj_init_filter(j, &jf); break; case IXJCTL_SET_FILTER_RAW: - if (copy_from_user(&jfr, argp, sizeof(jfr))) + if (copy_from_user(&jfr, argp, sizeof(jfr))) retval = -EFAULT; else retval = ixj_init_filter_raw(j, &jfr); @@ -6638,9 +6638,9 @@ static long do_ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long ar raise *= 2; } if(j->sigdef.signal) - j->ex_sig.bytes |= raise; + j->ex_sig.bytes |= raise; else - j->ex_sig.bytes &= (raise^0xffff); + j->ex_sig.bytes &= (raise^0xffff); } break; case IXJCTL_INTERCOM_STOP: @@ -7040,9 +7040,9 @@ static int ixj_selfprobe(IXJ *j) /* initialise the DTMF prescale to a sensible value */ if (j->cardtype == QTI_LINEJACK) { - set_dtmf_prescale(j, 0x10); + set_dtmf_prescale(j, 0x10); } else { - set_dtmf_prescale(j, 0x40); + set_dtmf_prescale(j, 0x40); } set_play_volume(j, 0x100); set_rec_volume(j, 0x100); @@ -7095,15 +7095,15 @@ static int ixj_selfprobe(IXJ *j) j->ixj_signals[cnt] = SIGIO; /* Set the excetion signal enable flags */ - j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring = - j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 = + j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring = + j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 = j->ex_sig.bits.f3 = j->ex_sig.bits.fc0 = j->ex_sig.bits.fc1 = j->ex_sig.bits.fc2 = j->ex_sig.bits.fc3 = 1; #ifdef IXJ_DYN_ALLOC j->fskdata = NULL; #endif j->fskdcnt = 0; j->cidcw_wait = 0; - + /* Register with the Telephony for Linux subsystem */ j->p.f_op = &ixj_fops; j->p.open = ixj_open; @@ -7118,7 +7118,7 @@ static int ixj_selfprobe(IXJ *j) /* * Exported service for pcmcia card handling */ - + IXJ *ixj_pcmcia_probe(unsigned long dsp, unsigned long xilinx) { IXJ *j = ixj_alloc(); @@ -7320,7 +7320,7 @@ static int ixj_get_status_proc(char *buf) len += sprintf(buf + len, "\nRec volume 0x%x", get_rec_volume(j)); len += sprintf(buf + len, "\nPlay volume 0x%x", get_play_volume(j)); len += sprintf(buf + len, "\nDTMF prescale 0x%x", get_dtmf_prescale(j)); - + len += sprintf(buf + len, "\nHook state %d", j->hookstate); /* j->r_hook); */ if (j->cardtype == QTI_LINEJACK) { @@ -7417,7 +7417,7 @@ static int ixj_get_status_proc(char *buf) len += sprintf(buf + len, "\nPControl Wait Fails %ld", j->pcontrolwaitfail); len += sprintf(buf + len, "\nIs Control Ready Checks %ld", j->iscontrolready); len += sprintf(buf + len, "\nIs Control Ready Check failures %ld", j->iscontrolreadyfail); - + #endif len += sprintf(buf + len, "\n"); } @@ -7608,7 +7608,7 @@ static IXJ *new_ixj(unsigned long port) } static int __init ixj_probe_isapnp(int *cnt) -{ +{ int probe = 0; int func = 0x110; struct pnp_dev *dev = NULL, *old_dev = NULL; @@ -7686,7 +7686,7 @@ static int __init ixj_probe_isapnp(int *cnt) } return probe; } - + static int __init ixj_probe_isa(int *cnt) { int i, probe; @@ -7713,7 +7713,7 @@ static int __init ixj_probe_isa(int *cnt) static int __init ixj_probe_pci(int *cnt) { - struct pci_dev *pci = NULL; + struct pci_dev *pci = NULL; int i, probe = 0; IXJ *j = NULL; @@ -7745,7 +7745,7 @@ static int __init ixj_probe_pci(int *cnt) static int __init ixj_init(void) { int cnt = 0; - int probe = 0; + int probe = 0; cnt = 0; @@ -7887,7 +7887,7 @@ static void DAA_Coeff_US(IXJ *j) /* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x2D; */ /* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0x62; */ /* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x2D; */ - /* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */ + /* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */ /* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x2D; */ /* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x62; */ /* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; */ -- cgit v0.10.2 From 2471ec5895b2e3eeb55f4386a793123c8a5bf88a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 29 Mar 2012 21:52:20 +0300 Subject: Staging: rts5139: a couple off by one fixes Inside the array we check ms_start_idx[seg_no + 1] so on the last round through we end up going past the end of the array. Also if we don't break out of the loop early then we are beyond the end of the array there as well. With this change, if we don't find what we are looking for, we end on the last element of the array. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/ms.c b/drivers/staging/rts5139/ms.c index b0e9071..02aad2d 100644 --- a/drivers/staging/rts5139/ms.c +++ b/drivers/staging/rts5139/ms.c @@ -3864,7 +3864,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip, log_blk = (u16) (start_sector >> ms_card->block_shift); start_page = (u8) (start_sector & ms_card->page_off); - for (seg_no = 0; seg_no < sizeof(ms_start_idx) / 2; seg_no++) { + for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1; seg_no++) { if (log_blk < ms_start_idx[seg_no + 1]) break; } @@ -4020,7 +4020,8 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip, log_blk++; - for (seg_no = 0; seg_no < sizeof(ms_start_idx) / 2; seg_no++) { + for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1; + seg_no++) { if (log_blk < ms_start_idx[seg_no + 1]) break; } -- cgit v0.10.2 From f56d711bc9cc25b17643a76ead98caff24507ba9 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 30 Mar 2012 10:31:32 -0700 Subject: staging: fix android persistent_ram printk formats Fix printk format warnings in android/persistent_ram.c: drivers/staging/android/persistent_ram.c:426:4: warning: format '%ld' expects type 'long int', but argument 2 has type 'size_t' drivers/staging/android/persistent_ram.c:426:4: warning: format '%ld' expects type 'long int', but argument 3 has type 'size_t' drivers/staging/android/persistent_ram.c:430:4: warning: format '%ld' expects type 'long int', but argument 2 has type 'size_t' drivers/staging/android/persistent_ram.c:430:4: warning: format '%ld' expects type 'long int', but argument 3 has type 'size_t' Signed-off-by: Randy Dunlap Cc: Brian Swetland Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/persistent_ram.c b/drivers/staging/android/persistent_ram.c index e08f257..ce710f9 100644 --- a/drivers/staging/android/persistent_ram.c +++ b/drivers/staging/android/persistent_ram.c @@ -424,11 +424,11 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) if (buffer_size(prz) > prz->buffer_size || buffer_start(prz) > buffer_size(prz)) pr_info("persistent_ram: found existing invalid buffer," - " size %ld, start %ld\n", + " size %zu, start %zu\n", buffer_size(prz), buffer_start(prz)); else { pr_info("persistent_ram: found existing buffer," - " size %ld, start %ld\n", + " size %zu, start %zu\n", buffer_size(prz), buffer_start(prz)); persistent_ram_save_old(prz); } -- cgit v0.10.2 From ecb3b80ff968f1fffdbda9eb9aa8116db86ce220 Mon Sep 17 00:00:00 2001 From: Santosh Nayak Date: Tue, 3 Apr 2012 16:42:51 +0530 Subject: Staging: vme: Replace semaphore by mutex. Replace binary semaphore by mutex for code cleanup. Mutex also gives better performance than semaphore. Add 'mutex_destroy()' in 'vme_user_remove()' routine. Signed-off-by: Santosh Nayak Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index 7dcd162..10269d5 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include @@ -95,7 +95,7 @@ struct image_desc { void *kern_buf; /* Buffer address in kernel space */ dma_addr_t pci_buf; /* Buffer address in PCI address space */ unsigned long long size_buf; /* Buffer size */ - struct semaphore sem; /* Semaphore for locking image */ + struct mutex mutex; /* Mutex for locking image */ struct device *device; /* Sysfs device */ struct vme_resource *resource; /* VME resource */ int users; /* Number of current users */ @@ -168,7 +168,7 @@ static int vme_user_open(struct inode *inode, struct file *file) int err; unsigned int minor = MINOR(inode->i_rdev); - down(&image[minor].sem); + mutex_lock(&image[minor].mutex); /* Allow device to be opened if a resource is needed and allocated. */ if (minor < CONTROL_MINOR && image[minor].resource == NULL) { printk(KERN_ERR "No resources allocated for device\n"); @@ -179,12 +179,12 @@ static int vme_user_open(struct inode *inode, struct file *file) /* Increment user count */ image[minor].users++; - up(&image[minor].sem); + mutex_unlock(&image[minor].mutex); return 0; err_res: - up(&image[minor].sem); + mutex_unlock(&image[minor].mutex); return err; } @@ -193,12 +193,12 @@ static int vme_user_release(struct inode *inode, struct file *file) { unsigned int minor = MINOR(inode->i_rdev); - down(&image[minor].sem); + mutex_lock(&image[minor].mutex); /* Decrement user count */ image[minor].users--; - up(&image[minor].sem); + mutex_unlock(&image[minor].mutex); return 0; } @@ -325,14 +325,14 @@ static ssize_t vme_user_read(struct file *file, char __user *buf, size_t count, if (minor == CONTROL_MINOR) return 0; - down(&image[minor].sem); + mutex_lock(&image[minor].mutex); /* XXX Do we *really* want this helper - we can use vme_*_get ? */ image_size = vme_get_size(image[minor].resource); /* Ensure we are starting at a valid location */ if ((*ppos < 0) || (*ppos > (image_size - 1))) { - up(&image[minor].sem); + mutex_unlock(&image[minor].mutex); return 0; } @@ -353,8 +353,7 @@ static ssize_t vme_user_read(struct file *file, char __user *buf, size_t count, retval = -EINVAL; } - up(&image[minor].sem); - + mutex_unlock(&image[minor].mutex); if (retval > 0) *ppos += retval; @@ -372,13 +371,13 @@ static ssize_t vme_user_write(struct file *file, const char __user *buf, if (minor == CONTROL_MINOR) return 0; - down(&image[minor].sem); + mutex_lock(&image[minor].mutex); image_size = vme_get_size(image[minor].resource); /* Ensure we are starting at a valid location */ if ((*ppos < 0) || (*ppos > (image_size - 1))) { - up(&image[minor].sem); + mutex_unlock(&image[minor].mutex); return 0; } @@ -398,8 +397,8 @@ static ssize_t vme_user_write(struct file *file, const char __user *buf, default: retval = -EINVAL; } - - up(&image[minor].sem); + + mutex_unlock(&image[minor].mutex); if (retval > 0) *ppos += retval; @@ -416,7 +415,7 @@ static loff_t vme_user_llseek(struct file *file, loff_t off, int whence) if (minor == CONTROL_MINOR) return -EINVAL; - down(&image[minor].sem); + mutex_lock(&image[minor].mutex); image_size = vme_get_size(image[minor].resource); switch (whence) { @@ -430,19 +429,19 @@ static loff_t vme_user_llseek(struct file *file, loff_t off, int whence) absolute = image_size + off; break; default: - up(&image[minor].sem); + mutex_unlock(&image[minor].mutex); return -EINVAL; break; } if ((absolute < 0) || (absolute >= image_size)) { - up(&image[minor].sem); + mutex_unlock(&image[minor].mutex); return -EINVAL; } file->f_pos = absolute; - up(&image[minor].sem); + mutex_unlock(&image[minor].mutex); return absolute; } @@ -696,7 +695,7 @@ static int __devinit vme_user_probe(struct vme_dev *vdev) for (i = 0; i < VME_DEVS; i++) { image[i].kern_buf = NULL; image[i].pci_buf = 0; - sema_init(&image[i].sem, 1); + mutex_init(&image[i].mutex); image[i].device = NULL; image[i].resource = NULL; image[i].users = 0; @@ -858,8 +857,10 @@ static int __devexit vme_user_remove(struct vme_dev *dev) int i; /* Remove sysfs Entries */ - for (i = 0; i < VME_DEVS; i++) + for (i = 0; i < VME_DEVS; i++) { + mutex_destroy(&image[i].mutex); device_destroy(vme_user_sysfs_class, MKDEV(VME_MAJOR, i)); + } class_destroy(vme_user_sysfs_class); for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++) { -- cgit v0.10.2 From 73e18893ddf8d2c8cf319ff3d11a5aa75db5d5f8 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 4 Apr 2012 02:38:44 +0900 Subject: staging: Fix typo in wlags49_h2 Correct spellings within wlags49_h2 Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlags49_h2/README.ubuntu b/drivers/staging/wlags49_h2/README.ubuntu index edee8b9..5f1cfb8f 100644 --- a/drivers/staging/wlags49_h2/README.ubuntu +++ b/drivers/staging/wlags49_h2/README.ubuntu @@ -87,7 +87,7 @@ The linux driver files (wl_xxxx.c) are changed in the following ways: -- Recovery actions added The major problem was the order in which calls can be made. The original -looks like a traditonal UNIX driver. To call an "ioctl" function you +looks like a traditional UNIX driver. To call an "ioctl" function you have to "open" the device first to get a handle and after "close" no "ioctl" function can be called anymore. With the 2.6 driver this all changed; the former ioctl functions are now called before "open" and diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c index 6a44cb8..824b852 100644 --- a/drivers/staging/wlags49_h2/wl_netdev.c +++ b/drivers/staging/wlags49_h2/wl_netdev.c @@ -1063,7 +1063,7 @@ void wl_multicast( struct net_device *dev ) #if DBG if( DBG_FLAGS( DbgInfo ) & DBG_PARAM_ON ) { DBG_PRINT(" flags: %s%s%s\n", - ( dev->flags & IFF_PROMISC ) ? "Promiscous " : "", + ( dev->flags & IFF_PROMISC ) ? "Promiscuous " : "", ( dev->flags & IFF_MULTICAST ) ? "Multicast " : "", ( dev->flags & IFF_ALLMULTI ) ? "All-Multicast" : "" ); diff --git a/drivers/staging/wlags49_h2/wl_profile.c b/drivers/staging/wlags49_h2/wl_profile.c index b8c96cf..0e49272 100644 --- a/drivers/staging/wlags49_h2/wl_profile.c +++ b/drivers/staging/wlags49_h2/wl_profile.c @@ -401,7 +401,7 @@ void translate_option(char *buffer, struct wl_private *lp) if ((value_convert >= PARM_MIN_BRSC) || (value_convert <= PARM_MAX_BRSC)) lp->brsc[0] = value_convert; else - DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_BRSC_2GHZ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_BRSC_2GHZ); } else if (strcmp(key, PARM_NAME_BRSC_5GHZ) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_5GHZ, value); @@ -409,7 +409,7 @@ void translate_option(char *buffer, struct wl_private *lp) if ((value_convert >= PARM_MIN_BRSC) || (value_convert <= PARM_MAX_BRSC)) lp->brsc[1] = value_convert; else - DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_BRSC_5GHZ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_BRSC_5GHZ); } else if ((strcmp(key, PARM_NAME_DESIRED_SSID) == 0) || (strcmp(key, PARM_NAME_OWN_SSID) == 0)) { DBG_TRACE(DbgInfo, "SSID, value: %s\n", value); @@ -556,7 +556,7 @@ void translate_option(char *buffer, struct wl_private *lp) if ((value_convert >= PARM_MIN_SRSC) || (value_convert <= PARM_MAX_SRSC)) lp->srsc[0] = value_convert; else - DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_SRSC_2GHZ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_SRSC_2GHZ); } else if (strcmp(key, PARM_NAME_SRSC_5GHZ) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_5GHZ, value); @@ -564,7 +564,7 @@ void translate_option(char *buffer, struct wl_private *lp) if ((value_convert >= PARM_MIN_SRSC) || (value_convert <= PARM_MAX_SRSC)) lp->srsc[1] = value_convert; else - DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_SRSC_5GHZ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_SRSC_5GHZ); } else if (strcmp(key, PARM_NAME_SYSTEM_SCALE) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SYSTEM_SCALE, value); -- cgit v0.10.2 From 73e2918990c0d0ba7866696d492a8090e4f9f396 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 6 Apr 2012 23:33:52 +0900 Subject: staging: Fix typo in multiple files Collect spelling typo in multiple files within staging directory. Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index c7725e1..8223a69 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -835,7 +835,7 @@ int reset_card_proc(PMINI_ADAPTER ps_adapter) Bcm_kill_all_URBs(psIntfAdapter); /* Reset the UMA-B Device */ if (ps_adapter->chip_id >= T3LPB) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reseting UMA-B\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Resetting UMA-B\n"); retval = usb_reset_device(psIntfAdapter->udev); psIntfAdapter->psAdapter->StopAllXaction = FALSE; diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index e86ab58..53953c2 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -715,7 +715,7 @@ static int dt9812_probe(struct usb_interface *interface, iface_desc = interface->cur_altsetting; if (iface_desc->desc.bNumEndpoints != 5) { - err("Wrong number of endpints."); + err("Wrong number of endpoints."); retval = -ENODEV; goto error; } diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 1384419..3b7393a 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -353,7 +353,7 @@ struct rtdPrivate { unsigned long intCount; /* interrupt count */ long aiCount; /* total transfer size (samples) */ - int transCount; /* # to tranfer data. 0->1/2FIFO */ + int transCount; /* # to transfer data. 0->1/2FIFO */ int flags; /* flag event modes */ /* PCI device info */ @@ -1989,7 +1989,7 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) (TRANS_TARGET_PERIOD * cmd->chanlist_len) / cmd->scan_begin_arg; if (devpriv->transCount < cmd->chanlist_len) { - /* tranfer after each scan (and avoid 0) */ + /* transfer after each scan (and avoid 0) */ devpriv->transCount = cmd->chanlist_len; } else { /* make a multiple of scan length */ devpriv->transCount = @@ -2005,12 +2005,12 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->transCount = 0; devpriv->flags &= ~SEND_EOS; } else { - /* interrupt for each tranfer */ + /* interrupt for each transfer */ RtdAboutCounter(dev, devpriv->transCount - 1); } DPRINTK - ("rtd520: scanLen=%d tranferCount=%d fifoLen=%d\n scanTime(ns)=%d flags=0x%x\n", + ("rtd520: scanLen=%d transferCount=%d fifoLen=%d\n scanTime(ns)=%d flags=0x%x\n", cmd->chanlist_len, devpriv->transCount, devpriv->fifoLen, cmd->scan_begin_arg, devpriv->flags); } else { /* unknown timing, just use 1/2 FIFO */ diff --git a/drivers/staging/media/go7007/README b/drivers/staging/media/go7007/README index 48f4476..aeba132 100644 --- a/drivers/staging/media/go7007/README +++ b/drivers/staging/media/go7007/README @@ -6,6 +6,6 @@ Todo: - testing? - handle churn in v4l layer. -Please send patchs to Greg Kroah-Hartman and Cc: Ross +Please send patches to Greg Kroah-Hartman and Cc: Ross Cohen as well. diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c index 26bacb9..0f909b7 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c @@ -1905,7 +1905,7 @@ associate_complete: } }else{ ieee->softmac_stats.rx_auth_rs_err++; - IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode); + IEEE80211_DEBUG_MGMT("Authentication response status code 0x%x",errcode); ieee80211_associate_abort(ieee); } diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c index 3771985..b526fa4 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c @@ -216,7 +216,7 @@ static bool firmware_check_ready(struct net_device *dev, break; default: rt_status = false; - RT_TRACE(COMP_FIRMWARE, "Unknown firware status"); + RT_TRACE(COMP_FIRMWARE, "Unknown firmware status"); break; } diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c index 3e705ef..9676c59 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c @@ -689,7 +689,7 @@ void rtl8192_phy_setTxPower(struct net_device *dev, u8 channel) case RF_8258: break; default: - RT_TRACE(COMP_ERR, "unknown rf chip in funtion %s()\n", + RT_TRACE(COMP_ERR, "unknown rf chip in function %s()\n", __func__); break; } diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index be2a28c..6249c3f 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -671,7 +671,7 @@ void RxReorderIndicatePacket( struct ieee80211_device *ieee, index = 1; } else { /* Current packet is going to be inserted into pending list.*/ - //IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): We RX no ordered packed, insert to orderd list\n",__FUNCTION__); + //IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): We RX no ordered packed, insert to ordered list\n",__FUNCTION__); if(!list_empty(&ieee->RxReorder_Unused_List)) { pReorderEntry = (PRX_REORDER_ENTRY)list_entry(ieee->RxReorder_Unused_List.next,RX_REORDER_ENTRY,List); list_del_init(&pReorderEntry->List); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index c2ab5fa..f6ff8cf 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -2062,7 +2062,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, } }else{ ieee->softmac_stats.rx_auth_rs_err++; - IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode); + IEEE80211_DEBUG_MGMT("Authentication response status code 0x%x",errcode); ieee80211_associate_abort(ieee); } diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index 9b50b5b..c51f651 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -2212,7 +2212,7 @@ void dump_dl_modules(struct bridge_dev_context *bridge_context) if (status) { pr_debug( - "%s: Failed to read dll_module stuct for 0x%x.\n", + "%s: Failed to read dll_module struct for 0x%x.\n", __func__, module_dsp_addr); break; } diff --git a/drivers/staging/tidspbridge/core/ue_deh.c b/drivers/staging/tidspbridge/core/ue_deh.c index 006ffd7..3d28b23 100644 --- a/drivers/staging/tidspbridge/core/ue_deh.c +++ b/drivers/staging/tidspbridge/core/ue_deh.c @@ -215,7 +215,7 @@ static inline const char *event_to_string(int event) case DSP_MMUFAULT: return "DSP_MMUFAULT"; break; case DSP_PWRERROR: return "DSP_PWRERROR"; break; case DSP_WDTOVERFLOW: return "DSP_WDTOVERFLOW"; break; - default: return "unkown event"; break; + default: return "unknown event"; break; } } diff --git a/drivers/staging/usbip/usbip_protocol.txt b/drivers/staging/usbip/usbip_protocol.txt index 0f10208..16b6fe2 100644 --- a/drivers/staging/usbip/usbip_protocol.txt +++ b/drivers/staging/usbip/usbip_protocol.txt @@ -27,7 +27,7 @@ Once the client knows the list of exported USB devices it may decide to use one of them. First the client opens a TCP/IP connection towards the server and sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. If the import was successful the TCP/IP connection remains open and will be used -to trasfer the URB traffic between the client and the server. The client may +to transfer the URB traffic between the client and the server. The client may send two types of packets: the USBIP_CMD_SUBMIT to submit an URB, and USBIP_CMD_UNLINK to unlink a previously submitted URB. The answers of the server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. diff --git a/drivers/staging/vme/devices/vme_pio2_gpio.c b/drivers/staging/vme/devices/vme_pio2_gpio.c index 8584849..c766d39 100644 --- a/drivers/staging/vme/devices/vme_pio2_gpio.c +++ b/drivers/staging/vme/devices/vme_pio2_gpio.c @@ -79,7 +79,7 @@ static void pio2_gpio_set(struct gpio_chip *chip, unsigned int offset, if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == INPUT) | (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) { - dev_err(&card->vdev->dev, "Channel not availabe as output\n"); + dev_err(&card->vdev->dev, "Channel not available as output\n"); return; } -- cgit v0.10.2 From 6354eb81fe8cc32899959d2dac23aa1c9a12c9fa Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 2 Apr 2012 07:25:19 -0700 Subject: staging:omapdrm Fix typos in drivers:omapdrm The below patch fixes some typos that I found while reading. Note: I was told to hold off sending anything until *rc1 so hopefully now its alright.(wasnt sure what kernel *rc*) Signed-off-by: Justin P. Mattock Reviewed-by: Rob Clark Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/omapdrm/omap_fb.c b/drivers/staging/omapdrm/omap_fb.c index 04b235b..0c53a3c 100644 --- a/drivers/staging/omapdrm/omap_fb.c +++ b/drivers/staging/omapdrm/omap_fb.c @@ -167,7 +167,7 @@ void omap_framebuffer_update_scanout(struct drm_framebuffer *fb, int x, int y, } /* Call for unpin 'a' (if not NULL), and pin 'b' (if not NULL). Although - * buffers to unpin are just just pushed to the unpin fifo so that the + * buffers to unpin are just pushed to the unpin fifo so that the * caller can defer unpin until vblank. * * Note if this fails (ie. something went very wrong!), all buffers are diff --git a/drivers/staging/omapdrm/tcm-sita.c b/drivers/staging/omapdrm/tcm-sita.c index 10d5ac3..efb6095 100644 --- a/drivers/staging/omapdrm/tcm-sita.c +++ b/drivers/staging/omapdrm/tcm-sita.c @@ -200,7 +200,7 @@ static s32 sita_reserve_1d(struct tcm *tcm, u32 num_slots, * * @param w width * @param h height - * @param area pointer to the area that will be populated with the reesrved + * @param area pointer to the area that will be populated with the reserved * area * * @return 0 on success, non-0 error value on failure. -- cgit v0.10.2 From d740e889d2a49b48a4527b5192dea9278e691d6f Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 9 Apr 2012 07:48:57 -0700 Subject: staging:ramster Fix typos in staging:ramster The below patch fixes some typos that I found while reading. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ramster/cluster/tcp.c b/drivers/staging/ramster/cluster/tcp.c index 3af1b2c..3490192 100644 --- a/drivers/staging/ramster/cluster/tcp.c +++ b/drivers/staging/ramster/cluster/tcp.c @@ -111,7 +111,7 @@ static struct socket *r2net_listen_sock; * r2net_wq. teardown detaches the callbacks before destroying the workqueue. * quorum work is queued as sock containers are shutdown.. stop_listening * tears down all the node's sock containers, preventing future shutdowns - * and queued quroum work, before canceling delayed quorum work and + * and queued quorum work, before canceling delayed quorum work and * destroying the work queue. */ static struct workqueue_struct *r2net_wq; @@ -660,7 +660,7 @@ out: /* * we register callbacks so we can queue work on events before calling - * the original callbacks. our callbacks our careful to test user_data + * the original callbacks. our callbacks are careful to test user_data * to discover when they've reaced with r2net_unregister_callbacks(). */ static void r2net_register_callbacks(struct sock *sk, diff --git a/drivers/staging/ramster/xvmalloc.c b/drivers/staging/ramster/xvmalloc.c index 93ba8e9..44ceb0b 100644 --- a/drivers/staging/ramster/xvmalloc.c +++ b/drivers/staging/ramster/xvmalloc.c @@ -132,7 +132,7 @@ static u32 find_block(struct xv_pool *pool, u32 size, if (!pool->flbitmap) return 0; - /* Get freelist index correspoding to this size */ + /* Get freelist index corresponding to this size */ slindex = get_index(size); slbitmap = pool->slbitmap[slindex / BITS_PER_LONG]; slbitstart = slindex % BITS_PER_LONG; diff --git a/drivers/staging/ramster/zcache-main.c b/drivers/staging/ramster/zcache-main.c index 68b2e05..c071111 100644 --- a/drivers/staging/ramster/zcache-main.c +++ b/drivers/staging/ramster/zcache-main.c @@ -2095,7 +2095,7 @@ out: /* * Called on a remote persistent tmem_get to attempt to preallocate * local storage for the data contained in the remote persistent page. - * If succesfully preallocated, returns the pampd, marked as remote and + * If successfully preallocated, returns the pampd, marked as remote and * in_transit. Else returns NULL. Note that the appropriate tmem data * structure must be locked. */ -- cgit v0.10.2 From 26908c9be1386f01a12852cc6bea78bd237f226e Mon Sep 17 00:00:00 2001 From: Max Tottenham Date: Tue, 3 Apr 2012 12:35:24 +0100 Subject: Staging: bcm: IPv6Protocol.c: Fix coding style The first in a series of 8 patches to fix IPv6Protocol.c This first patch fixes formatting issues for braced statements (e.g. if/for/while) Signed-off-by: Max Tottenham Acked-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/IPv6Protocol.c b/drivers/staging/bcm/IPv6Protocol.c index 5b4fd37..cd5f1c3 100644 --- a/drivers/staging/bcm/IPv6Protocol.c +++ b/drivers/staging/bcm/IPv6Protocol.c @@ -9,20 +9,18 @@ static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader UCHAR *pucRetHeaderPtr = NULL; UCHAR *pucPayloadPtr = NULL; USHORT usNextHeaderOffset = 0 ; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); - if((NULL == ppucPayload) || (*pusPayloadLength == 0) || (*bParseDone)) - { + if ((NULL == ppucPayload) || (*pusPayloadLength == 0) || + (*bParseDone)) { *bParseDone = TRUE; return NULL; - } pucRetHeaderPtr = *ppucPayload; pucPayloadPtr = *ppucPayload; - if(!pucRetHeaderPtr || !pucPayloadPtr) - { + if (!pucRetHeaderPtr || !pucPayloadPtr) { *bParseDone = TRUE; return NULL; } @@ -31,9 +29,7 @@ static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader *bParseDone = FALSE; - - switch(*pucNextHeader) - { + switch (*pucNextHeader) { case IPV6HDR_TYPE_HOPBYHOP: { @@ -102,7 +98,7 @@ static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader *bParseDone = TRUE; } break; - default : + default: { *bParseDone = TRUE; @@ -112,23 +108,17 @@ static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader } - if(*bParseDone == FALSE) - { - if(*pusPayloadLength <= usNextHeaderOffset) - { + if (*bParseDone == FALSE) { + if(*pusPayloadLength <= usNextHeaderOffset) { *bParseDone = TRUE; - } - else - { + } else { *pucNextHeader = *pucPayloadPtr; - pucPayloadPtr+=usNextHeaderOffset; - (*pusPayloadLength)-=usNextHeaderOffset; + pucPayloadPtr += usNextHeaderOffset; + (*pusPayloadLength) -= usNextHeaderOffset; } } - - *ppucPayload = pucPayloadPtr; return pucRetHeaderPtr; } @@ -140,22 +130,18 @@ static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload,USHORT *pusSrcPort,USHORT *p BOOLEAN bDone = FALSE; UCHAR ucHeaderType =0; UCHAR *pucNextHeader = NULL; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); - if( !pucPayload || (usPayloadLength == 0)) - { + if ( !pucPayload || (usPayloadLength == 0)) { return 0; } *pusSrcPort = *pusDestPort = 0; ucHeaderType = ucNextHeader; - while(!bDone) - { + while (!bDone) { pucNextHeader = GetNextIPV6ChainedHeader(&pIpv6HdrScanContext,&ucHeaderType,&bDone,&usPayloadLength); - if(bDone) - { - if((ucHeaderType==TCP_HEADER_TYPE) || (ucHeaderType == UDP_HEADER_TYPE)) - { + if(bDone) { + if((ucHeaderType==TCP_HEADER_TYPE) || (ucHeaderType == UDP_HEADER_TYPE)) { *pusSrcPort=*((PUSHORT)(pucNextHeader)); *pusDestPort=*((PUSHORT)(pucNextHeader+2)); BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nProtocol Ports - Src Port :0x%x Dest Port : 0x%x",ntohs(*pusSrcPort),ntohs(*pusDestPort)); @@ -192,41 +178,37 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, /**< Pointer to the driver control stru pstIpv6Header->usPayloadLength, pstIpv6Header->ucNextHeader); - do - { - if(0 == pstClassifierRule->ucDirection) - { + do { + if (0 == pstClassifierRule->ucDirection) { //cannot be processed for classification. // it is a down link connection break; } - if(!pstClassifierRule->bIpv6Protocol) - { + if (!pstClassifierRule->bIpv6Protocol) { //We are looking for Ipv6 Classifiers . Lets ignore this classifier and try the next one. break; } bClassificationSucceed=MatchSrcIpv6Address(pstClassifierRule,pstIpv6Header); - if(!bClassificationSucceed) - break; + if (!bClassificationSucceed) + break; - bClassificationSucceed=MatchDestIpv6Address(pstClassifierRule,pstIpv6Header); - if(!bClassificationSucceed) - break; + bClassificationSucceed=MatchDestIpv6Address(pstClassifierRule,pstIpv6Header); + if (!bClassificationSucceed) + break; //Match the protocol type.For IPv6 the next protocol at end of Chain of IPv6 prot headers bClassificationSucceed=MatchProtocol(pstClassifierRule,ucNextProtocolAboveIP); - if(!bClassificationSucceed) - break; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Protocol Matched"); + if (!bClassificationSucceed) + break; + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Protocol Matched"); - if((ucNextProtocolAboveIP == TCP_HEADER_TYPE) || (ucNextProtocolAboveIP == UDP_HEADER_TYPE)) - { + if ((ucNextProtocolAboveIP == TCP_HEADER_TYPE) || (ucNextProtocolAboveIP == UDP_HEADER_TYPE)) { //Match Src Port BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Source Port:%x\n",ntohs(ushSrcPort)); bClassificationSucceed=MatchSrcPort(pstClassifierRule,ntohs(ushSrcPort)); - if(!bClassificationSucceed) + if (!bClassificationSucceed) break; BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Src Port Matched"); @@ -234,24 +216,19 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, /**< Pointer to the driver control stru //Match Dest Port BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Destination Port:%x\n",ntohs(ushDestPort)); bClassificationSucceed=MatchDestPort(pstClassifierRule,ntohs(ushDestPort)); - if(!bClassificationSucceed) + if (!bClassificationSucceed) break; BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Dest Port Matched"); } - }while(0); + } while (0); - if(TRUE==bClassificationSucceed) - { + if (TRUE == bClassificationSucceed) { INT iMatchedSFQueueIndex = 0; iMatchedSFQueueIndex = SearchSfid(Adapter,pstClassifierRule->ulSFID); - if(iMatchedSFQueueIndex >= NO_OF_QUEUES) - { + if(iMatchedSFQueueIndex >= NO_OF_QUEUES) { bClassificationSucceed = FALSE; - } - else - { - if(FALSE == Adapter->PackInfo[iMatchedSFQueueIndex].bActive) - { + } else { + if (FALSE == Adapter->PackInfo[iMatchedSFQueueIndex].bActive) { bClassificationSucceed = FALSE; } } @@ -263,11 +240,11 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, /**< Pointer to the driver control stru static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header) { - UINT uiLoopIndex=0; - UINT uiIpv6AddIndex=0; - UINT uiIpv6AddrNoLongWords = 4; + UINT uiLoopIndex = 0; + UINT uiIpv6AddIndex = 0; + UINT uiIpv6AddrNoLongWords = 4; ULONG aulSrcIP[4]; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); /* //This is the no. of Src Addresses ie Range of IP Addresses contained //in the classifier rule for which we need to match @@ -275,18 +252,16 @@ static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Head UINT uiCountIPSrcAddresses = (UINT)pstClassifierRule->ucIPSourceAddressLength; - if(0 == uiCountIPSrcAddresses) + if (0 == uiCountIPSrcAddresses) return TRUE; //First Convert the Ip Address in the packet to Host Endian order - for(uiIpv6AddIndex=0;uiIpv6AddIndexulSrcIpAddress[uiIpv6AddIndex]); } - for(uiLoopIndex=0;uiLoopIndexstSrcIpAddress.ulIpv6Addr[uiLoopIndex]); - for(uiIpv6AddIndex=0;uiIpv6AddIndexstSrcIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulSrcIP[uiIpv6AddIndex]) - != pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) - { + for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { + if ((pstClassifierRule->stSrcIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulSrcIP[uiIpv6AddIndex]) + != pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) { //Match failed for current Ipv6 Address.Try next Ipv6 Address break; } - if(uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) - { + if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) { //Match Found BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Src Ip Address Matched\n"); return TRUE; @@ -316,11 +288,11 @@ static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Head static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header) { - UINT uiLoopIndex=0; - UINT uiIpv6AddIndex=0; - UINT uiIpv6AddrNoLongWords = 4; + UINT uiLoopIndex = 0; + UINT uiIpv6AddIndex = 0; + UINT uiIpv6AddrNoLongWords = 4; ULONG aulDestIP[4]; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); /* //This is the no. of Destination Addresses ie Range of IP Addresses contained //in the classifier rule for which we need to match @@ -328,18 +300,16 @@ static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Hea UINT uiCountIPDestinationAddresses = (UINT)pstClassifierRule->ucIPDestinationAddressLength; - if(0 == uiCountIPDestinationAddresses) + if (0 == uiCountIPDestinationAddresses) return TRUE; //First Convert the Ip Address in the packet to Host Endian order - for(uiIpv6AddIndex=0;uiIpv6AddIndexulDestIpAddress[uiIpv6AddIndex]); } - for(uiLoopIndex=0;uiLoopIndexstDestIpAddress.ulIpv6Addr[uiLoopIndex]); - for(uiIpv6AddIndex=0;uiIpv6AddIndexstDestIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulDestIP[uiIpv6AddIndex]) - != pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) - { + for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { + if ((pstClassifierRule->stDestIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulDestIP[uiIpv6AddIndex]) + != pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) { //Match failed for current Ipv6 Address.Try next Ipv6 Address break; } - if(uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) - { + if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) { //Match Found BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Destination Ip Address Matched\n"); return TRUE; @@ -371,10 +338,9 @@ static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Hea VOID DumpIpv6Address(ULONG *puIpv6Address) { UINT uiIpv6AddrNoLongWords = 4; - UINT uiIpv6AddIndex=0; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); - for(uiIpv6AddIndex=0;uiIpv6AddIndexucVersionPrio & 0xf0; BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Version : %x \n",ucVersion); -- cgit v0.10.2 From ac8c1003fb74d41c7181304d12515bb7104b7772 Mon Sep 17 00:00:00 2001 From: Max Tottenham Date: Tue, 3 Apr 2012 12:35:25 +0100 Subject: Staging: bcm: IPv6Protocol.c coding style fix Second in a set of patches to fix coding style in IPv6Protocol.c This patch changes the commenting style Signed-off-by: Max Tottenham Acked-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/IPv6Protocol.c b/drivers/staging/bcm/IPv6Protocol.c index cd5f1c3..de513bc 100644 --- a/drivers/staging/bcm/IPv6Protocol.c +++ b/drivers/staging/bcm/IPv6Protocol.c @@ -25,7 +25,7 @@ static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader return NULL; } - //Get the Nextt Header Type + /* Get the Nextt Header Type */ *bParseDone = FALSE; @@ -154,9 +154,11 @@ static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload,USHORT *pusSrcPort,USHORT *p } - -USHORT IpVersion6(PMINI_ADAPTER Adapter, /**< Pointer to the driver control structure */ - PVOID pcIpHeader, /**ucDirection) { - //cannot be processed for classification. - // it is a down link connection + /* + * cannot be processed for classification. + * it is a down link connection + */ break; } if (!pstClassifierRule->bIpv6Protocol) { - //We are looking for Ipv6 Classifiers . Lets ignore this classifier and try the next one. + /* + * We are looking for Ipv6 Classifiers + * Lets ignore this classifier and try the next one + */ break; } @@ -198,14 +208,18 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, /**< Pointer to the driver control stru if (!bClassificationSucceed) break; - //Match the protocol type.For IPv6 the next protocol at end of Chain of IPv6 prot headers + /* + * Match the protocol type. + * For IPv6 the next protocol at end of + * Chain of IPv6 prot headers + */ bClassificationSucceed=MatchProtocol(pstClassifierRule,ucNextProtocolAboveIP); if (!bClassificationSucceed) break; BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Protocol Matched"); if ((ucNextProtocolAboveIP == TCP_HEADER_TYPE) || (ucNextProtocolAboveIP == UDP_HEADER_TYPE)) { - //Match Src Port + /* Match Src Port */ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Source Port:%x\n",ntohs(ushSrcPort)); bClassificationSucceed=MatchSrcPort(pstClassifierRule,ntohs(ushSrcPort)); if (!bClassificationSucceed) @@ -213,7 +227,7 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, /**< Pointer to the driver control stru BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Src Port Matched"); - //Match Dest Port + /* Match Dest Port */ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Destination Port:%x\n",ntohs(ushDestPort)); bClassificationSucceed=MatchDestPort(pstClassifierRule,ntohs(ushDestPort)); if (!bClassificationSucceed) @@ -246,9 +260,9 @@ static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Head ULONG aulSrcIP[4]; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); /* - //This is the no. of Src Addresses ie Range of IP Addresses contained - //in the classifier rule for which we need to match - */ + * This is the no. of Src Addresses ie Range of IP Addresses contained + * in the classifier rule for which we need to match + */ UINT uiCountIPSrcAddresses = (UINT)pstClassifierRule->ucIPSourceAddressLength; @@ -256,7 +270,7 @@ static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Head return TRUE; - //First Convert the Ip Address in the packet to Host Endian order + /* First Convert the Ip Address in the packet to Host Endian order */ for (uiIpv6AddIndex = 0; uiIpv6AddIndexulSrcIpAddress[uiIpv6AddIndex]); } @@ -272,12 +286,15 @@ static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Head for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { if ((pstClassifierRule->stSrcIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulSrcIP[uiIpv6AddIndex]) != pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) { - //Match failed for current Ipv6 Address.Try next Ipv6 Address + /* + * Match failed for current Ipv6 Address + * Try next Ipv6 Address + */ break; } if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) { - //Match Found + /* Match Found */ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Src Ip Address Matched\n"); return TRUE; } @@ -293,10 +310,11 @@ static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Hea UINT uiIpv6AddrNoLongWords = 4; ULONG aulDestIP[4]; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); - /* - //This is the no. of Destination Addresses ie Range of IP Addresses contained - //in the classifier rule for which we need to match - */ + /* + * This is the no. of Destination Addresses + * ie Range of IP Addresses contained in the classifier rule + * for which we need to match + */ UINT uiCountIPDestinationAddresses = (UINT)pstClassifierRule->ucIPDestinationAddressLength; @@ -304,7 +322,7 @@ static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Hea return TRUE; - //First Convert the Ip Address in the packet to Host Endian order + /* First Convert the Ip Address in the packet to Host Endian order */ for (uiIpv6AddIndex = 0;uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { aulDestIP[uiIpv6AddIndex]=ntohl(pstIpv6Header->ulDestIpAddress[uiIpv6AddIndex]); } @@ -320,12 +338,15 @@ static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Hea for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { if ((pstClassifierRule->stDestIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulDestIP[uiIpv6AddIndex]) != pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) { - //Match failed for current Ipv6 Address.Try next Ipv6 Address + /* + * Match failed for current Ipv6 Address. + * Try next Ipv6 Address + */ break; } if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) { - //Match Found + /* Match Found */ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Destination Ip Address Matched\n"); return TRUE; } @@ -356,7 +377,10 @@ static VOID DumpIpv6Header(IPV6Header *pstIpv6Header) BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Version : %x \n",ucVersion); ucPrio = pstIpv6Header->ucVersionPrio & 0x0f; BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Priority : %x \n",ucPrio); - //BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Flow Label : %x \n",(pstIpv6Header->ucVersionPrio &0xf0); + /* + * BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + * "Flow Label : %x \n",(pstIpv6Header->ucVersionPrio &0xf0); + */ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Payload Length : %x \n",ntohs(pstIpv6Header->usPayloadLength)); BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Next Header : %x \n",pstIpv6Header->ucNextHeader); BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Hop Limit : %x \n",pstIpv6Header->ucHopLimit); -- cgit v0.10.2 From 07ed6b7f0e574bcc5e77f247044727234e9eb092 Mon Sep 17 00:00:00 2001 From: Max Tottenham Date: Tue, 3 Apr 2012 12:35:26 +0100 Subject: Staging: bcm: IPv6Protocol.c fix coding style Third in a series of patches to fix coding style in Ipv6Protocol.c This patch fixes the spacing around ',' in function calls. Signed-off-by: Max Tottenham Acked-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/IPv6Protocol.c b/drivers/staging/bcm/IPv6Protocol.c index de513bc..6bb949c 100644 --- a/drivers/staging/bcm/IPv6Protocol.c +++ b/drivers/staging/bcm/IPv6Protocol.c @@ -1,10 +1,10 @@ #include "headers.h" -static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header); -static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header); +static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, IPV6Header *pstIpv6Header); +static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, IPV6Header *pstIpv6Header); static VOID DumpIpv6Header(IPV6Header *pstIpv6Header); -static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader,BOOLEAN *bParseDone,USHORT *pusPayloadLength) +static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload, UCHAR *pucNextHeader, BOOLEAN *bParseDone, USHORT *pusPayloadLength) { UCHAR *pucRetHeaderPtr = NULL; UCHAR *pucPayloadPtr = NULL; @@ -33,7 +33,7 @@ static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader case IPV6HDR_TYPE_HOPBYHOP: { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 HopByHop Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 HopByHop Header"); usNextHeaderOffset+=sizeof(IPV6HopByHopOptionsHeader); } break; @@ -41,7 +41,7 @@ static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader case IPV6HDR_TYPE_ROUTING: { IPV6RoutingHeader *pstIpv6RoutingHeader; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Routing Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Routing Header"); pstIpv6RoutingHeader = (IPV6RoutingHeader *)pucPayloadPtr; usNextHeaderOffset += sizeof(IPV6RoutingHeader); usNextHeaderOffset += pstIpv6RoutingHeader->ucNumAddresses * IPV6_ADDRESS_SIZEINBYTES; @@ -50,7 +50,7 @@ static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader break; case IPV6HDR_TYPE_FRAGMENTATION: { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Fragmentation Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Fragmentation Header"); usNextHeaderOffset+= sizeof(IPV6FragmentHeader); } @@ -59,7 +59,7 @@ static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader { IPV6DestOptionsHeader *pstIpv6DestOptsHdr = (IPV6DestOptionsHeader *)pucPayloadPtr; int nTotalOptions = pstIpv6DestOptsHdr->ucHdrExtLen; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 DestOpts Header Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 DestOpts Header Header"); usNextHeaderOffset+= sizeof(IPV6DestOptionsHeader); usNextHeaderOffset+= nTotalOptions * IPV6_DESTOPTS_HDR_OPTIONSIZE ; @@ -69,32 +69,32 @@ static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader { IPV6AuthenticationHeader *pstIpv6AuthHdr = (IPV6AuthenticationHeader *)pucPayloadPtr; int nHdrLen = pstIpv6AuthHdr->ucLength; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Authentication Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Authentication Header"); usNextHeaderOffset+= nHdrLen * 4; } break; case IPV6HDR_TYPE_ENCRYPTEDSECURITYPAYLOAD: { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Encrypted Security Payload Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Encrypted Security Payload Header"); *bParseDone = TRUE; } break; case IPV6_ICMP_HDR_TYPE: { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " ICMP Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " ICMP Header"); *bParseDone = TRUE; } break; case TCP_HEADER_TYPE: { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nTCP Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nTCP Header"); *bParseDone = TRUE; } break; case UDP_HEADER_TYPE: { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nUDP Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nUDP Header"); *bParseDone = TRUE; } break; @@ -124,7 +124,7 @@ static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader } -static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload,USHORT *pusSrcPort,USHORT *pusDestPort,USHORT usPayloadLength,UCHAR ucNextHeader) +static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort, USHORT *pusDestPort, USHORT usPayloadLength, UCHAR ucNextHeader) { UCHAR *pIpv6HdrScanContext = pucPayload; BOOLEAN bDone = FALSE; @@ -139,12 +139,12 @@ static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload,USHORT *pusSrcPort,USHORT *p *pusSrcPort = *pusDestPort = 0; ucHeaderType = ucNextHeader; while (!bDone) { - pucNextHeader = GetNextIPV6ChainedHeader(&pIpv6HdrScanContext,&ucHeaderType,&bDone,&usPayloadLength); + pucNextHeader = GetNextIPV6ChainedHeader(&pIpv6HdrScanContext, &ucHeaderType, &bDone, &usPayloadLength); if(bDone) { if((ucHeaderType==TCP_HEADER_TYPE) || (ucHeaderType == UDP_HEADER_TYPE)) { *pusSrcPort=*((PUSHORT)(pucNextHeader)); *pusDestPort=*((PUSHORT)(pucNextHeader+2)); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nProtocol Ports - Src Port :0x%x Dest Port : 0x%x",ntohs(*pusSrcPort),ntohs(*pusDestPort)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nProtocol Ports - Src Port :0x%x Dest Port : 0x%x", ntohs(*pusSrcPort), ntohs(*pusDestPort)); } break; @@ -167,7 +167,7 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, IPV6Header *pstIpv6Header = NULL; BOOLEAN bClassificationSucceed = FALSE; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "IpVersion6 ==========>\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "IpVersion6 ==========>\n"); pstIpv6Header = (IPV6Header *)pcIpHeader; @@ -213,26 +213,26 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, * For IPv6 the next protocol at end of * Chain of IPv6 prot headers */ - bClassificationSucceed=MatchProtocol(pstClassifierRule,ucNextProtocolAboveIP); + bClassificationSucceed=MatchProtocol(pstClassifierRule, ucNextProtocolAboveIP); if (!bClassificationSucceed) break; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Protocol Matched"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Protocol Matched"); if ((ucNextProtocolAboveIP == TCP_HEADER_TYPE) || (ucNextProtocolAboveIP == UDP_HEADER_TYPE)) { /* Match Src Port */ - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Source Port:%x\n",ntohs(ushSrcPort)); - bClassificationSucceed=MatchSrcPort(pstClassifierRule,ntohs(ushSrcPort)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Source Port:%x\n", ntohs(ushSrcPort)); + bClassificationSucceed=MatchSrcPort(pstClassifierRule, ntohs(ushSrcPort)); if (!bClassificationSucceed) break; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Src Port Matched"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Src Port Matched"); /* Match Dest Port */ - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Destination Port:%x\n",ntohs(ushDestPort)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Destination Port:%x\n",ntohs(ushDestPort)); bClassificationSucceed=MatchDestPort(pstClassifierRule,ntohs(ushDestPort)); if (!bClassificationSucceed) break; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Dest Port Matched"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Dest Port Matched"); } } while (0); @@ -252,7 +252,7 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, } -static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header) +static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, IPV6Header *pstIpv6Header) { UINT uiLoopIndex = 0; UINT uiIpv6AddIndex = 0; @@ -276,11 +276,11 @@ static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Head } for (uiLoopIndex = 0; uiLoopIndexstSrcIpAddress.ulIpv6Mask[uiLoopIndex]); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Address In Classifier Rule : \n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Address In Classifier Rule : \n"); DumpIpv6Address(&pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex]); for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { @@ -295,7 +295,7 @@ static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Head if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) { /* Match Found */ - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Src Ip Address Matched\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Src Ip Address Matched\n"); return TRUE; } } @@ -303,7 +303,7 @@ static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Head return FALSE; } -static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header) +static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, IPV6Header *pstIpv6Header) { UINT uiLoopIndex = 0; UINT uiIpv6AddIndex = 0; @@ -328,11 +328,11 @@ static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Hea } for (uiLoopIndex = 0;uiLoopIndex < uiCountIPDestinationAddresses; uiLoopIndex += uiIpv6AddrNoLongWords) { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Address In Received Packet : \n "); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Address In Received Packet : \n "); DumpIpv6Address(aulDestIP); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Mask In Classifier Rule: \n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Mask In Classifier Rule: \n"); DumpIpv6Address(&pstClassifierRule->stDestIpAddress.ulIpv6Mask[uiLoopIndex]); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Address In Classifier Rule : \n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Address In Classifier Rule : \n"); DumpIpv6Address(&pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex]); for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { @@ -347,7 +347,7 @@ static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Hea if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) { /* Match Found */ - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Destination Ip Address Matched\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Destination Ip Address Matched\n"); return TRUE; } } @@ -362,7 +362,7 @@ VOID DumpIpv6Address(ULONG *puIpv6Address) UINT uiIpv6AddIndex = 0; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, ":%lx",puIpv6Address[uiIpv6AddIndex]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, ":%lx", puIpv6Address[uiIpv6AddIndex]); } } @@ -372,23 +372,23 @@ static VOID DumpIpv6Header(IPV6Header *pstIpv6Header) UCHAR ucVersion; UCHAR ucPrio; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "----Ipv6 Header---"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "----Ipv6 Header---"); ucVersion = pstIpv6Header->ucVersionPrio & 0xf0; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Version : %x \n",ucVersion); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Version : %x \n", ucVersion); ucPrio = pstIpv6Header->ucVersionPrio & 0x0f; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Priority : %x \n",ucPrio); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Priority : %x \n", ucPrio); /* * BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, * "Flow Label : %x \n",(pstIpv6Header->ucVersionPrio &0xf0); */ - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Payload Length : %x \n",ntohs(pstIpv6Header->usPayloadLength)); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Next Header : %x \n",pstIpv6Header->ucNextHeader); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Hop Limit : %x \n",pstIpv6Header->ucHopLimit); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Src Address :\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Payload Length : %x \n", ntohs(pstIpv6Header->usPayloadLength)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Next Header : %x \n", pstIpv6Header->ucNextHeader); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Hop Limit : %x \n", pstIpv6Header->ucHopLimit); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Src Address :\n"); DumpIpv6Address(pstIpv6Header->ulSrcIpAddress); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Dest Address :\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Dest Address :\n"); DumpIpv6Address(pstIpv6Header->ulDestIpAddress); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "----Ipv6 Header End---"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "----Ipv6 Header End---"); } -- cgit v0.10.2 From fac290a11694efff330c96041a7a88579c5cf8f2 Mon Sep 17 00:00:00 2001 From: Max Tottenham Date: Tue, 3 Apr 2012 12:35:27 +0100 Subject: Staging: bcm: IPv6Protocol.c coding style fix Fourth patch in a series of patches to fix coding style in IPv6Protocol.c Continuation of fixing spacing arount ',' Signed-off-by: Max Tottenham Acked-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/IPv6Protocol.c b/drivers/staging/bcm/IPv6Protocol.c index 6bb949c..7bc1dc2 100644 --- a/drivers/staging/bcm/IPv6Protocol.c +++ b/drivers/staging/bcm/IPv6Protocol.c @@ -34,7 +34,7 @@ static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload, UCHAR *pucNextHeade { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 HopByHop Header"); - usNextHeaderOffset+=sizeof(IPV6HopByHopOptionsHeader); + usNextHeaderOffset += sizeof(IPV6HopByHopOptionsHeader); } break; @@ -51,7 +51,7 @@ static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload, UCHAR *pucNextHeade case IPV6HDR_TYPE_FRAGMENTATION: { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Fragmentation Header"); - usNextHeaderOffset+= sizeof(IPV6FragmentHeader); + usNextHeaderOffset += sizeof(IPV6FragmentHeader); } break; @@ -60,8 +60,8 @@ static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload, UCHAR *pucNextHeade IPV6DestOptionsHeader *pstIpv6DestOptsHdr = (IPV6DestOptionsHeader *)pucPayloadPtr; int nTotalOptions = pstIpv6DestOptsHdr->ucHdrExtLen; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 DestOpts Header Header"); - usNextHeaderOffset+= sizeof(IPV6DestOptionsHeader); - usNextHeaderOffset+= nTotalOptions * IPV6_DESTOPTS_HDR_OPTIONSIZE ; + usNextHeaderOffset += sizeof(IPV6DestOptionsHeader); + usNextHeaderOffset += nTotalOptions * IPV6_DESTOPTS_HDR_OPTIONSIZE ; } break; @@ -70,7 +70,7 @@ static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload, UCHAR *pucNextHeade IPV6AuthenticationHeader *pstIpv6AuthHdr = (IPV6AuthenticationHeader *)pucPayloadPtr; int nHdrLen = pstIpv6AuthHdr->ucLength; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Authentication Header"); - usNextHeaderOffset+= nHdrLen * 4; + usNextHeaderOffset += nHdrLen * 4; } break; case IPV6HDR_TYPE_ENCRYPTEDSECURITYPAYLOAD: @@ -128,7 +128,7 @@ static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort, USHORT { UCHAR *pIpv6HdrScanContext = pucPayload; BOOLEAN bDone = FALSE; - UCHAR ucHeaderType =0; + UCHAR ucHeaderType = 0; UCHAR *pucNextHeader = NULL; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); @@ -141,9 +141,9 @@ static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort, USHORT while (!bDone) { pucNextHeader = GetNextIPV6ChainedHeader(&pIpv6HdrScanContext, &ucHeaderType, &bDone, &usPayloadLength); if(bDone) { - if((ucHeaderType==TCP_HEADER_TYPE) || (ucHeaderType == UDP_HEADER_TYPE)) { - *pusSrcPort=*((PUSHORT)(pucNextHeader)); - *pusDestPort=*((PUSHORT)(pucNextHeader+2)); + if((ucHeaderType == TCP_HEADER_TYPE) || (ucHeaderType == UDP_HEADER_TYPE)) { + *pusSrcPort = *((PUSHORT)(pucNextHeader)); + *pusDestPort = *((PUSHORT)(pucNextHeader+2)); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nProtocol Ports - Src Port :0x%x Dest Port : 0x%x", ntohs(*pusSrcPort), ntohs(*pusDestPort)); } break; @@ -163,7 +163,7 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, { USHORT ushDestPort = 0; USHORT ushSrcPort = 0; - UCHAR ucNextProtocolAboveIP =0; + UCHAR ucNextProtocolAboveIP = 0; IPV6Header *pstIpv6Header = NULL; BOOLEAN bClassificationSucceed = FALSE; @@ -200,11 +200,11 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, break; } - bClassificationSucceed=MatchSrcIpv6Address(pstClassifierRule,pstIpv6Header); + bClassificationSucceed = MatchSrcIpv6Address(pstClassifierRule, pstIpv6Header); if (!bClassificationSucceed) break; - bClassificationSucceed=MatchDestIpv6Address(pstClassifierRule,pstIpv6Header); + bClassificationSucceed = MatchDestIpv6Address(pstClassifierRule, pstIpv6Header); if (!bClassificationSucceed) break; @@ -213,7 +213,7 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, * For IPv6 the next protocol at end of * Chain of IPv6 prot headers */ - bClassificationSucceed=MatchProtocol(pstClassifierRule, ucNextProtocolAboveIP); + bClassificationSucceed = MatchProtocol(pstClassifierRule, ucNextProtocolAboveIP); if (!bClassificationSucceed) break; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Protocol Matched"); @@ -221,15 +221,15 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, if ((ucNextProtocolAboveIP == TCP_HEADER_TYPE) || (ucNextProtocolAboveIP == UDP_HEADER_TYPE)) { /* Match Src Port */ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Source Port:%x\n", ntohs(ushSrcPort)); - bClassificationSucceed=MatchSrcPort(pstClassifierRule, ntohs(ushSrcPort)); + bClassificationSucceed = MatchSrcPort(pstClassifierRule, ntohs(ushSrcPort)); if (!bClassificationSucceed) break; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Src Port Matched"); /* Match Dest Port */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Destination Port:%x\n",ntohs(ushDestPort)); - bClassificationSucceed=MatchDestPort(pstClassifierRule,ntohs(ushDestPort)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Destination Port:%x\n", ntohs(ushDestPort)); + bClassificationSucceed = MatchDestPort(pstClassifierRule, ntohs(ushDestPort)); if (!bClassificationSucceed) break; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Dest Port Matched"); @@ -238,7 +238,7 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, if (TRUE == bClassificationSucceed) { INT iMatchedSFQueueIndex = 0; - iMatchedSFQueueIndex = SearchSfid(Adapter,pstClassifierRule->ulSFID); + iMatchedSFQueueIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID); if(iMatchedSFQueueIndex >= NO_OF_QUEUES) { bClassificationSucceed = FALSE; } else { @@ -271,11 +271,11 @@ static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, IPV6Hea /* First Convert the Ip Address in the packet to Host Endian order */ - for (uiIpv6AddIndex = 0; uiIpv6AddIndexulSrcIpAddress[uiIpv6AddIndex]); + for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { + aulSrcIP[uiIpv6AddIndex] = ntohl(pstIpv6Header->ulSrcIpAddress[uiIpv6AddIndex]); } - for (uiLoopIndex = 0; uiLoopIndexulDestIpAddress[uiIpv6AddIndex]); + for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { + aulDestIP[uiIpv6AddIndex] = ntohl(pstIpv6Header->ulDestIpAddress[uiIpv6AddIndex]); } - for (uiLoopIndex = 0;uiLoopIndex < uiCountIPDestinationAddresses; uiLoopIndex += uiIpv6AddrNoLongWords) { + for (uiLoopIndex = 0; uiLoopIndex < uiCountIPDestinationAddresses; uiLoopIndex += uiIpv6AddrNoLongWords) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Address In Received Packet : \n "); DumpIpv6Address(aulDestIP); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Mask In Classifier Rule: \n"); -- cgit v0.10.2 From aadb4ec271ee73b39031acb8a201f96e56d1cbf1 Mon Sep 17 00:00:00 2001 From: Max Tottenham Date: Tue, 3 Apr 2012 12:35:28 +0100 Subject: Staging: bcm: IPv6Protocol.c coding style fix Fith in a series of patche to fi coding syle in IPv6Protocol.c Fixed trailing whitespaces and replaced spaces with tabs in code indents Signed-off-by: Max Tottenham Acked-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/IPv6Protocol.c b/drivers/staging/bcm/IPv6Protocol.c index 7bc1dc2..80173e7 100644 --- a/drivers/staging/bcm/IPv6Protocol.c +++ b/drivers/staging/bcm/IPv6Protocol.c @@ -4,7 +4,7 @@ static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, IPV6Hea static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, IPV6Header *pstIpv6Header); static VOID DumpIpv6Header(IPV6Header *pstIpv6Header); -static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload, UCHAR *pucNextHeader, BOOLEAN *bParseDone, USHORT *pusPayloadLength) +static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload, UCHAR *pucNextHeader, BOOLEAN *bParseDone, USHORT *pusPayloadLength) { UCHAR *pucRetHeaderPtr = NULL; UCHAR *pucPayloadPtr = NULL; @@ -109,7 +109,7 @@ static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload, UCHAR *pucNextHeade } if (*bParseDone == FALSE) { - if(*pusPayloadLength <= usNextHeaderOffset) { + if (*pusPayloadLength <= usNextHeaderOffset) { *bParseDone = TRUE; } else { *pucNextHeader = *pucPayloadPtr; @@ -132,7 +132,7 @@ static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort, USHORT UCHAR *pucNextHeader = NULL; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); - if ( !pucPayload || (usPayloadLength == 0)) { + if (!pucPayload || (usPayloadLength == 0)) { return 0; } @@ -140,8 +140,8 @@ static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort, USHORT ucHeaderType = ucNextHeader; while (!bDone) { pucNextHeader = GetNextIPV6ChainedHeader(&pIpv6HdrScanContext, &ucHeaderType, &bDone, &usPayloadLength); - if(bDone) { - if((ucHeaderType == TCP_HEADER_TYPE) || (ucHeaderType == UDP_HEADER_TYPE)) { + if (bDone) { + if ((ucHeaderType == TCP_HEADER_TYPE) || (ucHeaderType == UDP_HEADER_TYPE)) { *pusSrcPort = *((PUSHORT)(pucNextHeader)); *pusDestPort = *((PUSHORT)(pucNextHeader+2)); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nProtocol Ports - Src Port :0x%x Dest Port : 0x%x", ntohs(*pusSrcPort), ntohs(*pusDestPort)); @@ -159,7 +159,7 @@ static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort, USHORT * Arg 2 PVOID pcIpHeader is a pointer to the IP header of the packet */ USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, - S_CLASSIFIER_RULE *pstClassifierRule ) + S_CLASSIFIER_RULE *pstClassifierRule) { USHORT ushDestPort = 0; USHORT ushSrcPort = 0; @@ -173,8 +173,8 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, DumpIpv6Header(pstIpv6Header); - /* - * Try to get the next higher layer protocol + /* + * Try to get the next higher layer protocol * and the Ports Nos if TCP or UDP */ ucNextProtocolAboveIP = GetIpv6ProtocolPorts((UCHAR *)(pcIpHeader + sizeof(IPV6Header)), @@ -185,38 +185,39 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, do { if (0 == pstClassifierRule->ucDirection) { - /* + /* * cannot be processed for classification. - * it is a down link connection + * it is a down link connection */ break; } if (!pstClassifierRule->bIpv6Protocol) { /* - * We are looking for Ipv6 Classifiers + * We are looking for Ipv6 Classifiers * Lets ignore this classifier and try the next one */ break; } bClassificationSucceed = MatchSrcIpv6Address(pstClassifierRule, pstIpv6Header); - if (!bClassificationSucceed) - break; + if (!bClassificationSucceed) + break; - bClassificationSucceed = MatchDestIpv6Address(pstClassifierRule, pstIpv6Header); - if (!bClassificationSucceed) - break; + bClassificationSucceed = MatchDestIpv6Address(pstClassifierRule, pstIpv6Header); + if (!bClassificationSucceed) + break; - /* + /* * Match the protocol type. - * For IPv6 the next protocol at end of + * For IPv6 the next protocol at end of * Chain of IPv6 prot headers */ bClassificationSucceed = MatchProtocol(pstClassifierRule, ucNextProtocolAboveIP); - if (!bClassificationSucceed) - break; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Protocol Matched"); + if (!bClassificationSucceed) + break; + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Protocol Matched"); if ((ucNextProtocolAboveIP == TCP_HEADER_TYPE) || (ucNextProtocolAboveIP == UDP_HEADER_TYPE)) { /* Match Src Port */ @@ -239,7 +240,7 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, if (TRUE == bClassificationSucceed) { INT iMatchedSFQueueIndex = 0; iMatchedSFQueueIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID); - if(iMatchedSFQueueIndex >= NO_OF_QUEUES) { + if (iMatchedSFQueueIndex >= NO_OF_QUEUES) { bClassificationSucceed = FALSE; } else { if (FALSE == Adapter->PackInfo[iMatchedSFQueueIndex].bActive) { @@ -286,7 +287,7 @@ static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, IPV6Hea for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { if ((pstClassifierRule->stSrcIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulSrcIP[uiIpv6AddIndex]) != pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) { - /* + /* * Match failed for current Ipv6 Address * Try next Ipv6 Address */ @@ -310,9 +311,9 @@ static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, IPV6He UINT uiIpv6AddrNoLongWords = 4; ULONG aulDestIP[4]; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); - /* - * This is the no. of Destination Addresses - * ie Range of IP Addresses contained in the classifier rule + /* + * This is the no. of Destination Addresses + * ie Range of IP Addresses contained in the classifier rule * for which we need to match */ UINT uiCountIPDestinationAddresses = (UINT)pstClassifierRule->ucIPDestinationAddressLength; @@ -338,7 +339,7 @@ static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, IPV6He for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { if ((pstClassifierRule->stDestIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulDestIP[uiIpv6AddIndex]) != pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) { - /* + /* * Match failed for current Ipv6 Address. * Try next Ipv6 Address */ @@ -377,8 +378,8 @@ static VOID DumpIpv6Header(IPV6Header *pstIpv6Header) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Version : %x \n", ucVersion); ucPrio = pstIpv6Header->ucVersionPrio & 0x0f; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Priority : %x \n", ucPrio); - /* - * BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + /* + * BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, * "Flow Label : %x \n",(pstIpv6Header->ucVersionPrio &0xf0); */ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Payload Length : %x \n", ntohs(pstIpv6Header->usPayloadLength)); -- cgit v0.10.2 From 6d147069346f99482bd9c417dec7fd4ce50d266a Mon Sep 17 00:00:00 2001 From: Max Tottenham Date: Tue, 3 Apr 2012 12:35:29 +0100 Subject: Staging: bcm: IPv6Protocol.c coding style fix Sixth in a series of patche to fix coding style in IPv6Protocol.c This patch changes the format of if statments from: if (#VALUE == variable) to: if (variable == #VALUE) Signed-off-by: Max Tottenham Acked-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/IPv6Protocol.c b/drivers/staging/bcm/IPv6Protocol.c index 80173e7..0f87119 100644 --- a/drivers/staging/bcm/IPv6Protocol.c +++ b/drivers/staging/bcm/IPv6Protocol.c @@ -11,7 +11,7 @@ static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload, UCHAR *pucNextHeader USHORT usNextHeaderOffset = 0 ; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); - if ((NULL == ppucPayload) || (*pusPayloadLength == 0) || + if ((ppucPayload == NULL) || (*pusPayloadLength == 0) || (*bParseDone)) { *bParseDone = TRUE; return NULL; @@ -184,7 +184,7 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, pstIpv6Header->ucNextHeader); do { - if (0 == pstClassifierRule->ucDirection) { + if (pstClassifierRule->ucDirection == 0) { /* * cannot be processed for classification. * it is a down link connection @@ -237,13 +237,13 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, } } while (0); - if (TRUE == bClassificationSucceed) { + if (bClassificationSucceed == TRUE) { INT iMatchedSFQueueIndex = 0; iMatchedSFQueueIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID); if (iMatchedSFQueueIndex >= NO_OF_QUEUES) { bClassificationSucceed = FALSE; } else { - if (FALSE == Adapter->PackInfo[iMatchedSFQueueIndex].bActive) { + if (Adapter->PackInfo[iMatchedSFQueueIndex].bActive == FALSE) { bClassificationSucceed = FALSE; } } @@ -267,7 +267,7 @@ static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, IPV6Hea UINT uiCountIPSrcAddresses = (UINT)pstClassifierRule->ucIPSourceAddressLength; - if (0 == uiCountIPSrcAddresses) + if (uiCountIPSrcAddresses == 0) return TRUE; @@ -319,7 +319,7 @@ static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, IPV6He UINT uiCountIPDestinationAddresses = (UINT)pstClassifierRule->ucIPDestinationAddressLength; - if (0 == uiCountIPDestinationAddresses) + if (uiCountIPDestinationAddresses == 0) return TRUE; -- cgit v0.10.2 From 6704fc83cb0db017d840eb5a6ca6326a44399eb2 Mon Sep 17 00:00:00 2001 From: Max Tottenham Date: Tue, 3 Apr 2012 12:35:30 +0100 Subject: Staging: bcm: IPv6Protocol.c: coding style fix Seventh patch in a series of patches to fix coding style in IPv6Protocol.c this patch makes the file mostly conform to the 80 char line limit there are some exceptions to this rule I have left in to aid readability Signed-off-by: Max Tottenham Acked-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/IPv6Protocol.c b/drivers/staging/bcm/IPv6Protocol.c index 0f87119..d9c9cef 100644 --- a/drivers/staging/bcm/IPv6Protocol.c +++ b/drivers/staging/bcm/IPv6Protocol.c @@ -1,10 +1,13 @@ #include "headers.h" -static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, IPV6Header *pstIpv6Header); -static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, IPV6Header *pstIpv6Header); +static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, + IPV6Header *pstIpv6Header); +static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, + IPV6Header *pstIpv6Header); static VOID DumpIpv6Header(IPV6Header *pstIpv6Header); -static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload, UCHAR *pucNextHeader, BOOLEAN *bParseDone, USHORT *pusPayloadLength) +static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload, + UCHAR *pucNextHeader, BOOLEAN *bParseDone, USHORT *pusPayloadLength) { UCHAR *pucRetHeaderPtr = NULL; UCHAR *pucPayloadPtr = NULL; @@ -33,7 +36,8 @@ static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload, UCHAR *pucNextHeader case IPV6HDR_TYPE_HOPBYHOP: { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 HopByHop Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "\nIPv6 HopByHop Header"); usNextHeaderOffset += sizeof(IPV6HopByHopOptionsHeader); } break; @@ -41,7 +45,8 @@ static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload, UCHAR *pucNextHeader case IPV6HDR_TYPE_ROUTING: { IPV6RoutingHeader *pstIpv6RoutingHeader; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Routing Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "\nIPv6 Routing Header"); pstIpv6RoutingHeader = (IPV6RoutingHeader *)pucPayloadPtr; usNextHeaderOffset += sizeof(IPV6RoutingHeader); usNextHeaderOffset += pstIpv6RoutingHeader->ucNumAddresses * IPV6_ADDRESS_SIZEINBYTES; @@ -50,7 +55,9 @@ static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload, UCHAR *pucNextHeader break; case IPV6HDR_TYPE_FRAGMENTATION: { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Fragmentation Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, + "\nIPv6 Fragmentation Header"); usNextHeaderOffset += sizeof(IPV6FragmentHeader); } @@ -59,7 +66,9 @@ static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload, UCHAR *pucNextHeader { IPV6DestOptionsHeader *pstIpv6DestOptsHdr = (IPV6DestOptionsHeader *)pucPayloadPtr; int nTotalOptions = pstIpv6DestOptsHdr->ucHdrExtLen; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 DestOpts Header Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, + "\nIPv6 DestOpts Header Header"); usNextHeaderOffset += sizeof(IPV6DestOptionsHeader); usNextHeaderOffset += nTotalOptions * IPV6_DESTOPTS_HDR_OPTIONSIZE ; @@ -69,32 +78,39 @@ static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload, UCHAR *pucNextHeader { IPV6AuthenticationHeader *pstIpv6AuthHdr = (IPV6AuthenticationHeader *)pucPayloadPtr; int nHdrLen = pstIpv6AuthHdr->ucLength; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Authentication Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, + "\nIPv6 Authentication Header"); usNextHeaderOffset += nHdrLen * 4; } break; case IPV6HDR_TYPE_ENCRYPTEDSECURITYPAYLOAD: { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Encrypted Security Payload Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, + "\nIPv6 Encrypted Security Payload Header"); *bParseDone = TRUE; } break; case IPV6_ICMP_HDR_TYPE: { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " ICMP Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "\nICMP Header"); *bParseDone = TRUE; } break; case TCP_HEADER_TYPE: { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nTCP Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "\nTCP Header"); *bParseDone = TRUE; } break; case UDP_HEADER_TYPE: { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nUDP Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "\nUDP Header"); *bParseDone = TRUE; } break; @@ -124,7 +140,8 @@ static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload, UCHAR *pucNextHeader } -static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort, USHORT *pusDestPort, USHORT usPayloadLength, UCHAR ucNextHeader) +static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort, + USHORT *pusDestPort, USHORT usPayloadLength, UCHAR ucNextHeader) { UCHAR *pIpv6HdrScanContext = pucPayload; BOOLEAN bDone = FALSE; @@ -139,12 +156,18 @@ static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort, USHORT *pusSrcPort = *pusDestPort = 0; ucHeaderType = ucNextHeader; while (!bDone) { - pucNextHeader = GetNextIPV6ChainedHeader(&pIpv6HdrScanContext, &ucHeaderType, &bDone, &usPayloadLength); + pucNextHeader = GetNextIPV6ChainedHeader(&pIpv6HdrScanContext, + &ucHeaderType, &bDone, &usPayloadLength); if (bDone) { - if ((ucHeaderType == TCP_HEADER_TYPE) || (ucHeaderType == UDP_HEADER_TYPE)) { - *pusSrcPort = *((PUSHORT)(pucNextHeader)); - *pusDestPort = *((PUSHORT)(pucNextHeader+2)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nProtocol Ports - Src Port :0x%x Dest Port : 0x%x", ntohs(*pusSrcPort), ntohs(*pusDestPort)); + if ((ucHeaderType == TCP_HEADER_TYPE) || + (ucHeaderType == UDP_HEADER_TYPE)) { + *pusSrcPort = *((PUSHORT)(pucNextHeader)); + *pusDestPort = *((PUSHORT)(pucNextHeader+2)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, + "\nProtocol Ports - Src Port :0x%x Dest Port : 0x%x", + ntohs(*pusSrcPort), + ntohs(*pusDestPort)); } break; @@ -167,7 +190,8 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, IPV6Header *pstIpv6Header = NULL; BOOLEAN bClassificationSucceed = FALSE; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "IpVersion6 ==========>\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "IpVersion6 ==========>\n"); pstIpv6Header = (IPV6Header *)pcIpHeader; @@ -200,11 +224,13 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, break; } - bClassificationSucceed = MatchSrcIpv6Address(pstClassifierRule, pstIpv6Header); + bClassificationSucceed = MatchSrcIpv6Address(pstClassifierRule, + pstIpv6Header); if (!bClassificationSucceed) break; - bClassificationSucceed = MatchDestIpv6Address(pstClassifierRule, pstIpv6Header); + bClassificationSucceed = MatchDestIpv6Address(pstClassifierRule, + pstIpv6Header); if (!bClassificationSucceed) break; @@ -213,27 +239,38 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, * For IPv6 the next protocol at end of * Chain of IPv6 prot headers */ - bClassificationSucceed = MatchProtocol(pstClassifierRule, ucNextProtocolAboveIP); + bClassificationSucceed = MatchProtocol(pstClassifierRule, + ucNextProtocolAboveIP); if (!bClassificationSucceed) break; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Protocol Matched"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "\nIPv6 Protocol Matched"); - if ((ucNextProtocolAboveIP == TCP_HEADER_TYPE) || (ucNextProtocolAboveIP == UDP_HEADER_TYPE)) { + if ((ucNextProtocolAboveIP == TCP_HEADER_TYPE) || + (ucNextProtocolAboveIP == UDP_HEADER_TYPE)) { /* Match Src Port */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Source Port:%x\n", ntohs(ushSrcPort)); - bClassificationSucceed = MatchSrcPort(pstClassifierRule, ntohs(ushSrcPort)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "\nIPv6 Source Port:%x\n", + ntohs(ushSrcPort)); + bClassificationSucceed = MatchSrcPort(pstClassifierRule, + ntohs(ushSrcPort)); if (!bClassificationSucceed) break; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Src Port Matched"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "\nIPv6 Src Port Matched"); /* Match Dest Port */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Destination Port:%x\n", ntohs(ushDestPort)); - bClassificationSucceed = MatchDestPort(pstClassifierRule, ntohs(ushDestPort)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "\nIPv6 Destination Port:%x\n", + ntohs(ushDestPort)); + bClassificationSucceed = MatchDestPort(pstClassifierRule, + ntohs(ushDestPort)); if (!bClassificationSucceed) break; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Dest Port Matched"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "\nIPv6 Dest Port Matched"); } } while (0); @@ -253,7 +290,8 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, } -static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, IPV6Header *pstIpv6Header) +static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, + IPV6Header *pstIpv6Header) { UINT uiLoopIndex = 0; UINT uiIpv6AddIndex = 0; @@ -277,11 +315,14 @@ static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, IPV6Hea } for (uiLoopIndex = 0; uiLoopIndex < uiCountIPSrcAddresses; uiLoopIndex += uiIpv6AddrNoLongWords) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Address In Received Packet : \n "); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "\n Src Ipv6 Address In Received Packet :\n "); DumpIpv6Address(aulSrcIP); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Mask In Classifier Rule: \n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "\n Src Ipv6 Mask In Classifier Rule:\n"); DumpIpv6Address(&pstClassifierRule->stSrcIpAddress.ulIpv6Mask[uiLoopIndex]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Address In Classifier Rule : \n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "\n Src Ipv6 Address In Classifier Rule :\n"); DumpIpv6Address(&pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex]); for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { @@ -296,7 +337,9 @@ static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, IPV6Hea if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) { /* Match Found */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Src Ip Address Matched\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, + "Ipv6 Src Ip Address Matched\n"); return TRUE; } } @@ -304,7 +347,8 @@ static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, IPV6Hea return FALSE; } -static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, IPV6Header *pstIpv6Header) +static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, + IPV6Header *pstIpv6Header) { UINT uiLoopIndex = 0; UINT uiIpv6AddIndex = 0; @@ -329,11 +373,14 @@ static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, IPV6He } for (uiLoopIndex = 0; uiLoopIndex < uiCountIPDestinationAddresses; uiLoopIndex += uiIpv6AddrNoLongWords) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Address In Received Packet : \n "); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "\n Destination Ipv6 Address In Received Packet :\n "); DumpIpv6Address(aulDestIP); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Mask In Classifier Rule: \n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "\n Destination Ipv6 Mask In Classifier Rule :\n"); DumpIpv6Address(&pstClassifierRule->stDestIpAddress.ulIpv6Mask[uiLoopIndex]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Address In Classifier Rule : \n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "\n Destination Ipv6 Address In Classifier Rule :\n"); DumpIpv6Address(&pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex]); for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { @@ -348,7 +395,9 @@ static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, IPV6He if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) { /* Match Found */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Destination Ip Address Matched\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, + "Ipv6 Destination Ip Address Matched\n"); return TRUE; } } @@ -363,7 +412,8 @@ VOID DumpIpv6Address(ULONG *puIpv6Address) UINT uiIpv6AddIndex = 0; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, ":%lx", puIpv6Address[uiIpv6AddIndex]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + ":%lx", puIpv6Address[uiIpv6AddIndex]); } } @@ -373,23 +423,33 @@ static VOID DumpIpv6Header(IPV6Header *pstIpv6Header) UCHAR ucVersion; UCHAR ucPrio; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "----Ipv6 Header---"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "----Ipv6 Header---"); ucVersion = pstIpv6Header->ucVersionPrio & 0xf0; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Version : %x \n", ucVersion); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "Version : %x\n", ucVersion); ucPrio = pstIpv6Header->ucVersionPrio & 0x0f; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Priority : %x \n", ucPrio); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "Priority : %x\n", ucPrio); /* * BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - * "Flow Label : %x \n",(pstIpv6Header->ucVersionPrio &0xf0); + * "Flow Label : %x\n",(pstIpv6Header->ucVersionPrio &0xf0); */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Payload Length : %x \n", ntohs(pstIpv6Header->usPayloadLength)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Next Header : %x \n", pstIpv6Header->ucNextHeader); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Hop Limit : %x \n", pstIpv6Header->ucHopLimit); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Src Address :\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "Payload Length : %x\n", + ntohs(pstIpv6Header->usPayloadLength)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "Next Header : %x\n", pstIpv6Header->ucNextHeader); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "Hop Limit : %x\n", pstIpv6Header->ucHopLimit); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "Src Address :\n"); DumpIpv6Address(pstIpv6Header->ulSrcIpAddress); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Dest Address :\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "Dest Address :\n"); DumpIpv6Address(pstIpv6Header->ulDestIpAddress); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "----Ipv6 Header End---"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "----Ipv6 Header End---"); } -- cgit v0.10.2 From 59b2bbb614ca1bd934bb0e5c615a0849d11d8858 Mon Sep 17 00:00:00 2001 From: Max Tottenham Date: Tue, 3 Apr 2012 12:35:31 +0100 Subject: Staging: bcm: IPv6Protocol.c: coding style fix Eighth patch in a series to fix coding style in IPv6Protocol.c This patch removes some uneeded braces around single line if/for statements Signed-off-by: Max Tottenham Acked-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/IPv6Protocol.c b/drivers/staging/bcm/IPv6Protocol.c index d9c9cef..1da2164 100644 --- a/drivers/staging/bcm/IPv6Protocol.c +++ b/drivers/staging/bcm/IPv6Protocol.c @@ -149,9 +149,8 @@ static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort, UCHAR *pucNextHeader = NULL; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); - if (!pucPayload || (usPayloadLength == 0)) { + if (!pucPayload || (usPayloadLength == 0)) return 0; - } *pusSrcPort = *pusDestPort = 0; ucHeaderType = ucNextHeader; @@ -280,9 +279,8 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, if (iMatchedSFQueueIndex >= NO_OF_QUEUES) { bClassificationSucceed = FALSE; } else { - if (Adapter->PackInfo[iMatchedSFQueueIndex].bActive == FALSE) { + if (Adapter->PackInfo[iMatchedSFQueueIndex].bActive == FALSE) bClassificationSucceed = FALSE; - } } } @@ -310,9 +308,8 @@ static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, /* First Convert the Ip Address in the packet to Host Endian order */ - for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { + for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) aulSrcIP[uiIpv6AddIndex] = ntohl(pstIpv6Header->ulSrcIpAddress[uiIpv6AddIndex]); - } for (uiLoopIndex = 0; uiLoopIndex < uiCountIPSrcAddresses; uiLoopIndex += uiIpv6AddrNoLongWords) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, @@ -368,9 +365,8 @@ static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, /* First Convert the Ip Address in the packet to Host Endian order */ - for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { + for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) aulDestIP[uiIpv6AddIndex] = ntohl(pstIpv6Header->ulDestIpAddress[uiIpv6AddIndex]); - } for (uiLoopIndex = 0; uiLoopIndex < uiCountIPDestinationAddresses; uiLoopIndex += uiIpv6AddrNoLongWords) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, -- cgit v0.10.2 From 3abc48ae35ef7cff845a8d57322c19cc153fb482 Mon Sep 17 00:00:00 2001 From: Martyn Welch Date: Thu, 22 Mar 2012 13:27:29 +0000 Subject: Staging: VME: Convert TSI148 to use dma_map_single The DMA functionality fails to work on some Intel based platforms. Some recent Intel platforms have an IOMMU. Transferring the DMA descriptors, which were mapped using virt_to_phys(), failed. This patch updates the driver to use dma_map_single(). Signed-off-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index f505821..cd3c821 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c @@ -1614,7 +1614,6 @@ static int tsi148_dma_list_add(struct vme_dma_list *list, struct vme_dma_pattern *pattern_attr; struct vme_dma_pci *pci_attr; struct vme_dma_vme *vme_attr; - dma_addr_t desc_ptr; int retval = 0; struct vme_bridge *tsi148_bridge; @@ -1739,9 +1738,12 @@ static int tsi148_dma_list_add(struct vme_dma_list *list, prev = list_entry(entry->list.prev, struct tsi148_dma_entry, list); /* We need the bus address for the pointer */ - desc_ptr = virt_to_bus(&entry->descriptor); - reg_split(desc_ptr, &prev->descriptor.dnlau, - &prev->descriptor.dnlal); + entry->dma_handle = dma_map_single(tsi148_bridge->parent, + &entry->descriptor, + sizeof(struct tsi148_dma_descriptor), DMA_TO_DEVICE); + + reg_split((unsigned long long)entry->dma_handle, + &prev->descriptor.dnlau, &prev->descriptor.dnlal); } return 0; @@ -1784,7 +1786,6 @@ static int tsi148_dma_list_exec(struct vme_dma_list *list) struct vme_dma_resource *ctrlr; int channel, retval = 0; struct tsi148_dma_entry *entry; - dma_addr_t bus_addr; u32 bus_addr_high, bus_addr_low; u32 val, dctlreg = 0; struct vme_bridge *tsi148_bridge; @@ -1817,11 +1818,13 @@ static int tsi148_dma_list_exec(struct vme_dma_list *list) entry = list_first_entry(&list->entries, struct tsi148_dma_entry, list); - bus_addr = virt_to_bus(&entry->descriptor); + entry->dma_handle = dma_map_single(tsi148_bridge->parent, + &entry->descriptor, + sizeof(struct tsi148_dma_descriptor), DMA_TO_DEVICE); mutex_unlock(&ctrlr->mtx); - reg_split(bus_addr, &bus_addr_high, &bus_addr_low); + reg_split(entry->dma_handle, &bus_addr_high, &bus_addr_low); iowrite32be(bus_addr_high, bridge->base + TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAU); @@ -1864,10 +1867,15 @@ static int tsi148_dma_list_empty(struct vme_dma_list *list) struct list_head *pos, *temp; struct tsi148_dma_entry *entry; + struct vme_bridge *tsi148_bridge = list->parent->parent; + /* detach and free each entry */ list_for_each_safe(pos, temp, &list->entries) { list_del(pos); entry = list_entry(pos, struct tsi148_dma_entry, list); + + dma_unmap_single(tsi148_bridge->parent, entry->dma_handle, + sizeof(struct tsi148_dma_descriptor), DMA_TO_DEVICE); kfree(entry); } diff --git a/drivers/staging/vme/bridges/vme_tsi148.h b/drivers/staging/vme/bridges/vme_tsi148.h index a3ac2fe..00b1160 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.h +++ b/drivers/staging/vme/bridges/vme_tsi148.h @@ -75,6 +75,7 @@ struct tsi148_dma_entry { */ struct tsi148_dma_descriptor descriptor; struct list_head list; + dma_addr_t dma_handle; }; /* -- cgit v0.10.2 From ac1a4f2caf7b071a56ca10a48673a37b762f7ac7 Mon Sep 17 00:00:00 2001 From: Martyn Welch Date: Thu, 22 Mar 2012 13:27:30 +0000 Subject: Staging: VME: Ensure TSI148 link list descriptors are written big endian The DMA functionality fails to work on little endian processors, such as found on x86 based platforms. The DMA engine copies the link list descriptors from memory into big endian registers. On little endian systems this results in the values being byte swapped. This patch uses standard kernel functionality to ensure that the descriptors are stored in big endian format. Signed-off-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index cd3c821..ced5942 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "../vme.h" #include "../vme_bridge.h" @@ -1415,51 +1416,55 @@ static unsigned int tsi148_master_rmw(struct vme_master_resource *image, return result; } -static int tsi148_dma_set_vme_src_attributes(struct device *dev, u32 *attr, +static int tsi148_dma_set_vme_src_attributes(struct device *dev, __be32 *attr, u32 aspace, u32 cycle, u32 dwidth) { + u32 val; + + val = be32_to_cpu(*attr); + /* Setup 2eSST speeds */ switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) { case VME_2eSST160: - *attr |= TSI148_LCSR_DSAT_2eSSTM_160; + val |= TSI148_LCSR_DSAT_2eSSTM_160; break; case VME_2eSST267: - *attr |= TSI148_LCSR_DSAT_2eSSTM_267; + val |= TSI148_LCSR_DSAT_2eSSTM_267; break; case VME_2eSST320: - *attr |= TSI148_LCSR_DSAT_2eSSTM_320; + val |= TSI148_LCSR_DSAT_2eSSTM_320; break; } /* Setup cycle types */ if (cycle & VME_SCT) - *attr |= TSI148_LCSR_DSAT_TM_SCT; + val |= TSI148_LCSR_DSAT_TM_SCT; if (cycle & VME_BLT) - *attr |= TSI148_LCSR_DSAT_TM_BLT; + val |= TSI148_LCSR_DSAT_TM_BLT; if (cycle & VME_MBLT) - *attr |= TSI148_LCSR_DSAT_TM_MBLT; + val |= TSI148_LCSR_DSAT_TM_MBLT; if (cycle & VME_2eVME) - *attr |= TSI148_LCSR_DSAT_TM_2eVME; + val |= TSI148_LCSR_DSAT_TM_2eVME; if (cycle & VME_2eSST) - *attr |= TSI148_LCSR_DSAT_TM_2eSST; + val |= TSI148_LCSR_DSAT_TM_2eSST; if (cycle & VME_2eSSTB) { dev_err(dev, "Currently not setting Broadcast Select " "Registers\n"); - *attr |= TSI148_LCSR_DSAT_TM_2eSSTB; + val |= TSI148_LCSR_DSAT_TM_2eSSTB; } /* Setup data width */ switch (dwidth) { case VME_D16: - *attr |= TSI148_LCSR_DSAT_DBW_16; + val |= TSI148_LCSR_DSAT_DBW_16; break; case VME_D32: - *attr |= TSI148_LCSR_DSAT_DBW_32; + val |= TSI148_LCSR_DSAT_DBW_32; break; default: dev_err(dev, "Invalid data width\n"); @@ -1469,31 +1474,31 @@ static int tsi148_dma_set_vme_src_attributes(struct device *dev, u32 *attr, /* Setup address space */ switch (aspace) { case VME_A16: - *attr |= TSI148_LCSR_DSAT_AMODE_A16; + val |= TSI148_LCSR_DSAT_AMODE_A16; break; case VME_A24: - *attr |= TSI148_LCSR_DSAT_AMODE_A24; + val |= TSI148_LCSR_DSAT_AMODE_A24; break; case VME_A32: - *attr |= TSI148_LCSR_DSAT_AMODE_A32; + val |= TSI148_LCSR_DSAT_AMODE_A32; break; case VME_A64: - *attr |= TSI148_LCSR_DSAT_AMODE_A64; + val |= TSI148_LCSR_DSAT_AMODE_A64; break; case VME_CRCSR: - *attr |= TSI148_LCSR_DSAT_AMODE_CRCSR; + val |= TSI148_LCSR_DSAT_AMODE_CRCSR; break; case VME_USER1: - *attr |= TSI148_LCSR_DSAT_AMODE_USER1; + val |= TSI148_LCSR_DSAT_AMODE_USER1; break; case VME_USER2: - *attr |= TSI148_LCSR_DSAT_AMODE_USER2; + val |= TSI148_LCSR_DSAT_AMODE_USER2; break; case VME_USER3: - *attr |= TSI148_LCSR_DSAT_AMODE_USER3; + val |= TSI148_LCSR_DSAT_AMODE_USER3; break; case VME_USER4: - *attr |= TSI148_LCSR_DSAT_AMODE_USER4; + val |= TSI148_LCSR_DSAT_AMODE_USER4; break; default: dev_err(dev, "Invalid address space\n"); @@ -1502,58 +1507,64 @@ static int tsi148_dma_set_vme_src_attributes(struct device *dev, u32 *attr, } if (cycle & VME_SUPER) - *attr |= TSI148_LCSR_DSAT_SUP; + val |= TSI148_LCSR_DSAT_SUP; if (cycle & VME_PROG) - *attr |= TSI148_LCSR_DSAT_PGM; + val |= TSI148_LCSR_DSAT_PGM; + + *attr = cpu_to_be32(val); return 0; } -static int tsi148_dma_set_vme_dest_attributes(struct device *dev, u32 *attr, +static int tsi148_dma_set_vme_dest_attributes(struct device *dev, __be32 *attr, u32 aspace, u32 cycle, u32 dwidth) { + u32 val; + + val = be32_to_cpu(*attr); + /* Setup 2eSST speeds */ switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) { case VME_2eSST160: - *attr |= TSI148_LCSR_DDAT_2eSSTM_160; + val |= TSI148_LCSR_DDAT_2eSSTM_160; break; case VME_2eSST267: - *attr |= TSI148_LCSR_DDAT_2eSSTM_267; + val |= TSI148_LCSR_DDAT_2eSSTM_267; break; case VME_2eSST320: - *attr |= TSI148_LCSR_DDAT_2eSSTM_320; + val |= TSI148_LCSR_DDAT_2eSSTM_320; break; } /* Setup cycle types */ if (cycle & VME_SCT) - *attr |= TSI148_LCSR_DDAT_TM_SCT; + val |= TSI148_LCSR_DDAT_TM_SCT; if (cycle & VME_BLT) - *attr |= TSI148_LCSR_DDAT_TM_BLT; + val |= TSI148_LCSR_DDAT_TM_BLT; if (cycle & VME_MBLT) - *attr |= TSI148_LCSR_DDAT_TM_MBLT; + val |= TSI148_LCSR_DDAT_TM_MBLT; if (cycle & VME_2eVME) - *attr |= TSI148_LCSR_DDAT_TM_2eVME; + val |= TSI148_LCSR_DDAT_TM_2eVME; if (cycle & VME_2eSST) - *attr |= TSI148_LCSR_DDAT_TM_2eSST; + val |= TSI148_LCSR_DDAT_TM_2eSST; if (cycle & VME_2eSSTB) { dev_err(dev, "Currently not setting Broadcast Select " "Registers\n"); - *attr |= TSI148_LCSR_DDAT_TM_2eSSTB; + val |= TSI148_LCSR_DDAT_TM_2eSSTB; } /* Setup data width */ switch (dwidth) { case VME_D16: - *attr |= TSI148_LCSR_DDAT_DBW_16; + val |= TSI148_LCSR_DDAT_DBW_16; break; case VME_D32: - *attr |= TSI148_LCSR_DDAT_DBW_32; + val |= TSI148_LCSR_DDAT_DBW_32; break; default: dev_err(dev, "Invalid data width\n"); @@ -1563,31 +1574,31 @@ static int tsi148_dma_set_vme_dest_attributes(struct device *dev, u32 *attr, /* Setup address space */ switch (aspace) { case VME_A16: - *attr |= TSI148_LCSR_DDAT_AMODE_A16; + val |= TSI148_LCSR_DDAT_AMODE_A16; break; case VME_A24: - *attr |= TSI148_LCSR_DDAT_AMODE_A24; + val |= TSI148_LCSR_DDAT_AMODE_A24; break; case VME_A32: - *attr |= TSI148_LCSR_DDAT_AMODE_A32; + val |= TSI148_LCSR_DDAT_AMODE_A32; break; case VME_A64: - *attr |= TSI148_LCSR_DDAT_AMODE_A64; + val |= TSI148_LCSR_DDAT_AMODE_A64; break; case VME_CRCSR: - *attr |= TSI148_LCSR_DDAT_AMODE_CRCSR; + val |= TSI148_LCSR_DDAT_AMODE_CRCSR; break; case VME_USER1: - *attr |= TSI148_LCSR_DDAT_AMODE_USER1; + val |= TSI148_LCSR_DDAT_AMODE_USER1; break; case VME_USER2: - *attr |= TSI148_LCSR_DDAT_AMODE_USER2; + val |= TSI148_LCSR_DDAT_AMODE_USER2; break; case VME_USER3: - *attr |= TSI148_LCSR_DDAT_AMODE_USER3; + val |= TSI148_LCSR_DDAT_AMODE_USER3; break; case VME_USER4: - *attr |= TSI148_LCSR_DDAT_AMODE_USER4; + val |= TSI148_LCSR_DDAT_AMODE_USER4; break; default: dev_err(dev, "Invalid address space\n"); @@ -1596,21 +1607,25 @@ static int tsi148_dma_set_vme_dest_attributes(struct device *dev, u32 *attr, } if (cycle & VME_SUPER) - *attr |= TSI148_LCSR_DDAT_SUP; + val |= TSI148_LCSR_DDAT_SUP; if (cycle & VME_PROG) - *attr |= TSI148_LCSR_DDAT_PGM; + val |= TSI148_LCSR_DDAT_PGM; + + *attr = cpu_to_be32(val); return 0; } /* * Add a link list descriptor to the list + * + * Note: DMA engine expects the DMA descriptor to be big endian. */ static int tsi148_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, struct vme_dma_attr *dest, size_t count) { struct tsi148_dma_entry *entry, *prev; - u32 address_high, address_low; + u32 address_high, address_low, val; struct vme_dma_pattern *pattern_attr; struct vme_dma_pci *pci_attr; struct vme_dma_vme *vme_attr; @@ -1647,34 +1662,36 @@ static int tsi148_dma_list_add(struct vme_dma_list *list, case VME_DMA_PATTERN: pattern_attr = src->private; - entry->descriptor.dsal = pattern_attr->pattern; - entry->descriptor.dsat = TSI148_LCSR_DSAT_TYP_PAT; + entry->descriptor.dsal = cpu_to_be32(pattern_attr->pattern); + + val = TSI148_LCSR_DSAT_TYP_PAT; + /* Default behaviour is 32 bit pattern */ if (pattern_attr->type & VME_DMA_PATTERN_BYTE) - entry->descriptor.dsat |= TSI148_LCSR_DSAT_PSZ; + val |= TSI148_LCSR_DSAT_PSZ; /* It seems that the default behaviour is to increment */ if ((pattern_attr->type & VME_DMA_PATTERN_INCREMENT) == 0) - entry->descriptor.dsat |= TSI148_LCSR_DSAT_NIN; - + val |= TSI148_LCSR_DSAT_NIN; + entry->descriptor.dsat = cpu_to_be32(val); break; case VME_DMA_PCI: pci_attr = src->private; reg_split((unsigned long long)pci_attr->address, &address_high, &address_low); - entry->descriptor.dsau = address_high; - entry->descriptor.dsal = address_low; - entry->descriptor.dsat = TSI148_LCSR_DSAT_TYP_PCI; + entry->descriptor.dsau = cpu_to_be32(address_high); + entry->descriptor.dsal = cpu_to_be32(address_low); + entry->descriptor.dsat = cpu_to_be32(TSI148_LCSR_DSAT_TYP_PCI); break; case VME_DMA_VME: vme_attr = src->private; reg_split((unsigned long long)vme_attr->address, &address_high, &address_low); - entry->descriptor.dsau = address_high; - entry->descriptor.dsal = address_low; - entry->descriptor.dsat = TSI148_LCSR_DSAT_TYP_VME; + entry->descriptor.dsau = cpu_to_be32(address_high); + entry->descriptor.dsal = cpu_to_be32(address_low); + entry->descriptor.dsat = cpu_to_be32(TSI148_LCSR_DSAT_TYP_VME); retval = tsi148_dma_set_vme_src_attributes( tsi148_bridge->parent, &entry->descriptor.dsat, @@ -1690,9 +1707,8 @@ static int tsi148_dma_list_add(struct vme_dma_list *list, } /* Assume last link - this will be over-written by adding another */ - entry->descriptor.dnlau = 0; - entry->descriptor.dnlal = TSI148_LCSR_DNLAL_LLA; - + entry->descriptor.dnlau = cpu_to_be32(0); + entry->descriptor.dnlal = cpu_to_be32(TSI148_LCSR_DNLAL_LLA); /* Fill out destination part */ switch (dest->type) { @@ -1701,18 +1717,18 @@ static int tsi148_dma_list_add(struct vme_dma_list *list, reg_split((unsigned long long)pci_attr->address, &address_high, &address_low); - entry->descriptor.ddau = address_high; - entry->descriptor.ddal = address_low; - entry->descriptor.ddat = TSI148_LCSR_DDAT_TYP_PCI; + entry->descriptor.ddau = cpu_to_be32(address_high); + entry->descriptor.ddal = cpu_to_be32(address_low); + entry->descriptor.ddat = cpu_to_be32(TSI148_LCSR_DDAT_TYP_PCI); break; case VME_DMA_VME: vme_attr = dest->private; reg_split((unsigned long long)vme_attr->address, &address_high, &address_low); - entry->descriptor.ddau = address_high; - entry->descriptor.ddal = address_low; - entry->descriptor.ddat = TSI148_LCSR_DDAT_TYP_VME; + entry->descriptor.ddau = cpu_to_be32(address_high); + entry->descriptor.ddal = cpu_to_be32(address_low); + entry->descriptor.ddat = cpu_to_be32(TSI148_LCSR_DDAT_TYP_VME); retval = tsi148_dma_set_vme_dest_attributes( tsi148_bridge->parent, &entry->descriptor.ddat, @@ -1728,7 +1744,7 @@ static int tsi148_dma_list_add(struct vme_dma_list *list, } /* Fill out count */ - entry->descriptor.dcnt = (u32)count; + entry->descriptor.dcnt = cpu_to_be32((u32)count); /* Add to list */ list_add_tail(&entry->list, &list->entries); @@ -1742,8 +1758,11 @@ static int tsi148_dma_list_add(struct vme_dma_list *list, &entry->descriptor, sizeof(struct tsi148_dma_descriptor), DMA_TO_DEVICE); - reg_split((unsigned long long)entry->dma_handle, - &prev->descriptor.dnlau, &prev->descriptor.dnlal); + reg_split((unsigned long long)entry->dma_handle, &address_high, + &address_low); + entry->descriptor.dnlau = cpu_to_be32(address_high); + entry->descriptor.dnlal = cpu_to_be32(address_low); + } return 0; @@ -1831,12 +1850,16 @@ static int tsi148_dma_list_exec(struct vme_dma_list *list) iowrite32be(bus_addr_low, bridge->base + TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAL); + dctlreg = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] + + TSI148_LCSR_OFFSET_DCTL); + /* Start the operation */ iowrite32be(dctlreg | TSI148_LCSR_DCTL_DGO, bridge->base + TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL); wait_event_interruptible(bridge->dma_queue[channel], tsi148_dma_busy(ctrlr->parent, channel)); + /* * Read status register, this register is valid until we kick off a * new transfer. diff --git a/drivers/staging/vme/bridges/vme_tsi148.h b/drivers/staging/vme/bridges/vme_tsi148.h index 00b1160..f5ed143 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.h +++ b/drivers/staging/vme/bridges/vme_tsi148.h @@ -56,16 +56,16 @@ struct tsi148_driver { * correctly laid out - It must also be aligned on 64-bit boundaries. */ struct tsi148_dma_descriptor { - u32 dsau; /* Source Address */ - u32 dsal; - u32 ddau; /* Destination Address */ - u32 ddal; - u32 dsat; /* Source attributes */ - u32 ddat; /* Destination attributes */ - u32 dnlau; /* Next link address */ - u32 dnlal; - u32 dcnt; /* Byte count */ - u32 ddbs; /* 2eSST Broadcast select */ + __be32 dsau; /* Source Address */ + __be32 dsal; + __be32 ddau; /* Destination Address */ + __be32 ddal; + __be32 dsat; /* Source attributes */ + __be32 ddat; /* Destination attributes */ + __be32 dnlau; /* Next link address */ + __be32 dnlal; + __be32 dcnt; /* Byte count */ + __be32 ddbs; /* 2eSST Broadcast select */ }; struct tsi148_dma_entry { -- cgit v0.10.2 From 8c287d2053c28b838de557ce5319acbd6e4bb627 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 26 Mar 2012 16:57:26 +0100 Subject: staging: comedi: amplc_dio200: separately configure ISA and PCI The amplc_dio200 driver supports both ISA and PCI cards, but currently it is only possible to select the driver if PCI is configured. This patch splits the configuration to make the ISA and PCI parts seperately selectable, and changes the driver to only include the selected ISA and/or PCI board types. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 12c691d..6edcba9 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -211,6 +211,18 @@ config COMEDI_PCM3730 To compile this driver as a module, choose M here: the module will be called pcm3730. +config COMEDI_AMPLC_DIO200_ISA + tristate "Amplicon PC212E/PC214E/PC215E/PC218E/PC272E" + select COMEDI_AMPLC_DIO200 + depends on COMEDI_ISA_DRIVERS + default N + ---help--- + Enable support for Amplicon PC212E, PC214E, PC215E, PC218E and + PC272E ISA DIO boards + + To compile this driver as a module, choose M here: the module will be + called amplc_dio200. + config COMEDI_RTI800 tristate "Analog Devices RTI-800/815 ISA card support" default N @@ -772,12 +784,12 @@ config COMEDI_ADV_PCI_DIO To compile this driver as a module, choose M here: the module will be called adv_pci_dio. -config COMEDI_AMPLC_DIO200 - tristate "Amplicon PC272E and PCI272 DIO board support" - select COMEDI_8255 +config COMEDI_AMPLC_DIO200_PCI + tristate "Amplicon PCI215 and PCI272 DIO board support" + select COMEDI_AMPLC_DIO200 default N ---help--- - Enable support for Amplicon PC272E and PCI272 DIO boards + Enable support for Amplicon PCI215 and PCI272 DIO boards. To compile this driver as a module, choose M here: the module will be called amplc_dio200. @@ -1382,3 +1394,8 @@ config COMEDI_FC To compile this driver as a module, choose M here: the module will be called comedi_fc. + +config COMEDI_AMPLC_DIO200 + def_tristate N + depends on COMEDI + select COMEDI_8255 diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 566cc44..7e8828f 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -217,6 +217,14 @@ order they appear in the channel list. #define DIO200_DRIVER_NAME "amplc_dio200" +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA_MODULE +#define CONFIG_COMEDI_AMPLC_DIO200_ISA +#endif + +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI_MODULE +#define CONFIG_COMEDI_AMPLC_DIO200_PCI +#endif + /* PCI IDs */ #define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a @@ -274,10 +282,14 @@ enum dio200_model { }; enum dio200_layout { +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA pc212_layout, pc214_layout, +#endif pc215_layout, +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA pc218_layout, +#endif pc272_layout }; @@ -290,6 +302,7 @@ struct dio200_board { }; static const struct dio200_board dio200_boards[] = { +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA { .name = "pc212e", .bustype = isa_bustype, @@ -308,15 +321,6 @@ static const struct dio200_board dio200_boards[] = { .model = pc215e_model, .layout = pc215_layout, }, -#ifdef CONFIG_COMEDI_PCI - { - .name = "pci215", - .devid = PCI_DEVICE_ID_AMPLICON_PCI215, - .bustype = pci_bustype, - .model = pci215_model, - .layout = pc215_layout, - }, -#endif { .name = "pc218e", .bustype = isa_bustype, @@ -329,7 +333,15 @@ static const struct dio200_board dio200_boards[] = { .model = pc272e_model, .layout = pc272_layout, }, -#ifdef CONFIG_COMEDI_PCI +#endif +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI + { + .name = "pci215", + .devid = PCI_DEVICE_ID_AMPLICON_PCI215, + .bustype = pci_bustype, + .model = pci215_model, + .layout = pc215_layout, + }, { .name = "pci272", .devid = PCI_DEVICE_ID_AMPLICON_PCI272, @@ -337,8 +349,6 @@ static const struct dio200_board dio200_boards[] = { .model = pci272_model, .layout = pc272_layout, }, -#endif -#ifdef CONFIG_COMEDI_PCI { .name = DIO200_DRIVER_NAME, .devid = PCI_DEVICE_ID_INVALID, @@ -367,6 +377,7 @@ struct dio200_layout_struct { }; static const struct dio200_layout_struct dio200_layouts[] = { +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA [pc212_layout] = { .n_subdevs = 6, .sdtype = {sd_8255, sd_8254, sd_8254, sd_8254, @@ -385,6 +396,7 @@ static const struct dio200_layout_struct dio200_layouts[] = { .has_int_sce = 0, .has_clk_gat_sce = 0, }, +#endif [pc215_layout] = { .n_subdevs = 5, .sdtype = {sd_8255, sd_8255, sd_8254, @@ -394,6 +406,7 @@ static const struct dio200_layout_struct dio200_layouts[] = { .has_int_sce = 1, .has_clk_gat_sce = 1, }, +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA [pc218_layout] = { .n_subdevs = 7, .sdtype = {sd_8254, sd_8254, sd_8255, sd_8254, @@ -405,6 +418,7 @@ static const struct dio200_layout_struct dio200_layouts[] = { .has_int_sce = 1, .has_clk_gat_sce = 1, }, +#endif [pc272_layout] = { .n_subdevs = 4, .sdtype = {sd_8255, sd_8255, sd_8255, @@ -419,7 +433,7 @@ static const struct dio200_layout_struct dio200_layouts[] = { * PCI driver table. */ -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215) }, { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272) }, @@ -427,7 +441,7 @@ static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = { }; MODULE_DEVICE_TABLE(pci, dio200_pci_table); -#endif /* CONFIG_COMEDI_PCI */ +#endif /* CONFIG_COMEDI_AMPLC_DIO200_PCI */ /* * Useful for shorthand access to the particular board structure @@ -441,7 +455,7 @@ MODULE_DEVICE_TABLE(pci, dio200_pci_table); feel free to suggest moving the variable to the struct comedi_device struct. */ struct dio200_private { -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI struct pci_dev *pci_dev; /* PCI device */ #endif int intr_sd; @@ -490,7 +504,7 @@ static struct comedi_driver driver_amplc_dio200 = { .num_names = ARRAY_SIZE(dio200_boards), }; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI static int __devinit driver_amplc_dio200_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) @@ -549,7 +563,7 @@ module_exit(driver_amplc_dio200_cleanup_module); * This function looks for a PCI device matching the requested board name, * bus and slot. */ -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI static int dio200_find_pci(struct comedi_device *dev, int bus, int slot, struct pci_dev **pci_dev_p) @@ -611,6 +625,7 @@ dio200_find_pci(struct comedi_device *dev, int bus, int slot, * This function checks and requests an I/O region, reporting an error * if there is a conflict. */ +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA static int dio200_request_region(unsigned minor, unsigned long from, unsigned long extent) { @@ -621,6 +636,7 @@ dio200_request_region(unsigned minor, unsigned long from, unsigned long extent) } return 0; } +#endif /* * 'insn_bits' function for an 'INTERRUPT' subdevice. @@ -1332,7 +1348,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; unsigned long iobase = 0; unsigned int irq = 0; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI struct pci_dev *pci_dev = NULL; int bus = 0, slot = 0; #endif @@ -1354,12 +1370,14 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Process options. */ switch (thisboard->bustype) { +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA case isa_bustype: iobase = it->options[0]; irq = it->options[1]; share_irq = 0; break; -#ifdef CONFIG_COMEDI_PCI +#endif +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI case pci_bustype: bus = it->options[0]; slot = it->options[1]; @@ -1382,7 +1400,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->intr_sd = -1; /* Enable device and reserve I/O spaces. */ -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI if (pci_dev) { ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME); if (ret < 0) { @@ -1396,9 +1414,11 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) } else #endif { +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE); if (ret < 0) return ret; +#endif } dev->iobase = iobase; @@ -1474,12 +1494,19 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) } printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name); - if (thisboard->bustype == isa_bustype) { + switch (thisboard->bustype) { +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA + case isa_bustype: printk("(base %#lx) ", iobase); - } else { -#ifdef CONFIG_COMEDI_PCI + break; +#endif +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI + case pci_bustype: printk("(pci %s) ", pci_name(pci_dev)); + break; #endif + default: + break; } if (irq) printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE")); @@ -1529,7 +1556,7 @@ static int dio200_detach(struct comedi_device *dev) } } if (devpriv) { -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI if (devpriv->pci_dev) { if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); @@ -1537,8 +1564,10 @@ static int dio200_detach(struct comedi_device *dev) } else #endif { +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA if (dev->iobase) release_region(dev->iobase, DIO200_IO_SIZE); +#endif } } if (dev->board_name) -- cgit v0.10.2 From 717ab674e261932ca642af838ef9eea111623682 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 26 Mar 2012 16:57:27 +0100 Subject: staging: comedi: amplc_pc236: separately configure ISA and PCI The amplc_pc236 driver supports both ISA and PCI cards, but currently it is only possible to select the driver if PCI is configured. This patch splits the configuration to make the ISA and PCI parts seperately selectable, and changes the driver to only include the selected ISA and/or PCI board types. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 6edcba9..df6eb2a 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -223,6 +223,16 @@ config COMEDI_AMPLC_DIO200_ISA To compile this driver as a module, choose M here: the module will be called amplc_dio200. +config COMEDI_AMPLC_PC236_ISA + tristate "Amplicon PC36AT DIO board support" + select COMEDI_AMPLC_PC236 + default N + ---help--- + Enable support for Amplicon PC36AT ISA DIO board. + + To compile this driver as a module, choose M here: the module will be + called amplc_pc236. + config COMEDI_RTI800 tristate "Analog Devices RTI-800/815 ISA card support" default N @@ -794,12 +804,12 @@ config COMEDI_AMPLC_DIO200_PCI To compile this driver as a module, choose M here: the module will be called amplc_dio200. -config COMEDI_AMPLC_PC236 - tristate "Amplicon PC36AT and PCI236 DIO board support" - select COMEDI_8255 +config COMEDI_AMPLC_PC236_PCI + tristate "Amplicon PCI236 DIO board support" + select COMEDI_AMPLC_PC236 default N ---help--- - Enable support for Amplicon PC36AT and PCI236 DIO boards + Enable support for Amplicon PCI236 DIO board. To compile this driver as a module, choose M here: the module will be called amplc_pc236. @@ -1399,3 +1409,8 @@ config COMEDI_AMPLC_DIO200 def_tristate N depends on COMEDI select COMEDI_8255 + +config COMEDI_AMPLC_PC236 + def_tristate N + depends on COMEDI + select COMEDI_8255 diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 7972cad..b15d0ee 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -63,6 +63,14 @@ unused. #define PC236_DRIVER_NAME "amplc_pc236" +#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA_MODULE +#define CONFIG_COMEDI_AMPLC_PC236_ISA +#endif + +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI_MODULE +#define CONFIG_COMEDI_AMPLC_PC236_PCI +#endif + /* PCI236 PCI configuration register information */ #define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI236 0x0009 @@ -106,13 +114,15 @@ struct pc236_board { enum pc236_model model; }; static const struct pc236_board pc236_boards[] = { +#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA { .name = "pc36at", .fancy_name = "PC36AT", .bustype = isa_bustype, .model = pc36at_model, }, -#ifdef CONFIG_COMEDI_PCI +#endif +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI { .name = "pci236", .fancy_name = "PCI236", @@ -120,8 +130,6 @@ static const struct pc236_board pc236_boards[] = { .bustype = pci_bustype, .model = pci236_model, }, -#endif -#ifdef CONFIG_COMEDI_PCI { .name = PC236_DRIVER_NAME, .fancy_name = PC236_DRIVER_NAME, @@ -132,14 +140,14 @@ static const struct pc236_board pc236_boards[] = { #endif }; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI static DEFINE_PCI_DEVICE_TABLE(pc236_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI236) }, {0} }; MODULE_DEVICE_TABLE(pci, pc236_pci_table); -#endif /* CONFIG_COMEDI_PCI */ +#endif /* CONFIG_COMEDI_AMPLC_PC236_PCI */ /* * Useful for shorthand access to the particular board structure @@ -151,7 +159,7 @@ MODULE_DEVICE_TABLE(pci, pc236_pci_table); feel free to suggest moving the variable to the struct comedi_device struct. */ struct pc236_private { -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI /* PCI device */ struct pci_dev *pci_dev; unsigned long lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */ @@ -179,7 +187,7 @@ static struct comedi_driver driver_amplc_pc236 = { .num_names = ARRAY_SIZE(pc236_boards), }; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI static int __devinit driver_amplc_pc236_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) @@ -234,8 +242,10 @@ module_init(driver_amplc_pc236_init_module); module_exit(driver_amplc_pc236_cleanup_module); #endif +#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA static int pc236_request_region(unsigned minor, unsigned long from, unsigned long extent); +#endif static void pc236_intr_disable(struct comedi_device *dev); static void pc236_intr_enable(struct comedi_device *dev); static int pc236_intr_check(struct comedi_device *dev); @@ -255,7 +265,7 @@ static irqreturn_t pc236_interrupt(int irq, void *d); * This function looks for a PCI device matching the requested board name, * bus and slot. */ -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI static int pc236_find_pci(struct comedi_device *dev, int bus, int slot, struct pci_dev **pci_dev_p) @@ -324,7 +334,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; unsigned long iobase = 0; unsigned int irq = 0; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI struct pci_dev *pci_dev = NULL; int bus = 0, slot = 0; #endif @@ -345,12 +355,14 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* Process options. */ switch (thisboard->bustype) { +#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA case isa_bustype: iobase = it->options[0]; irq = it->options[1]; share_irq = 0; break; -#ifdef CONFIG_COMEDI_PCI +#endif +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI case pci_bustype: bus = it->options[0]; slot = it->options[1]; @@ -361,7 +373,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; devpriv->pci_dev = pci_dev; break; -#endif /* CONFIG_COMEDI_PCI */ +#endif default: printk(KERN_ERR "comedi%d: %s: BUG! cannot determine board type!\n", @@ -376,7 +388,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = thisboard->name; /* Enable device and reserve I/O spaces. */ -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI if (pci_dev) { ret = comedi_pci_enable(pci_dev, PC236_DRIVER_NAME); @@ -392,9 +404,11 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) } else #endif { +#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA ret = pc236_request_region(dev->minor, iobase, PC236_IO_SIZE); if (ret < 0) return ret; +#endif } dev->iobase = iobase; @@ -439,12 +453,19 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) } } printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name); - if (thisboard->bustype == isa_bustype) { + switch (thisboard->bustype) { +#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA + case isa_bustype: printk("(base %#lx) ", iobase); - } else { -#ifdef CONFIG_COMEDI_PCI + break; +#endif +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI + case pci_bustype: printk("(pci %s) ", pci_name(pci_dev)); + break; #endif + default: + break; } if (irq) printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE")); @@ -476,7 +497,7 @@ static int pc236_detach(struct comedi_device *dev) if (dev->subdevices) subdev_8255_cleanup(dev, dev->subdevices + 0); if (devpriv) { -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI if (devpriv->pci_dev) { if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); @@ -484,8 +505,10 @@ static int pc236_detach(struct comedi_device *dev) } else #endif { +#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA if (dev->iobase) release_region(dev->iobase, PC236_IO_SIZE); +#endif } } if (dev->board_name) { @@ -499,6 +522,7 @@ static int pc236_detach(struct comedi_device *dev) * This function checks and requests an I/O region, reporting an error * if there is a conflict. */ +#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA static int pc236_request_region(unsigned minor, unsigned long from, unsigned long extent) { @@ -509,6 +533,7 @@ static int pc236_request_region(unsigned minor, unsigned long from, } return 0; } +#endif /* * This function is called to mark the interrupt as disabled (no command @@ -521,7 +546,7 @@ static void pc236_intr_disable(struct comedi_device *dev) spin_lock_irqsave(&dev->spinlock, flags); devpriv->enable_irq = 0; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI if (devpriv->lcr_iobase) outl(PCI236_INTR_DISABLE, devpriv->lcr_iobase + PLX9052_INTCSR); #endif @@ -539,7 +564,7 @@ static void pc236_intr_enable(struct comedi_device *dev) spin_lock_irqsave(&dev->spinlock, flags); devpriv->enable_irq = 1; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI if (devpriv->lcr_iobase) outl(PCI236_INTR_ENABLE, devpriv->lcr_iobase + PLX9052_INTCSR); #endif @@ -561,7 +586,7 @@ static int pc236_intr_check(struct comedi_device *dev) spin_lock_irqsave(&dev->spinlock, flags); if (devpriv->enable_irq) { retval = 1; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI if (devpriv->lcr_iobase) { if ((inl(devpriv->lcr_iobase + PLX9052_INTCSR) & PLX9052_INTCSR_LI1STAT_MASK) -- cgit v0.10.2 From 3e6be97ebbb0b45bb834670a45b343383d6de97f Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 26 Mar 2012 16:57:28 +0100 Subject: staging: comedi: amplc_pc263: separately configure ISA and PCI The amplc_pc263 driver supports both ISA and PCI cards, but currently it is only possible to select the driver if PCI is configured. This patch splits the configuration to make the ISA and PCI parts seperately selectable, and changes the driver to only include the selected ISA and/or PCI board types. Also fix a conditionally mismatched brace in pc263_detach(). Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index df6eb2a..391a713 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -233,6 +233,16 @@ config COMEDI_AMPLC_PC236_ISA To compile this driver as a module, choose M here: the module will be called amplc_pc236. +config COMEDI_AMPLC_PC263_ISA + tristate "Amplicon PC263 relay board support" + select COMEDI_AMPLC_PC263 + default N + ---help--- + Enable support for Amplicon PC263 ISA relay board. + + To compile this driver as a module, choose M here: the module will be + called amplc_pc263. + config COMEDI_RTI800 tristate "Analog Devices RTI-800/815 ISA card support" default N @@ -814,11 +824,12 @@ config COMEDI_AMPLC_PC236_PCI To compile this driver as a module, choose M here: the module will be called amplc_pc236. -config COMEDI_AMPLC_PC263 - tristate "Amplicon PC263 and PCI263 relay board support" +config COMEDI_AMPLC_PC263_PCI + tristate "Amplicon PCI263 relay board support" + select COMEDI_AMPLC_PC263 default N ---help--- - Enable support for Amplicon PC263 and PCI263 relay boards + Enable support for Amplicon PCI263 relay board. To compile this driver as a module, choose M here: the module will be called amplc_pc263. @@ -1414,3 +1425,7 @@ config COMEDI_AMPLC_PC236 def_tristate N depends on COMEDI select COMEDI_8255 + +config COMEDI_AMPLC_PC263 + def_tristate N + depends on COMEDI diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 191ac0d..0f761c5 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -50,6 +50,14 @@ The state of the outputs can be read. #define PC263_DRIVER_NAME "amplc_pc263" +#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA_MODULE +#define CONFIG_COMEDI_AMPLC_PC263_ISA +#endif + +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI_MODULE +#define CONFIG_COMEDI_AMPLC_PC263_PCI +#endif + /* PCI263 PCI configuration register information */ #define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI263 0x000c @@ -73,13 +81,15 @@ struct pc263_board { enum pc263_model model; }; static const struct pc263_board pc263_boards[] = { +#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA { .name = "pc263", .fancy_name = "PC263", .bustype = isa_bustype, .model = pc263_model, }, -#ifdef CONFIG_COMEDI_PCI +#endif +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI { .name = "pci263", .fancy_name = "PCI263", @@ -87,8 +97,6 @@ static const struct pc263_board pc263_boards[] = { .bustype = pci_bustype, .model = pci263_model, }, -#endif -#ifdef CONFIG_COMEDI_PCI { .name = PC263_DRIVER_NAME, .fancy_name = PC263_DRIVER_NAME, @@ -99,14 +107,14 @@ static const struct pc263_board pc263_boards[] = { #endif }; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI static DEFINE_PCI_DEVICE_TABLE(pc263_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI263) }, {0} }; MODULE_DEVICE_TABLE(pci, pc263_pci_table); -#endif /* CONFIG_COMEDI_PCI */ +#endif /* CONFIG_COMEDI_AMPLC_PC263_PCI */ /* * Useful for shorthand access to the particular board structure @@ -117,14 +125,14 @@ MODULE_DEVICE_TABLE(pci, pc263_pci_table); several hardware drivers keep similar information in this structure, feel free to suggest moving the variable to the struct comedi_device struct. */ -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI struct pc263_private { /* PCI device. */ struct pci_dev *pci_dev; }; #define devpriv ((struct pc263_private *)dev->private) -#endif /* CONFIG_COMEDI_PCI */ +#endif /* CONFIG_COMEDI_AMPLC_PC263_PCI */ /* * The struct comedi_driver structure tells the Comedi core module @@ -144,8 +152,10 @@ static struct comedi_driver driver_amplc_pc263 = { .num_names = ARRAY_SIZE(pc263_boards), }; +#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA static int pc263_request_region(unsigned minor, unsigned long from, unsigned long extent); +#endif static int pc263_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); @@ -157,7 +167,7 @@ static int pc263_dio_insn_config(struct comedi_device *dev, * This function looks for a PCI device matching the requested board name, * bus and slot. */ -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI static int pc263_find_pci(struct comedi_device *dev, int bus, int slot, struct pci_dev **pci_dev_p) @@ -225,7 +235,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; unsigned long iobase = 0; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI struct pci_dev *pci_dev = NULL; int bus = 0, slot = 0; #endif @@ -237,7 +247,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) * Allocate the private structure area. alloc_private() is a * convenient macro defined in comedidev.h. */ -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI ret = alloc_private(dev, sizeof(struct pc263_private)); if (ret < 0) { printk(KERN_ERR "comedi%d: error! out of memory!\n", @@ -247,10 +257,12 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) #endif /* Process options. */ switch (thisboard->bustype) { +#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA case isa_bustype: iobase = it->options[0]; break; -#ifdef CONFIG_COMEDI_PCI +#endif +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI case pci_bustype: bus = it->options[0]; slot = it->options[1]; @@ -260,7 +272,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; devpriv->pci_dev = pci_dev; break; -#endif /* CONFIG_COMEDI_PCI */ +#endif default: printk(KERN_ERR "comedi%d: %s: BUG! cannot determine board type!\n", @@ -275,7 +287,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = thisboard->name; /* Enable device and reserve I/O spaces. */ -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI if (pci_dev) { ret = comedi_pci_enable(pci_dev, PC263_DRIVER_NAME); if (ret < 0) { @@ -289,9 +301,11 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) } else #endif { +#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA ret = pc263_request_region(dev->minor, iobase, PC263_IO_SIZE); if (ret < 0) return ret; +#endif } dev->iobase = iobase; @@ -322,12 +336,18 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->state = s->state | (inb(dev->iobase) << 8); printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name); - if (thisboard->bustype == isa_bustype) { + switch (thisboard->bustype) { +#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA + case isa_bustype: printk("(base %#lx) ", iobase); - } else { -#ifdef CONFIG_COMEDI_PCI + break; +#endif +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI printk("(pci %s) ", pci_name(pci_dev)); + break; #endif + default: + break; } printk("attached\n"); @@ -348,10 +368,11 @@ static int pc263_detach(struct comedi_device *dev) printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor, PC263_DRIVER_NAME); -#ifdef CONFIG_COMEDI_PCI - if (devpriv) { +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI + if (devpriv) #endif -#ifdef CONFIG_COMEDI_PCI + { +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI if (devpriv->pci_dev) { if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); @@ -359,8 +380,10 @@ static int pc263_detach(struct comedi_device *dev) } else #endif { +#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA if (dev->iobase) release_region(dev->iobase, PC263_IO_SIZE); +#endif } } if (dev->board_name) { @@ -374,6 +397,7 @@ static int pc263_detach(struct comedi_device *dev) * This function checks and requests an I/O region, reporting an error * if there is a conflict. */ +#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA static int pc263_request_region(unsigned minor, unsigned long from, unsigned long extent) { @@ -384,6 +408,7 @@ static int pc263_request_region(unsigned minor, unsigned long from, } return 0; } +#endif /* DIO devices are slightly special. Although it is possible to * implement the insn_read/insn_write interface, it is much more @@ -429,7 +454,7 @@ static int pc263_dio_insn_config(struct comedi_device *dev, * A convenient macro that defines init_module() and cleanup_module(), * as necessary. */ -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI static int __devinit driver_amplc_pc263_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) -- cgit v0.10.2 From 2e3c024df12adf8a4c44d0d21d5c8edcdf083209 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 26 Mar 2012 16:57:29 +0100 Subject: staging: comedi: das08: separately configure ISA and PCI The das08 driver supports both ISA and PCI cards, but currently is configured outside the ISA and PCI comedi driver sections. The module is also used by the das08_cs driver. This patch splits the configuration to make the ISA and PCI parts separately selectable, and changes the driver to only include the selected ISA and/or PCI board types. Also, if neither the ISA or PCI parts are selected, and the module is only needed for the das08_cs driver, don't register the driver as a comedi driver as it doesn't have any boards to support. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 391a713..9037d02 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -272,6 +272,20 @@ config COMEDI_DAS16M1 To compile this driver as a module, choose M here: the module will be called das16m1. +config COMEDI_DAS08_ISA + tristate "DAS-08 compatible ISA and PC/104 card support" + select COMEDI_DAS08 + default N + ---help--- + Enable support for Keithley Metrabyte/ComputerBoards DAS08 + and compatible ISA and PC/104 cards: + Keithley Metrabyte/ComputerBoards DAS08, DAS08-PGM, DAS08-PGH, + DAS08-PGL, DAS08-AOH, DAS08-AOL, DAS08-AOM, DAS08/JR-AO, + DAS08/JR-16-AO, PC104-DAS08, DAS08/JR/16. + + To compile this driver as a module, choose M here: the module will be + called das08. + config COMEDI_DAS16 tristate "DAS-16 compatible ISA and PC/104 card support" select COMEDI_8255 @@ -864,6 +878,16 @@ config COMEDI_CONTEC_PCI_DIO To compile this driver as a module, choose M here: the module will be called contec_pci_dio. +config COMEDI_DAS08_PCI + tristate "DAS-08 PCI support" + select COMEDI_DAS08 + default N + ---help--- + Enable support for PCI DAS-08 cards. + + To compile this driver as a module, choose M here: the module will be + called das08. + config COMEDI_DT3000 tristate "Data Translation DT3000 series support" default N @@ -1390,20 +1414,6 @@ config COMEDI_8255 To compile this driver as a module, choose M here: the module will be called 8255. -config COMEDI_DAS08 - tristate "DAS-08 compatible support" - depends on COMEDI - select COMEDI_8255 - default N - ---help--- - Enable support for DAS08 and compatible ISA, PC/104 and PCI cards. - - Note that PCMCIA DAS08 cards are not directly supported by this - driver, and need a separate driver as a wrapper. - - To compile this driver as a module, choose M here: the module will be - called das08. - config COMEDI_FC tristate "Comedi shared functions for low-level driver support" depends on COMEDI @@ -1429,3 +1439,8 @@ config COMEDI_AMPLC_PC236 config COMEDI_AMPLC_PC263 def_tristate N depends on COMEDI + +config COMEDI_DAS08 + def_tristate N + depends on COMEDI + select COMEDI_8255 diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index c2dd0ed..05a8d0c 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -61,6 +61,20 @@ #define DRV_NAME "das08" +#ifdef CONFIG_COMEDI_DAS08_ISA_MODULE +#define CONFIG_COMEDI_DAS08_ISA +#endif +#ifdef CONFIG_COMEDI_DAS08_PCI_MODULE +#define CONFIG_COMEDI_DAS08_PCI +#endif +#ifdef CONFIG_COMEDI_DAS08_CS_MODULE +#define CONFIG_COMEDI_DAS08_CS +#endif + +#if defined(CONFIG_COMEDI_DAS08_ISA) || defined(CONFIG_COMEDI_DAS08_PCI) +#define DO_COMEDI_DRIVER_REGISTER +#endif + #define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307 #define PCI_DEVICE_ID_PCIDAS08 0x29 #define PCIDAS08_SIZE 0x54 @@ -160,6 +174,7 @@ static int das08_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); static int das08_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); +#ifdef CONFIG_COMEDI_DAS08_ISA static int das08jr_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); @@ -172,6 +187,7 @@ static int das08jr_ao_winsn(struct comedi_device *dev, static int das08ao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); +#endif static void i8254_set_mode_low(unsigned int base, int channel, unsigned int mode); @@ -253,7 +269,9 @@ static const int *const das08_gainlists[] = { das08_pgm_gainlist, }; +#ifdef DO_COMEDI_DRIVER_REGISTER static const struct das08_board_struct das08_boards[] = { +#ifdef CONFIG_COMEDI_DAS08_ISA { .name = "isa-das08", /* cio-das08.pdf */ .bustype = isa, @@ -395,25 +413,6 @@ static const struct das08_board_struct das08_boards[] = { .i8254_offset = 0x04, .iosize = 16, /* unchecked */ }, -#ifdef CONFIG_COMEDI_PCI - { - .name = "das08", /* pci-das08 */ - .id = PCI_DEVICE_ID_PCIDAS08, - .bustype = pci, - .ai = das08_ai_rinsn, - .ai_nbits = 12, - .ai_pg = das08_bipolar5, - .ai_encoding = das08_encode12, - .ao = NULL, - .ao_nbits = 0, - .di = das08_di_rbits, - .do_ = das08_do_wbits, - .do_nchan = 4, - .i8255_offset = 0, - .i8254_offset = 4, - .iosize = 8, - }, -#endif { .name = "pc104-das08", .bustype = pc104, @@ -462,9 +461,30 @@ static const struct das08_board_struct das08_boards[] = { .name = "das08-pga-g2", /* a KM board */ }, #endif +#endif /* CONFIG_COMEDI_DAS08_ISA */ +#ifdef CONFIG_COMEDI_DAS08_PCI + { + .name = "das08", /* pci-das08 */ + .id = PCI_DEVICE_ID_PCIDAS08, + .bustype = pci, + .ai = das08_ai_rinsn, + .ai_nbits = 12, + .ai_pg = das08_bipolar5, + .ai_encoding = das08_encode12, + .ao = NULL, + .ao_nbits = 0, + .di = das08_di_rbits, + .do_ = das08_do_wbits, + .do_nchan = 4, + .i8255_offset = 0, + .i8254_offset = 4, + .iosize = 8, + }, +#endif /* CONFIG_COMEDI_DAS08_PCI */ }; +#endif /* DO_COMEDI_DRIVER_REGISTER */ -#ifdef CONFIG_COMEDI_PCMCIA +#ifdef CONFIG_COMEDI_DAS08_CS struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS] = { { .name = "pcm-das08", @@ -504,7 +524,7 @@ struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS] = { }; #endif -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_DAS08_PCI static DEFINE_PCI_DEVICE_TABLE(das08_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, PCI_DEVICE_ID_PCIDAS08) }, {0} @@ -619,6 +639,7 @@ static int das08_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, return 2; } +#ifdef CONFIG_COMEDI_DAS08_ISA static int das08jr_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -628,7 +649,9 @@ static int das08jr_di_rbits(struct comedi_device *dev, return 2; } +#endif +#ifdef CONFIG_COMEDI_DAS08_ISA static int das08jr_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -643,7 +666,9 @@ static int das08jr_do_wbits(struct comedi_device *dev, return 2; } +#endif +#ifdef CONFIG_COMEDI_DAS08_ISA static int das08jr_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -672,6 +697,7 @@ static int das08jr_ao_winsn(struct comedi_device *dev, return n; } +#endif /* * @@ -679,6 +705,7 @@ static int das08jr_ao_winsn(struct comedi_device *dev, * a different method to force an update. * */ +#ifdef CONFIG_COMEDI_DAS08_ISA static int das08ao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -707,6 +734,7 @@ static int das08ao_ao_winsn(struct comedi_device *dev, return n; } +#endif static unsigned int i8254_read_channel_low(unsigned int base, int chan) { @@ -842,6 +870,7 @@ static int das08_counter_config(struct comedi_device *dev, return 2; } +#ifdef DO_COMEDI_DRIVER_REGISTER static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it); static struct comedi_driver driver_das08 = { @@ -853,6 +882,7 @@ static struct comedi_driver driver_das08 = { .num_names = sizeof(das08_boards) / sizeof(struct das08_board_struct), .offset = sizeof(struct das08_board_struct), }; +#endif int das08_common_attach(struct comedi_device *dev, unsigned long iobase) { @@ -972,11 +1002,12 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) } EXPORT_SYMBOL_GPL(das08_common_attach); +#ifdef DO_COMEDI_DRIVER_REGISTER static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) { int ret; unsigned long iobase; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_DAS08_PCI unsigned long pci_iobase = 0; struct pci_dev *pdev = NULL; #endif @@ -986,9 +1017,9 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; printk(KERN_INFO "comedi%d: das08: ", dev->minor); +#ifdef CONFIG_COMEDI_DAS08_PCI /* deal with a pci board */ if (thisboard->bustype == pci) { -#ifdef CONFIG_COMEDI_PCI if (it->options[0] || it->options[1]) { printk("bus %i slot %i ", it->options[0], it->options[1]); @@ -1037,17 +1068,16 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Enable local interrupt 1 and pci interrupt */ outw(INTR1_ENABLE | PCI_INTR_ENABLE, pci_iobase + INTCSR); #endif -#else /* CONFIG_COMEDI_PCI */ - printk(KERN_ERR "this driver has not been built with PCI support.\n"); - return -EINVAL; -#endif /* CONFIG_COMEDI_PCI */ - } else { + } else +#endif /* CONFIG_COMEDI_DAS08_PCI */ + { iobase = it->options[0]; } printk(KERN_INFO "\n"); return das08_common_attach(dev, iobase); } +#endif /* DO_COMEDI_DRIVER_REGISTER */ int das08_common_detach(struct comedi_device *dev) @@ -1062,7 +1092,7 @@ int das08_common_detach(struct comedi_device *dev) if (dev->iobase) release_region(dev->iobase, thisboard->iosize); } -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_DAS08_PCI if (devpriv) { if (devpriv->pdev) { if (devpriv->pci_iobase) @@ -1077,7 +1107,7 @@ int das08_common_detach(struct comedi_device *dev) } EXPORT_SYMBOL_GPL(das08_common_detach); -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_DAS08_PCI static int __devinit driver_das08_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { @@ -1094,43 +1124,38 @@ static struct pci_driver driver_das08_pci_driver = { .probe = &driver_das08_pci_probe, .remove = __devexit_p(&driver_das08_pci_remove) }; +#endif /* CONFIG_COMEDI_DAS08_PCI */ static int __init driver_das08_init_module(void) { - int retval; + int retval = 0; +#ifdef DO_COMEDI_DRIVER_REGISTER retval = comedi_driver_register(&driver_das08); if (retval < 0) return retval; - +#endif +#ifdef CONFIG_COMEDI_DAS08_PCI driver_das08_pci_driver.name = (char *)driver_das08.driver_name; - return pci_register_driver(&driver_das08_pci_driver); + retval = pci_register_driver(&driver_das08_pci_driver); +#endif + return retval; } static void __exit driver_das08_cleanup_module(void) { +#ifdef CONFIG_COMEDI_DAS08_PCI pci_unregister_driver(&driver_das08_pci_driver); +#endif +#ifdef DO_COMEDI_DRIVER_REGISTER comedi_driver_unregister(&driver_das08); +#endif } module_init(driver_das08_init_module); module_exit(driver_das08_cleanup_module); -#else -static int __init driver_das08_init_module(void) -{ - return comedi_driver_register(&driver_das08); -} - -static void __exit driver_das08_cleanup_module(void) -{ - comedi_driver_unregister(&driver_das08); -} - -module_init(driver_das08_init_module); -module_exit(driver_das08_cleanup_module); -#endif -#ifdef CONFIG_COMEDI_PCMCIA +#ifdef CONFIG_COMEDI_DAS08_CS EXPORT_SYMBOL_GPL(das08_cs_boards); #endif -- cgit v0.10.2 From 4c093a6dc2240fd54d71a25b284e02d51509e430 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 30 Mar 2012 17:14:56 +0100 Subject: staging: comedi: pass 'struct comedi_driver *' to comedi_..._auto_config The comedi_pci_auto_config() and comedi_usb_auto_config() functions currently take a board name parameter which is actually a driver name parameter. Replace it with a pointer to the struct comedi_driver. This will allow comedi_pci_auto_config() and comedi_usb_auto_config() to call bus-type-specific auto-configuration hooks in the struct comedi_driver if they exist (they don't yet). The idea is that these bus-type-specific auto-configuration hooks won't have to search the bus for the device being auto-configured like 'attach()' hook has to. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 7a0d4bc..7e65add 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -456,10 +456,12 @@ static inline void *comedi_aux_data(int options[], int n) int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s); void comedi_free_subdevice_minor(struct comedi_subdevice *s); -int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name); +int comedi_pci_auto_config(struct pci_dev *pcidev, + struct comedi_driver *driver); void comedi_pci_auto_unconfig(struct pci_dev *pcidev); struct usb_device; /* forward declaration */ -int comedi_usb_auto_config(struct usb_device *usbdev, const char *board_name); +int comedi_usb_auto_config(struct usb_device *usbdev, + struct comedi_driver *driver); void comedi_usb_auto_unconfig(struct usb_device *usbdev); #ifdef CONFIG_COMEDI_PCI_DRIVERS diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index bf185e2..9dd2da1 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -874,7 +874,7 @@ static void comedi_auto_unconfig(struct device *hardware_device) kfree(minor); } -int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name) +int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver) { int options[2]; @@ -883,7 +883,7 @@ int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name) /* pci slot */ options[1] = PCI_SLOT(pcidev->devfn); - return comedi_auto_config(&pcidev->dev, board_name, + return comedi_auto_config(&pcidev->dev, driver->driver_name, options, ARRAY_SIZE(options)); } EXPORT_SYMBOL_GPL(comedi_pci_auto_config); @@ -894,10 +894,11 @@ void comedi_pci_auto_unconfig(struct pci_dev *pcidev) } EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig); -int comedi_usb_auto_config(struct usb_device *usbdev, const char *board_name) +int comedi_usb_auto_config(struct usb_device *usbdev, + struct comedi_driver *driver) { BUG_ON(usbdev == NULL); - return comedi_auto_config(&usbdev->dev, board_name, NULL, 0); + return comedi_auto_config(&usbdev->dev, driver->driver_name, NULL, 0); } EXPORT_SYMBOL_GPL(comedi_usb_auto_config); diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index ca5bd9b8..2f341a3 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -2543,7 +2543,7 @@ static struct comedi_driver driver_addi = { static int __devinit driver_addi_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_addi.driver_name); + return comedi_pci_auto_config(dev, &driver_addi); } static void __devexit driver_addi_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 4fc9e85..de0ec80 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -121,7 +121,7 @@ static struct comedi_driver driver_pci6208 = { static int __devinit driver_pci6208_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_pci6208.driver_name); + return comedi_pci_auto_config(dev, &driver_pci6208); } static void __devexit driver_pci6208_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/adl_pci7230.c b/drivers/staging/comedi/drivers/adl_pci7230.c index 20d5705..c322433 100644 --- a/drivers/staging/comedi/drivers/adl_pci7230.c +++ b/drivers/staging/comedi/drivers/adl_pci7230.c @@ -196,7 +196,7 @@ static int __devinit driver_adl_pci7230_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_adl_pci7230.driver_name); + return comedi_pci_auto_config(dev, &driver_adl_pci7230); } static void __devexit driver_adl_pci7230_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/adl_pci7296.c b/drivers/staging/comedi/drivers/adl_pci7296.c index 9a232053..bd18865 100644 --- a/drivers/staging/comedi/drivers/adl_pci7296.c +++ b/drivers/staging/comedi/drivers/adl_pci7296.c @@ -176,7 +176,7 @@ static int __devinit driver_adl_pci7296_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_adl_pci7296.driver_name); + return comedi_pci_auto_config(dev, &driver_adl_pci7296); } static void __devexit driver_adl_pci7296_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/adl_pci7432.c b/drivers/staging/comedi/drivers/adl_pci7432.c index 86ee219..1e0db48 100644 --- a/drivers/staging/comedi/drivers/adl_pci7432.c +++ b/drivers/staging/comedi/drivers/adl_pci7432.c @@ -209,7 +209,7 @@ static int __devinit driver_adl_pci7432_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_adl_pci7432.driver_name); + return comedi_pci_auto_config(dev, &driver_adl_pci7432); } static void __devexit driver_adl_pci7432_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index 3b83d65..bd0c14b 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -388,7 +388,7 @@ static int __devinit driver_adl_pci8164_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_adl_pci8164.driver_name); + return comedi_pci_auto_config(dev, &driver_adl_pci8164); } static void __devexit driver_adl_pci8164_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 2a9bd88a..6b4d98a 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -364,7 +364,7 @@ static struct comedi_driver pci9111_driver = { static int __devinit pci9111_driver_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, pci9111_driver.driver_name); + return comedi_pci_auto_config(dev, &pci9111_driver); } static void __devexit pci9111_driver_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index f17654e..cfe164a 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -292,7 +292,7 @@ static struct comedi_driver driver_pci9118 = { static int __devinit driver_pci9118_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_pci9118.driver_name); + return comedi_pci_auto_config(dev, &driver_pci9118); } static void __devexit driver_pci9118_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 8318c82..dc6fe3d 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1612,7 +1612,7 @@ static int pci1710_detach(struct comedi_device *dev) static int __devinit driver_pci1710_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_pci1710.driver_name); + return comedi_pci_auto_config(dev, &driver_pci1710); } static void __devexit driver_pci1710_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 29455a8..eb49c87 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -498,7 +498,7 @@ static int pci1723_detach(struct comedi_device *dev) static int __devinit driver_pci1723_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_pci1723.driver_name); + return comedi_pci_auto_config(dev, &driver_pci1723); } static void __devexit driver_pci1723_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 7af068f..491df0c 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -1319,7 +1319,7 @@ static int pci_dio_detach(struct comedi_device *dev) static int __devinit driver_pci_dio_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_pci_dio.driver_name); + return comedi_pci_auto_config(dev, &driver_pci_dio); } static void __devexit driver_pci_dio_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 7e8828f..cbfa0cd 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -509,7 +509,7 @@ static int __devinit driver_amplc_dio200_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_amplc_dio200.driver_name); + return comedi_pci_auto_config(dev, &driver_amplc_dio200); } static void __devexit driver_amplc_dio200_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index b15d0ee..821cf1d 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -192,7 +192,7 @@ static int __devinit driver_amplc_pc236_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_amplc_pc236.driver_name); + return comedi_pci_auto_config(dev, &driver_amplc_pc236); } static void __devexit driver_amplc_pc236_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 0f761c5..58ef6e4 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -459,7 +459,7 @@ static int __devinit driver_amplc_pc263_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_amplc_pc263.driver_name); + return comedi_pci_auto_config(dev, &driver_amplc_pc263); } static void __devexit driver_amplc_pc263_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index b278917c..0f2cac2 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -444,7 +444,7 @@ static int __devinit driver_amplc_pci224_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_amplc_pci224.driver_name); + return comedi_pci_auto_config(dev, &driver_amplc_pci224); } static void __devexit driver_amplc_pci224_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 5389795..1d2eb47 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -618,7 +618,7 @@ static int __devinit driver_amplc_pci230_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_amplc_pci230.driver_name); + return comedi_pci_auto_config(dev, &driver_amplc_pci230); } static void __devexit driver_amplc_pci230_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 7e4ffcf..f1ad286 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1925,7 +1925,7 @@ static int nvram_read(struct comedi_device *dev, unsigned int address, static int __devinit driver_cb_pcidas_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_cb_pcidas.driver_name); + return comedi_pci_auto_config(dev, &driver_cb_pcidas); } static void __devexit driver_cb_pcidas_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 915157d..ff79fd4 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1219,7 +1219,7 @@ static void load_ao_dma(struct comedi_device *dev, static int __devinit driver_cb_pcidas_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_cb_pcidas.driver_name); + return comedi_pci_auto_config(dev, &driver_cb_pcidas); } static void __devexit driver_cb_pcidas_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index abba220..41e06c1 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -850,7 +850,7 @@ static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel, static int __devinit driver_cb_pcidda_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_cb_pcidda.driver_name); + return comedi_pci_auto_config(dev, &driver_cb_pcidda); } static void __devexit driver_cb_pcidda_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c index 8f32152..3758af7 100644 --- a/drivers/staging/comedi/drivers/cb_pcidio.c +++ b/drivers/staging/comedi/drivers/cb_pcidio.c @@ -293,7 +293,7 @@ static int pcidio_detach(struct comedi_device *dev) static int __devinit driver_cb_pcidio_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_cb_pcidio.driver_name); + return comedi_pci_auto_config(dev, &driver_cb_pcidio); } static void __devexit driver_cb_pcidio_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 8ba6942..f92b800 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -487,7 +487,7 @@ static int __devinit driver_cb_pcimdas_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_cb_pcimdas.driver_name); + return comedi_pci_auto_config(dev, &driver_cb_pcimdas); } static void __devexit driver_cb_pcimdas_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 40bddfa..8d1081e 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -201,7 +201,7 @@ static int __devinit cb_pcimdda_driver_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, cb_pcimdda_driver.driver_name); + return comedi_pci_auto_config(dev, &cb_pcimdda_driver); } static void __devexit cb_pcimdda_driver_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index e3659bd..621e8af 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -231,7 +231,7 @@ static int contec_di_insn_bits(struct comedi_device *dev, static int __devinit driver_contec_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_contec.driver_name); + return comedi_pci_auto_config(dev, &driver_contec); } static void __devexit driver_contec_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index e61c6a8..70731972 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -878,7 +878,7 @@ static int __devinit driver_daqboard2000_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_daqboard2000.driver_name); + return comedi_pci_auto_config(dev, &driver_daqboard2000); } static void __devexit driver_daqboard2000_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 05a8d0c..575c5cc 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -1111,7 +1111,7 @@ EXPORT_SYMBOL_GPL(das08_common_detach); static int __devinit driver_das08_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_das08.driver_name); + return comedi_pci_auto_config(dev, &driver_das08); } static void __devexit driver_das08_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 0a7979e..d44c89d 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -289,7 +289,7 @@ static struct comedi_driver driver_dt3000 = { static int __devinit driver_dt3000_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_dt3000.driver_name); + return comedi_pci_auto_config(dev, &driver_dt3000); } static void __devexit driver_dt3000_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index da8a2bf..f54e7ff 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -421,7 +421,7 @@ static int dyna_pci10xx_detach(struct comedi_device *dev) static int __devinit driver_dyna_pci10xx_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_dyna_pci10xx.driver_name); + return comedi_pci_auto_config(dev, &driver_dyna_pci10xx); } static void __devexit driver_dyna_pci10xx_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index bc020de..a7b9f6e 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -348,7 +348,7 @@ static struct comedi_driver driver_hpdi = { static int __devinit driver_hpdi_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_hpdi.driver_name); + return comedi_pci_auto_config(dev, &driver_hpdi); } static void __devexit driver_hpdi_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 6a79ba1..114885d 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -977,7 +977,7 @@ static int jr3_pci_detach(struct comedi_device *dev) static int __devinit driver_jr3_pci_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_jr3_pci.driver_name); + return comedi_pci_auto_config(dev, &driver_jr3_pci); } static void __devexit driver_jr3_pci_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index 4e9e9a0..fef6ea7 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -97,7 +97,7 @@ static struct comedi_driver cnt_driver = { static int __devinit cnt_driver_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, cnt_driver.driver_name); + return comedi_pci_auto_config(dev, &cnt_driver); } static void __devexit cnt_driver_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index b0bc6bb..54bcacc 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -2427,7 +2427,7 @@ static int me4000_cnt_insn_write(struct comedi_device *dev, static int __devinit driver_me4000_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_me4000.driver_name); + return comedi_pci_auto_config(dev, &driver_me4000); } static void __devexit driver_me4000_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 8b812e4..e286dcb 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -257,7 +257,7 @@ static struct comedi_driver me_driver = { static int __devinit me_driver_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, me_driver.driver_name); + return comedi_pci_auto_config(dev, &me_driver); } static void __devexit me_driver_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 54741c9..75c146d 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -493,7 +493,7 @@ static int ni6527_find_device(struct comedi_device *dev, int bus, int slot) static int __devinit driver_ni6527_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_ni6527.driver_name); + return comedi_pci_auto_config(dev, &driver_ni6527); } static void __devexit driver_ni6527_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 403fc09..4a3f54ed 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -837,7 +837,7 @@ static int ni_65xx_find_device(struct comedi_device *dev, int bus, int slot) static int __devinit driver_ni_65xx_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_ni_65xx.driver_name); + return comedi_pci_auto_config(dev, &driver_ni_65xx); } static void __devexit driver_ni_65xx_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 35f3a47..eea7047 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -474,7 +474,7 @@ static struct comedi_driver driver_ni_660x = { static int __devinit driver_ni_660x_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_ni_660x.driver_name); + return comedi_pci_auto_config(dev, &driver_ni_660x); } static void __devexit driver_ni_660x_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index d8d91f9..c74efc4 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -123,7 +123,7 @@ static struct comedi_driver driver_ni_670x = { static int __devinit driver_ni_670x_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_ni_670x.driver_name); + return comedi_pci_auto_config(dev, &driver_ni_670x); } static void __devexit driver_ni_670x_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 721b2be..b281fc6 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -2141,7 +2141,7 @@ static void write_caldac(struct comedi_device *dev, unsigned int channel, static int __devinit driver_labpc_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_labpc.driver_name); + return comedi_pci_auto_config(dev, &driver_labpc); } static void __devexit driver_labpc_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 1df8fcb..6452841 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -1359,7 +1359,7 @@ static int nidio_find_device(struct comedi_device *dev, int bus, int slot) static int __devinit driver_pcidio_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_pcidio.driver_name); + return comedi_pci_auto_config(dev, &driver_pcidio); } static void __devexit driver_pcidio_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 27baefa..1065b2c 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1263,7 +1263,7 @@ static struct comedi_driver driver_pcimio = { static int __devinit driver_pcimio_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_pcimio.driver_name); + return comedi_pci_auto_config(dev, &driver_pcimio); } static void __devexit driver_pcimio_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 3b7393a..0b7ff76d 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -2355,7 +2355,7 @@ static int rtd_dio_insn_config(struct comedi_device *dev, static int __devinit rtd520Driver_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, rtd520Driver.driver_name); + return comedi_pci_auto_config(dev, &rtd520Driver); } static void __devexit rtd520Driver_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 23fc64b..5e04d6a 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -227,7 +227,7 @@ static struct dio_private *dio_private_word[]={ static int __devinit driver_s626_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_s626.driver_name); + return comedi_pci_auto_config(dev, &driver_s626); } static void __devexit driver_s626_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index ed69008..19a513e 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -623,7 +623,7 @@ static int skel_dio_insn_config(struct comedi_device *dev, static int __devinit driver_skel_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_skel.driver_name); + return comedi_pci_auto_config(dev, &driver_skel); } static void __devexit driver_skel_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index bf62e0d..1420fcc 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -317,6 +317,8 @@ static struct usbduxsub usbduxsub[NUMUSBDUX]; static DEFINE_SEMAPHORE(start_stop_sem); +static struct comedi_driver driver_usbdux; /* see below for initializer */ + /* * Stops the data acquision * It should be safe to call this function from any context @@ -2324,7 +2326,7 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw, "Could not upload firmware (err=%d)\n", ret); goto out; } - comedi_usb_auto_config(usbdev, BOARDNAME); + comedi_usb_auto_config(usbdev, &driver_usbdux); out: release_firmware(fw); } diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 2a8e725..bf6198e 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -201,6 +201,8 @@ static struct usbduxfastsub_s usbduxfastsub[NUMUSBDUXFAST]; static DEFINE_SEMAPHORE(start_stop_sem); +static struct comedi_driver driver_usbduxfast; /* see below for initializer */ + /* * bulk transfers to usbduxfast */ @@ -1458,7 +1460,7 @@ static void usbduxfast_firmware_request_complete_handler(const struct firmware goto out; } - comedi_usb_auto_config(usbdev, BOARDNAME); + comedi_usb_auto_config(usbdev, &driver_usbduxfast); out: release_firmware(fw); } diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 63c9b6d..e59d1c0 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -267,6 +267,8 @@ static struct usbduxsub usbduxsub[NUMUSBDUX]; static DEFINE_SEMAPHORE(start_stop_sem); +static struct comedi_driver driver_usbduxsigma; /* see below for initializer */ + /* * Stops the data acquision * It should be safe to call this function from any context @@ -2332,7 +2334,7 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw, "Could not upload firmware (err=%d)\n", ret); goto out; } - comedi_usb_auto_config(usbdev, BOARDNAME); + comedi_usb_auto_config(usbdev, &driver_usbduxsigma); out: release_firmware(fw); } diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index 3d13ca6e1..4bda1e8 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -247,6 +247,8 @@ static struct vmk80xx_usb vmb[VMK80XX_MAX_BOARDS]; static DEFINE_MUTEX(glb_mutex); +static struct comedi_driver driver_vmk80xx; /* see below for initializer */ + static void vmk80xx_tx_callback(struct urb *urb) { struct vmk80xx_usb *dev = urb->context; @@ -1482,7 +1484,7 @@ static int vmk80xx_probe(struct usb_interface *intf, mutex_unlock(&glb_mutex); - comedi_usb_auto_config(dev->udev, BOARDNAME); + comedi_usb_auto_config(dev->udev, &driver_vmk80xx); return 0; error: -- cgit v0.10.2 From 7cbd8f3dcaeeb489894fb49e669b007455d9785e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 30 Mar 2012 17:14:57 +0100 Subject: staging: comedi: don't disable IRQ for comedi_file_info_table_lock None of the functions that acquire the comedi_file_info_table_lock spin-lock need to disable interrupts. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 9bcf87a..f5417a3 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2192,7 +2192,6 @@ static void comedi_device_cleanup(struct comedi_device *dev) int comedi_alloc_board_minor(struct device *hardware_device) { - unsigned long flags; struct comedi_device_file_info *info; struct device *csdev; unsigned i; @@ -2207,14 +2206,14 @@ int comedi_alloc_board_minor(struct device *hardware_device) return -ENOMEM; } comedi_device_init(info->device); - spin_lock_irqsave(&comedi_file_info_table_lock, flags); + spin_lock(&comedi_file_info_table_lock); for (i = 0; i < COMEDI_NUM_BOARD_MINORS; ++i) { if (comedi_file_info_table[i] == NULL) { comedi_file_info_table[i] = info; break; } } - spin_unlock_irqrestore(&comedi_file_info_table_lock, flags); + spin_unlock(&comedi_file_info_table_lock); if (i == COMEDI_NUM_BOARD_MINORS) { comedi_device_cleanup(info->device); kfree(info->device); @@ -2271,14 +2270,13 @@ int comedi_alloc_board_minor(struct device *hardware_device) void comedi_free_board_minor(unsigned minor) { - unsigned long flags; struct comedi_device_file_info *info; BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS); - spin_lock_irqsave(&comedi_file_info_table_lock, flags); + spin_lock(&comedi_file_info_table_lock); info = comedi_file_info_table[minor]; comedi_file_info_table[minor] = NULL; - spin_unlock_irqrestore(&comedi_file_info_table_lock, flags); + spin_unlock(&comedi_file_info_table_lock); if (info) { struct comedi_device *dev = info->device; @@ -2297,7 +2295,6 @@ void comedi_free_board_minor(unsigned minor) int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s) { - unsigned long flags; struct comedi_device_file_info *info; struct device *csdev; unsigned i; @@ -2309,14 +2306,14 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev, info->device = dev; info->read_subdevice = s; info->write_subdevice = s; - spin_lock_irqsave(&comedi_file_info_table_lock, flags); + spin_lock(&comedi_file_info_table_lock); for (i = COMEDI_FIRST_SUBDEVICE_MINOR; i < COMEDI_NUM_MINORS; ++i) { if (comedi_file_info_table[i] == NULL) { comedi_file_info_table[i] = info; break; } } - spin_unlock_irqrestore(&comedi_file_info_table_lock, flags); + spin_unlock(&comedi_file_info_table_lock); if (i == COMEDI_NUM_MINORS) { kfree(info); printk(KERN_ERR @@ -2372,7 +2369,6 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev, void comedi_free_subdevice_minor(struct comedi_subdevice *s) { - unsigned long flags; struct comedi_device_file_info *info; if (s == NULL) @@ -2383,10 +2379,10 @@ void comedi_free_subdevice_minor(struct comedi_subdevice *s) BUG_ON(s->minor >= COMEDI_NUM_MINORS); BUG_ON(s->minor < COMEDI_FIRST_SUBDEVICE_MINOR); - spin_lock_irqsave(&comedi_file_info_table_lock, flags); + spin_lock(&comedi_file_info_table_lock); info = comedi_file_info_table[s->minor]; comedi_file_info_table[s->minor] = NULL; - spin_unlock_irqrestore(&comedi_file_info_table_lock, flags); + spin_unlock(&comedi_file_info_table_lock); if (s->class_dev) { device_destroy(comedi_class, MKDEV(COMEDI_MAJOR, s->minor)); @@ -2397,13 +2393,12 @@ void comedi_free_subdevice_minor(struct comedi_subdevice *s) struct comedi_device_file_info *comedi_get_device_file_info(unsigned minor) { - unsigned long flags; struct comedi_device_file_info *info; BUG_ON(minor >= COMEDI_NUM_MINORS); - spin_lock_irqsave(&comedi_file_info_table_lock, flags); + spin_lock(&comedi_file_info_table_lock); info = comedi_file_info_table[minor]; - spin_unlock_irqrestore(&comedi_file_info_table_lock, flags); + spin_unlock(&comedi_file_info_table_lock); return info; } EXPORT_SYMBOL_GPL(comedi_get_device_file_info); -- cgit v0.10.2 From c43435d7722134ed1fda58ce1025f41029bd58ad Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 30 Mar 2012 17:14:58 +0100 Subject: staging: comedi: don't hijack hardware device private data comedi_auto_config() associates a Comedi minor device number with an auto-configured hardware device and comedi_auto_unconfig() disassociates it. Currently, these use the hardware device's private data pointer to point to some allocated storage holding the minor device number. This is a bit of a waste of the hardware device's private data pointer, preventing it from being used for something more useful by the low-level comedi device drivers. For example, it would make more sense if comedi_usb_auto_config() was passed a pointer to the struct usb_interface instead of the struct usb_device, but this cannot be done currently because the low-level comedi drivers already use the private data pointer in the struct usb_interface for something more useful. This patch stops the comedi core hijacking the hardware device's private data pointer. Instead, comedi_auto_config() stores a pointer to the hardware device's struct device in the struct comedi_device_file_info associated with the minor device number, and comedi_auto_unconfig() calls new function comedi_find_board_minor() to recover the minor device number associated with the hardware device. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index f5417a3..fdf4282 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2205,6 +2205,7 @@ int comedi_alloc_board_minor(struct device *hardware_device) kfree(info); return -ENOMEM; } + info->hardware_device = hardware_device; comedi_device_init(info->device); spin_lock(&comedi_file_info_table_lock); for (i = 0; i < COMEDI_NUM_BOARD_MINORS; ++i) { @@ -2292,6 +2293,23 @@ void comedi_free_board_minor(unsigned minor) } } +int comedi_find_board_minor(struct device *hardware_device) +{ + int minor; + struct comedi_device_file_info *info; + + for (minor = 0; minor < COMEDI_NUM_BOARD_MINORS; minor++) { + spin_lock(&comedi_file_info_table_lock); + info = comedi_file_info_table[minor]; + if (info && info->hardware_device == hardware_device) { + spin_unlock(&comedi_file_info_table_lock); + return minor; + } + spin_unlock(&comedi_file_info_table_lock); + } + return -ENODEV; +} + int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s) { diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 7e65add..965998f 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -234,6 +234,7 @@ struct comedi_device_file_info { struct comedi_device *device; struct comedi_subdevice *read_subdevice; struct comedi_subdevice *write_subdevice; + struct device *hardware_device; }; #ifdef CONFIG_COMEDI_DEBUG diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 9dd2da1..417aed2 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -822,25 +822,14 @@ static int comedi_auto_config(struct device *hardware_device, int minor; struct comedi_device_file_info *dev_file_info; int retval; - unsigned *private_data = NULL; - if (!comedi_autoconfig) { - dev_set_drvdata(hardware_device, NULL); + if (!comedi_autoconfig) return 0; - } minor = comedi_alloc_board_minor(hardware_device); if (minor < 0) return minor; - private_data = kmalloc(sizeof(unsigned), GFP_KERNEL); - if (private_data == NULL) { - retval = -ENOMEM; - goto cleanup; - } - *private_data = minor; - dev_set_drvdata(hardware_device, private_data); - dev_file_info = comedi_get_device_file_info(minor); memset(&it, 0, sizeof(it)); @@ -853,25 +842,22 @@ static int comedi_auto_config(struct device *hardware_device, retval = comedi_device_attach(dev_file_info->device, &it); mutex_unlock(&dev_file_info->device->mutex); -cleanup: - if (retval < 0) { - kfree(private_data); + if (retval < 0) comedi_free_board_minor(minor); - } return retval; } static void comedi_auto_unconfig(struct device *hardware_device) { - unsigned *minor = (unsigned *)dev_get_drvdata(hardware_device); - if (minor == NULL) - return; - - BUG_ON(*minor >= COMEDI_NUM_BOARD_MINORS); + int minor; - comedi_free_board_minor(*minor); - dev_set_drvdata(hardware_device, NULL); - kfree(minor); + if (hardware_device == NULL) + return; + minor = comedi_find_board_minor(hardware_device); + if (minor < 0) + return; + BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS); + comedi_free_board_minor(minor); } int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver) diff --git a/drivers/staging/comedi/internal.h b/drivers/staging/comedi/internal.h index 434ce34..4208fb4 100644 --- a/drivers/staging/comedi/internal.h +++ b/drivers/staging/comedi/internal.h @@ -7,6 +7,7 @@ int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); int comedi_alloc_board_minor(struct device *hardware_device); void comedi_free_board_minor(unsigned minor); +int comedi_find_board_minor(struct device *hardware_device); void comedi_reset_async_buf(struct comedi_async *async); int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size); -- cgit v0.10.2 From d8b6ca0850c558f21989d468801ad1414b1372c4 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 30 Mar 2012 17:14:59 +0100 Subject: staging: comedi: pass usb interface to comedi_usb_auto_config The comedi_usb_auto_config() and comedi_usb_auto_unconfig() functions currently take a 'struct usb_device *'. It makes more sense to pass a 'struct usb_interface *' to allow for composite USB devices. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 965998f..e4626b6 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -460,10 +460,10 @@ void comedi_free_subdevice_minor(struct comedi_subdevice *s); int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver); void comedi_pci_auto_unconfig(struct pci_dev *pcidev); -struct usb_device; /* forward declaration */ -int comedi_usb_auto_config(struct usb_device *usbdev, +struct usb_interface; /* forward declaration */ +int comedi_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver); -void comedi_usb_auto_unconfig(struct usb_device *usbdev); +void comedi_usb_auto_unconfig(struct usb_interface *intf); #ifdef CONFIG_COMEDI_PCI_DRIVERS #define CONFIG_COMEDI_PCI diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 417aed2..feb33f8 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -880,17 +880,17 @@ void comedi_pci_auto_unconfig(struct pci_dev *pcidev) } EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig); -int comedi_usb_auto_config(struct usb_device *usbdev, +int comedi_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver) { - BUG_ON(usbdev == NULL); - return comedi_auto_config(&usbdev->dev, driver->driver_name, NULL, 0); + BUG_ON(intf == NULL); + return comedi_auto_config(&intf->dev, driver->driver_name, NULL, 0); } EXPORT_SYMBOL_GPL(comedi_usb_auto_config); -void comedi_usb_auto_unconfig(struct usb_device *usbdev) +void comedi_usb_auto_unconfig(struct usb_interface *intf) { - BUG_ON(usbdev == NULL); - comedi_auto_unconfig(&usbdev->dev); + BUG_ON(intf == NULL); + comedi_auto_unconfig(&intf->dev); } EXPORT_SYMBOL_GPL(comedi_usb_auto_unconfig); diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 1420fcc..781da44 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -2306,11 +2306,11 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw, void *context) { struct usbduxsub *usbduxsub_tmp = context; - struct usb_device *usbdev = usbduxsub_tmp->usbdev; + struct usb_interface *uinterf = usbduxsub_tmp->interface; int ret; if (fw == NULL) { - dev_err(&usbdev->dev, + dev_err(&uinterf->dev, "Firmware complete handler without firmware!\n"); return; } @@ -2322,11 +2322,11 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw, ret = firmwareUpload(usbduxsub_tmp, fw->data, fw->size); if (ret) { - dev_err(&usbdev->dev, + dev_err(&uinterf->dev, "Could not upload firmware (err=%d)\n", ret); goto out; } - comedi_usb_auto_config(usbdev, &driver_usbdux); + comedi_usb_auto_config(uinterf, &driver_usbdux); out: release_firmware(fw); } @@ -2608,7 +2608,7 @@ static void usbduxsub_disconnect(struct usb_interface *intf) dev_err(&intf->dev, "comedi_: BUG! called with wrong ptr!!!\n"); return; } - comedi_usb_auto_unconfig(udev); + comedi_usb_auto_unconfig(intf); down(&start_stop_sem); down(&usbduxsub_tmp->sem); tidy_up(usbduxsub_tmp); diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index bf6198e..2b4d251 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -1442,7 +1442,7 @@ static void usbduxfast_firmware_request_complete_handler(const struct firmware *fw, void *context) { struct usbduxfastsub_s *usbduxfastsub_tmp = context; - struct usb_device *usbdev = usbduxfastsub_tmp->usbdev; + struct usb_interface *uinterf = usbduxfastsub_tmp->interface; int ret; if (fw == NULL) @@ -1455,12 +1455,12 @@ static void usbduxfast_firmware_request_complete_handler(const struct firmware ret = firmwareUpload(usbduxfastsub_tmp, fw->data, fw->size); if (ret) { - dev_err(&usbdev->dev, + dev_err(&uinterf->dev, "Could not upload firmware (err=%d)\n", ret); goto out; } - comedi_usb_auto_config(usbdev, &driver_usbduxfast); + comedi_usb_auto_config(uinterf, &driver_usbduxfast); out: release_firmware(fw); } @@ -1608,7 +1608,7 @@ static void usbduxfastsub_disconnect(struct usb_interface *intf) return; } - comedi_usb_auto_unconfig(udev); + comedi_usb_auto_unconfig(intf); down(&start_stop_sem); down(&udfs->sem); diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index e59d1c0..f21bb0d 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -2314,11 +2314,11 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw, void *context) { struct usbduxsub *usbduxsub_tmp = context; - struct usb_device *usbdev = usbduxsub_tmp->usbdev; + struct usb_interface *uinterf = usbduxsub_tmp->interface; int ret; if (fw == NULL) { - dev_err(&usbdev->dev, + dev_err(&uinterf->dev, "Firmware complete handler without firmware!\n"); return; } @@ -2330,11 +2330,11 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw, ret = firmwareUpload(usbduxsub_tmp, fw->data, fw->size); if (ret) { - dev_err(&usbdev->dev, + dev_err(&uinterf->dev, "Could not upload firmware (err=%d)\n", ret); goto out; } - comedi_usb_auto_config(usbdev, &driver_usbduxsigma); + comedi_usb_auto_config(uinterf, &driver_usbduxsigma); out: release_firmware(fw); } @@ -2625,7 +2625,7 @@ static void usbduxsigma_disconnect(struct usb_interface *intf) if (usbduxsub_tmp->ao_cmd_running) /* we are still running a command */ usbdux_ao_stop(usbduxsub_tmp, 1); - comedi_usb_auto_unconfig(udev); + comedi_usb_auto_unconfig(intf); down(&start_stop_sem); down(&usbduxsub_tmp->sem); tidy_up(usbduxsub_tmp); diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index 4bda1e8..10ac58d 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -1484,7 +1484,7 @@ static int vmk80xx_probe(struct usb_interface *intf, mutex_unlock(&glb_mutex); - comedi_usb_auto_config(dev->udev, &driver_vmk80xx); + comedi_usb_auto_config(intf, &driver_vmk80xx); return 0; error: @@ -1502,7 +1502,7 @@ static void vmk80xx_disconnect(struct usb_interface *intf) if (!dev) return; - comedi_usb_auto_unconfig(dev->udev); + comedi_usb_auto_unconfig(intf); mutex_lock(&glb_mutex); down(&dev->limit_sem); -- cgit v0.10.2 From 3902a370281d2f2b130f141e8cf94eab40125769 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 30 Mar 2012 17:15:00 +0100 Subject: staging: comedi: refactor comedi_device_attach() a bit Split the post-config part of comedi_device_attach() into new function comedi_device_postconfig() and rearrange the rest of the function a bit. The new comedi_device_postconfig() function will be called by some new bus-type-specific auto-attach functions. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index feb33f8..cfb6fe9 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -106,6 +106,26 @@ void comedi_device_detach(struct comedi_device *dev) __comedi_device_detach(dev); } +/* do a little post-config cleanup */ +/* called with module refcount incremented, decrements it */ +static int comedi_device_postconfig(struct comedi_device *dev) +{ + int ret = postconfig(dev); + module_put(dev->driver->module); + if (ret < 0) { + __comedi_device_detach(dev); + return ret; + } + if (!dev->board_name) { + printk(KERN_WARNING "BUG: dev->board_name=<%p>\n", + dev->board_name); + dev->board_name = "BUG"; + } + smp_wmb(); + dev->attached = 1; + return 0; +} + int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_driver *driv; @@ -121,59 +141,36 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) } if (driv->num_names) { dev->board_ptr = comedi_recognize(driv, it->board_name); - if (dev->board_ptr == NULL) { - module_put(driv->module); - continue; - } - } else { - if (strcmp(driv->driver_name, it->board_name)) { - module_put(driv->module); + if (dev->board_ptr) + break; + } else if (strcmp(driv->driver_name, it->board_name)) + break; + module_put(driv->module); + } + if (driv == NULL) { + /* recognize has failed if we get here */ + /* report valid board names before returning error */ + for (driv = comedi_drivers; driv; driv = driv->next) { + if (!try_module_get(driv->module)) { + printk(KERN_INFO + "comedi: failed to increment module count\n"); continue; } + comedi_report_boards(driv); + module_put(driv->module); } - /* initialize dev->driver here so - * comedi_error() can be called from attach */ - dev->driver = driv; - ret = driv->attach(dev, it); - if (ret < 0) { - module_put(dev->driver->module); - __comedi_device_detach(dev); - return ret; - } - goto attached; + return -EIO; } - - /* recognize has failed if we get here */ - /* report valid board names before returning error */ - for (driv = comedi_drivers; driv; driv = driv->next) { - if (!try_module_get(driv->module)) { - printk(KERN_INFO - "comedi: failed to increment module count\n"); - continue; - } - comedi_report_boards(driv); - module_put(driv->module); - } - return -EIO; - -attached: - /* do a little post-config cleanup */ - ret = postconfig(dev); - module_put(dev->driver->module); + /* initialize dev->driver here so + * comedi_error() can be called from attach */ + dev->driver = driv; + ret = driv->attach(dev, it); if (ret < 0) { + module_put(dev->driver->module); __comedi_device_detach(dev); return ret; } - - if (!dev->board_name) { - printk(KERN_WARNING "BUG: dev->board_name=<%p>\n", - dev->board_name); - dev->board_name = "BUG"; - } - smp_wmb(); - dev->attached = 1; - - return 0; + return comedi_device_postconfig(dev); } int comedi_driver_register(struct comedi_driver *driver) -- cgit v0.10.2 From f4011670023f28cf9081904f8986c0c1be5c9f1e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 30 Mar 2012 17:15:01 +0100 Subject: staging: comedi: add bus-type-specific attach hooks for PCI and USB The Comedi auto-configuration mechanism used to bind hardware devices to comedi devices automatically is pretty kludgy. It fakes a "manual" configuration of the comedi device as though the COMEDI_DEVCONFIG ioctl (or the 'comedi_config' utility) were used. In particular, the low-level comedi driver's '->attach()' routine is called with a pointer to the struct comedi_device being attached and a pointer to a 'struct devconfig' containing a device name string and a few integer options to help the attach routine locate the device being attached. In the case of PCI devices, these integer options are the PCI bus and slot numbers. In the case of USB devices, there are no integer options and it relies more on pot luck to attach the correct device. This patch adds a couple of bus-type-specific attach routine hooks to the struct comedi_driver, which a low-level driver can optionally fill in if it supports auto-configuration. A low-level driver that supports auto-configuration of {PCI,USB} devices calls the existing comedi_{pci,usb}_auto_config() when it wishes to auto-configure a freshly probed device (maybe after loading firmware). This will call the new '->attach_{pci,usb}()' hook if the driver has defined it, otherwise it will fall back to calling the '->attach()' hook as before. The '->attach_{pci,usb}()' hook gets a pointer to the struct comedi_device and a pointer to the struct {pci_dev,usb_interface} and can figure out the {PCI,USB} device details for itself. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index e4626b6..300fd84 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -180,6 +180,9 @@ struct comedi_async { unsigned int x); }; +struct pci_dev; +struct usb_interface; + struct comedi_driver { struct comedi_driver *next; @@ -187,6 +190,8 @@ struct comedi_driver { struct module *module; int (*attach) (struct comedi_device *, struct comedi_devconfig *); int (*detach) (struct comedi_device *); + int (*attach_pci) (struct comedi_device *, struct pci_dev *); + int (*attach_usb) (struct comedi_device *, struct usb_interface *); /* number of elements in board_name and board_id arrays */ unsigned int num_names; @@ -460,7 +465,6 @@ void comedi_free_subdevice_minor(struct comedi_subdevice *s); int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver); void comedi_pci_auto_unconfig(struct pci_dev *pcidev); -struct usb_interface; /* forward declaration */ int comedi_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver); void comedi_usb_auto_unconfig(struct usb_interface *intf); diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index cfb6fe9..69e6fa3 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -811,6 +811,51 @@ void comedi_reset_async_buf(struct comedi_async *async) async->events = 0; } +static int +comedi_auto_config_helper(struct device *hardware_device, + struct comedi_driver *driver, + int (*attach_wrapper) (struct comedi_device *, + void *), void *context) +{ + int minor; + struct comedi_device_file_info *dev_file_info; + struct comedi_device *comedi_dev; + int ret; + + if (!comedi_autoconfig) + return 0; + + minor = comedi_alloc_board_minor(hardware_device); + if (minor < 0) + return minor; + + dev_file_info = comedi_get_device_file_info(minor); + comedi_dev = dev_file_info->device; + + mutex_lock(&comedi_dev->mutex); + if (comedi_dev->attached) + ret = -EBUSY; + else if (!try_module_get(driver->module)) { + printk(KERN_INFO "comedi: failed to increment module count\n"); + ret = -EIO; + } else { + /* set comedi_dev->driver here for attach wrapper */ + comedi_dev->driver = driver; + ret = (*attach_wrapper)(comedi_dev, context); + if (ret < 0) { + module_put(driver->module); + __comedi_device_detach(comedi_dev); + } else { + ret = comedi_device_postconfig(comedi_dev); + } + } + mutex_unlock(&comedi_dev->mutex); + + if (ret < 0) + comedi_free_board_minor(minor); + return ret; +} + static int comedi_auto_config(struct device *hardware_device, const char *board_name, const int *options, unsigned num_options) @@ -857,7 +902,8 @@ static void comedi_auto_unconfig(struct device *hardware_device) comedi_free_board_minor(minor); } -int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver) +static int comedi_old_pci_auto_config(struct pci_dev *pcidev, + struct comedi_driver *driver) { int options[2]; @@ -869,6 +915,27 @@ int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver) return comedi_auto_config(&pcidev->dev, driver->driver_name, options, ARRAY_SIZE(options)); } + +static int comedi_pci_attach_wrapper(struct comedi_device *dev, void *pcidev) +{ + return dev->driver->attach_pci(dev, pcidev); +} + +static int comedi_new_pci_auto_config(struct pci_dev *pcidev, + struct comedi_driver *driver) +{ + return comedi_auto_config_helper(&pcidev->dev, driver, + comedi_pci_attach_wrapper, pcidev); +} + +int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver) +{ + + if (driver->attach_pci) + return comedi_new_pci_auto_config(pcidev, driver); + else + return comedi_old_pci_auto_config(pcidev, driver); +} EXPORT_SYMBOL_GPL(comedi_pci_auto_config); void comedi_pci_auto_unconfig(struct pci_dev *pcidev) @@ -877,11 +944,32 @@ void comedi_pci_auto_unconfig(struct pci_dev *pcidev) } EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig); +static int comedi_old_usb_auto_config(struct usb_interface *intf, + struct comedi_driver *driver) +{ + return comedi_auto_config(&intf->dev, driver->driver_name, NULL, 0); +} + +static int comedi_usb_attach_wrapper(struct comedi_device *dev, void *intf) +{ + return dev->driver->attach_usb(dev, intf); +} + +static int comedi_new_usb_auto_config(struct usb_interface *intf, + struct comedi_driver *driver) +{ + return comedi_auto_config_helper(&intf->dev, driver, + comedi_usb_attach_wrapper, intf); +} + int comedi_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver) { BUG_ON(intf == NULL); - return comedi_auto_config(&intf->dev, driver->driver_name, NULL, 0); + if (driver->attach_usb) + return comedi_new_usb_auto_config(intf, driver); + else + return comedi_old_usb_auto_config(intf, driver); } EXPORT_SYMBOL_GPL(comedi_usb_auto_config); -- cgit v0.10.2 From 63bf3d11df34426caa81e5478b2ff0e99875e972 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 30 Mar 2012 17:15:02 +0100 Subject: staging: comedi: pass struct comedi_driver * to comedi_auto_config() Pass a pointer to the struct comedi_driver to comedi_auto_config() instead of the driver name. comedi_auto_config() will be changed to make use of this. It currently calls comedi_device_attach() which examines the whole list of struct comedi_driver objects. It will be changed to restrict itself to just the supplied struct comedi_driver object. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 69e6fa3..aec9c35 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -857,7 +857,7 @@ comedi_auto_config_helper(struct device *hardware_device, } static int comedi_auto_config(struct device *hardware_device, - const char *board_name, const int *options, + struct comedi_driver *driver, const int *options, unsigned num_options) { struct comedi_devconfig it; @@ -875,7 +875,7 @@ static int comedi_auto_config(struct device *hardware_device, dev_file_info = comedi_get_device_file_info(minor); memset(&it, 0, sizeof(it)); - strncpy(it.board_name, board_name, COMEDI_NAMELEN); + strncpy(it.board_name, driver->driver_name, COMEDI_NAMELEN); it.board_name[COMEDI_NAMELEN - 1] = '\0'; BUG_ON(num_options > COMEDI_NDEVCONFOPTS); memcpy(it.options, options, num_options * sizeof(int)); @@ -912,7 +912,7 @@ static int comedi_old_pci_auto_config(struct pci_dev *pcidev, /* pci slot */ options[1] = PCI_SLOT(pcidev->devfn); - return comedi_auto_config(&pcidev->dev, driver->driver_name, + return comedi_auto_config(&pcidev->dev, driver, options, ARRAY_SIZE(options)); } @@ -947,7 +947,7 @@ EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig); static int comedi_old_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver) { - return comedi_auto_config(&intf->dev, driver->driver_name, NULL, 0); + return comedi_auto_config(&intf->dev, driver, NULL, 0); } static int comedi_usb_attach_wrapper(struct comedi_device *dev, void *intf) -- cgit v0.10.2 From cf938c247307826e70f93dd9072c70d3020d6d67 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 30 Mar 2012 17:15:03 +0100 Subject: staging: comedi: restrict comedi_auto_config() to single driver comedi_auto_config() only needs to consider a single struct comedi_driver object, but it currently calls comedi_device_attach() which looks at all struct comedi_driver objects registered with the Comedi core. Instead, call the recently added comedi_auto_config_helper() with a new wrapper comedi_auto_config_wrapper() to mimic the effect of comedi_device_attach() for a single struct comedi_driver. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index aec9c35..872b598b 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -856,37 +856,40 @@ comedi_auto_config_helper(struct device *hardware_device, return ret; } +static int comedi_auto_config_wrapper(struct comedi_device *dev, void *context) +{ + struct comedi_devconfig *it = context; + struct comedi_driver *driv = dev->driver; + + if (driv->num_names) { + /* look for generic board entry matching driver name, which + * has already been copied to it->board_name */ + dev->board_ptr = comedi_recognize(driv, it->board_name); + if (dev->board_ptr == NULL) { + printk(KERN_WARNING + "comedi: auto config failed to find board entry" + " '%s' for driver '%s'\n", it->board_name, + driv->driver_name); + comedi_report_boards(driv); + return -EINVAL; + } + } + return driv->attach(dev, it); +} + static int comedi_auto_config(struct device *hardware_device, struct comedi_driver *driver, const int *options, unsigned num_options) { struct comedi_devconfig it; - int minor; - struct comedi_device_file_info *dev_file_info; - int retval; - - if (!comedi_autoconfig) - return 0; - - minor = comedi_alloc_board_minor(hardware_device); - if (minor < 0) - return minor; - - dev_file_info = comedi_get_device_file_info(minor); memset(&it, 0, sizeof(it)); strncpy(it.board_name, driver->driver_name, COMEDI_NAMELEN); it.board_name[COMEDI_NAMELEN - 1] = '\0'; BUG_ON(num_options > COMEDI_NDEVCONFOPTS); memcpy(it.options, options, num_options * sizeof(int)); - - mutex_lock(&dev_file_info->device->mutex); - retval = comedi_device_attach(dev_file_info->device, &it); - mutex_unlock(&dev_file_info->device->mutex); - - if (retval < 0) - comedi_free_board_minor(minor); - return retval; + return comedi_auto_config_helper(hardware_device, driver, + comedi_auto_config_wrapper, &it); } static void comedi_auto_unconfig(struct device *hardware_device) -- cgit v0.10.2 From 5e9d922f788a0be512b7cb1eaa90c3692d42c8c7 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 30 Mar 2012 17:15:04 +0100 Subject: staging: comedi: amplc_pci224: use attach_pci() hook Change the amplc_pci224 driver to use the new attach_pci() hook in struct comedi_driver to auto-configure probed PCI devices. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 0f2cac2..fe65338 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -430,11 +430,14 @@ struct pci224_private { static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it); static int pci224_detach(struct comedi_device *dev); +static int pci224_attach_pci(struct comedi_device *dev, + struct pci_dev *pci_dev); static struct comedi_driver driver_amplc_pci224 = { .driver_name = DRIVER_NAME, .module = THIS_MODULE, .attach = pci224_attach, .detach = pci224_detach, + .attach_pci = pci224_attach_pci, .board_name = &pci224_boards[0].name, .offset = sizeof(struct pci224_board), .num_names = ARRAY_SIZE(pci224_boards), @@ -1312,6 +1315,20 @@ static irqreturn_t pci224_interrupt(int irq, void *d) } /* + * This function looks for a board matching the supplied PCI device. + */ +static const struct pci224_board +*pci224_find_pci_board(struct pci_dev *pci_dev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(pci224_boards); i++) + if (pci_dev->device == pci224_boards[i].devid) + return &pci224_boards[i]; + return NULL; +} + +/* * This function looks for a PCI device matching the requested board name, * bus and slot. */ @@ -1336,17 +1353,12 @@ pci224_find_pci(struct comedi_device *dev, int bus, int slot, } if (thisboard->model == any_model) { /* Match any supported model. */ - int i; - - for (i = 0; i < ARRAY_SIZE(pci224_boards); i++) { - if (pci_dev->device == pci224_boards[i].devid) { - /* Change board_ptr to matched board. */ - dev->board_ptr = &pci224_boards[i]; - break; - } - } - if (i == ARRAY_SIZE(pci224_boards)) + const struct pci224_board *board_ptr; + board_ptr = pci224_find_pci_board(pci_dev); + if (board_ptr == NULL) continue; + /* Change board_ptr to matched board. */ + dev->board_ptr = board_ptr; } else { /* Match specific model name. */ if (thisboard->devid != pci_dev->device) @@ -1370,35 +1382,16 @@ pci224_find_pci(struct comedi_device *dev, int bus, int slot, } /* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. + * Common part of attach and attach_pci. */ -static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) +static int pci224_attach_common(struct comedi_device *dev, + struct pci_dev *pci_dev, int *options) { struct comedi_subdevice *s; - struct pci_dev *pci_dev; unsigned int irq; - int bus = 0, slot = 0; unsigned n; int ret; - printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, DRIVER_NAME); - - bus = it->options[0]; - slot = it->options[1]; - ret = alloc_private(dev, sizeof(struct pci224_private)); - if (ret < 0) { - printk(KERN_ERR "comedi%d: error! out of memory!\n", - dev->minor); - return ret; - } - - ret = pci224_find_pci(dev, bus, slot, &pci_dev); - if (ret < 0) - return ret; - devpriv->pci_dev = pci_dev; ret = comedi_pci_enable(pci_dev, DRIVER_NAME); if (ret < 0) { @@ -1483,24 +1476,26 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!s->range_table_list) return -ENOMEM; - for (n = 2; n < 3 + s->n_chan; n++) { - if (it->options[n] < 0 || it->options[n] > 1) { - printk(KERN_WARNING "comedi%d: %s: warning! " - "bad options[%u]=%d\n", - dev->minor, DRIVER_NAME, n, - it->options[n]); + if (options) { + for (n = 2; n < 3 + s->n_chan; n++) { + if (options[n] < 0 || options[n] > 1) { + printk(KERN_WARNING + "comedi%d: %s: warning! bad options[%u]=%d\n", + dev->minor, DRIVER_NAME, n, + options[n]); + } } } for (n = 0; n < s->n_chan; n++) { - if (n < COMEDI_NDEVCONFOPTS - 3 && - it->options[3 + n] == 1) { - if (it->options[2] == 1) + if (n < COMEDI_NDEVCONFOPTS - 3 && options && + options[3 + n] == 1) { + if (options[2] == 1) range_table_list[n] = &range_pci234_ext; else range_table_list[n] = &range_bipolar5; } else { - if (it->options[2] == 1) { + if (options && options[2] == 1) { range_table_list[n] = &range_pci234_ext2; } else { @@ -1511,14 +1506,14 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->hwrange = hwrange_pci234; } else { /* PCI224 range options. */ - if (it->options[2] == 1) { + if (options && options[2] == 1) { s->range_table = &range_pci224_external; devpriv->hwrange = hwrange_pci224_external; } else { - if (it->options[2] != 0) { + if (options && options[2] != 0) { printk(KERN_WARNING "comedi%d: %s: warning! " "bad options[2]=%d\n", - dev->minor, DRIVER_NAME, it->options[2]); + dev->minor, DRIVER_NAME, options[2]); } s->range_table = &range_pci224_internal; devpriv->hwrange = hwrange_pci224_internal; @@ -1553,6 +1548,66 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* + * _attach is called by the Comedi core to configure the driver + * for a particular board. If you specified a board_name array + * in the driver structure, dev->board_ptr contains that + * address. + */ +static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + struct pci_dev *pci_dev; + int bus, slot; + int ret; + + printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, DRIVER_NAME); + + bus = it->options[0]; + slot = it->options[1]; + ret = alloc_private(dev, sizeof(struct pci224_private)); + if (ret < 0) { + printk(KERN_ERR "comedi%d: error! out of memory!\n", + dev->minor); + return ret; + } + + ret = pci224_find_pci(dev, bus, slot, &pci_dev); + if (ret < 0) + return ret; + + return pci224_attach_common(dev, pci_dev, it->options); +} + +/* + * _attach_pci is called by comedi_pci_auto_config() in the Comedi core + * to configure a comedi device for a probed PCI device. + * dev->board_ptr is NULL on entry. + */ +static int +pci224_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) +{ + int ret; + + printk(KERN_DEBUG "comedi%d: %s: attach_pci %s\n", dev->minor, + DRIVER_NAME, pci_name(pci_dev)); + + ret = alloc_private(dev, sizeof(struct pci224_private)); + if (ret < 0) { + printk(KERN_ERR "comedi%d: error! out of memory!\n", + dev->minor); + return ret; + } + + dev->board_ptr = pci224_find_pci_board(pci_dev); + if (dev->board_ptr == NULL) { + printk(KERN_ERR + "comedi%d: %s: BUG! cannot determine board type!\n", + dev->minor, DRIVER_NAME); + return -EINVAL; + } + return pci224_attach_common(dev, pci_dev, NULL); +} + +/* * _detach is called to deconfigure a device. It should deallocate * resources. * This function is also called when _attach() fails, so it should be -- cgit v0.10.2 From 5a613d6460cdf311a2637aa29919ccb48bb402be Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 30 Mar 2012 17:15:05 +0100 Subject: staging: comedi: usbdux: use attach_usb() hook Change the usbdux driver to use the new attach_usb() hook in struct comedi_driver to auto-configure probed USB devices after the firmware is loaded. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 781da44..c3f928f 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -2617,46 +2617,22 @@ static void usbduxsub_disconnect(struct usb_interface *intf) dev_dbg(&intf->dev, "comedi_: disconnected from the usb\n"); } -/* is called when comedi-config is called */ -static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it) +/* 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) { int ret; - int index; - int i; - struct usbduxsub *udev; - + int index = (int)(udev - usbduxsub); struct comedi_subdevice *s = NULL; - dev->private = 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); - up(&start_stop_sem); - return -ENODEV; - } - - udev = &usbduxsub[index]; down(&udev->sem); /* pointer back to the corresponding comedi device */ udev->comedidev = dev; /* trying to upload the firmware into the chip */ - if (comedi_aux_data(it->options, 0) && - it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) { - firmwareUpload(udev, comedi_aux_data(it->options, 0), - it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]); - } + if (aux_data) + firmwareUpload(udev, aux_data, aux_len); dev->board_name = BOARDNAME; @@ -2675,7 +2651,6 @@ static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev_err(&udev->interface->dev, "comedi%d: error alloc space for subdev\n", dev->minor); up(&udev->sem); - up(&start_stop_sem); return ret; } @@ -2778,14 +2753,80 @@ static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it) up(&udev->sem); - up(&start_stop_sem); - dev_info(&udev->interface->dev, "comedi%d: attached to usbdux.\n", dev->minor); 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) +{ + int ret; + struct usbduxsub *this_usbduxsub; + + dev->private = NULL; + + down(&start_stop_sem); + this_usbduxsub = usb_get_intfdata(uinterf); + if (!this_usbduxsub || !this_usbduxsub->probed) { + printk(KERN_ERR + "comedi%d: usbdux: error: attach_usb failed, not connected\n", + dev->minor); + ret = -ENODEV; + } else if (this_usbduxsub->attached) { + printk(KERN_ERR + "comedi%d: usbdux: error: attach_usb failed, already attached\n", + dev->minor); + ret = -ENODEV; + } else + ret = usbdux_attach_common(dev, this_usbduxsub, NULL, 0); + up(&start_stop_sem); + return ret; +} + static int usbdux_detach(struct comedi_device *dev) { struct usbduxsub *usbduxsub_tmp; @@ -2824,6 +2865,7 @@ static struct comedi_driver driver_usbdux = { .module = THIS_MODULE, .attach = usbdux_attach, .detach = usbdux_detach, + .attach_usb = usbdux_attach_usb, }; /* Table with the USB-devices: just now only testing IDs */ -- cgit v0.10.2 From b3f79f980a07fabe22d553fb75010d5d0a12c943 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 2 Apr 2012 12:00:59 +0100 Subject: staging: comedi: usbdux: remove an unnecessary dev_info() usbdux_attach_common() prints two messages via dev_info() that shows a device has been attached. The first of these messages includes an index into a static array that the function determines by pointer subtraction, assuming the pointer passed to the function points to an element of the array. Dan Carpenter pointed out that this was kind of ugly. Since the dev_info() that prints the array index doesn't add anything useful (since no other messages print the array index and nothing else uses it), let's just get rid of it. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index c3f928f..3d300ef 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -2623,7 +2623,6 @@ static int usbdux_attach_common(struct comedi_device *dev, void *aux_data, int aux_len) { int ret; - int index = (int)(udev - usbduxsub); struct comedi_subdevice *s = NULL; down(&udev->sem); @@ -2654,9 +2653,6 @@ static int usbdux_attach_common(struct comedi_device *dev, return ret; } - dev_info(&udev->interface->dev, - "comedi%d: usb-device %d is attached to comedi.\n", - dev->minor, index); /* private structure is also simply the usb-structure */ dev->private = udev; -- cgit v0.10.2 From 6ad11bc3a0b84deb39f581ed36e19f82b9393695 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 10 Apr 2012 13:19:55 -0500 Subject: staging: drm/omap: dmabuf/prime support For now just implementing the exporting APIs, not yet importing. And kmap is rejected on tiled buffers (although the usefulness of that seems questionable, but could be added later if needed). Signed-off-by: Rob Clark Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/omapdrm/Makefile b/drivers/staging/omapdrm/Makefile index d9cdc12..1ca0e00 100644 --- a/drivers/staging/omapdrm/Makefile +++ b/drivers/staging/omapdrm/Makefile @@ -13,6 +13,7 @@ omapdrm-y := omap_drv.o \ omap_fb.o \ omap_fbdev.o \ omap_gem.o \ + omap_gem_dmabuf.o \ omap_dmm_tiler.o \ tcm-sita.o diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c index 3df5b4c..d6c602b 100644 --- a/drivers/staging/omapdrm/omap_drv.c +++ b/drivers/staging/omapdrm/omap_drv.c @@ -746,7 +746,7 @@ static const struct file_operations omapdriver_fops = { static struct drm_driver omap_drm_driver = { .driver_features = - DRIVER_HAVE_IRQ | DRIVER_MODESET | DRIVER_GEM, + DRIVER_HAVE_IRQ | DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, .load = dev_load, .unload = dev_unload, .open = dev_open, @@ -766,6 +766,8 @@ static struct drm_driver omap_drm_driver = { .debugfs_init = omap_debugfs_init, .debugfs_cleanup = omap_debugfs_cleanup, #endif + .prime_handle_to_fd = drm_gem_prime_handle_to_fd, + .gem_prime_export = omap_gem_prime_export, .gem_init_object = omap_gem_init_object, .gem_free_object = omap_gem_free_object, .gem_vm_ops = &omap_gem_vm_ops, diff --git a/drivers/staging/omapdrm/omap_drv.h b/drivers/staging/omapdrm/omap_drv.h index b7e0f07..3586173 100644 --- a/drivers/staging/omapdrm/omap_drv.h +++ b/drivers/staging/omapdrm/omap_drv.h @@ -148,9 +148,16 @@ int omap_gem_roll(struct drm_gem_object *obj, uint32_t roll); int omap_gem_get_paddr(struct drm_gem_object *obj, dma_addr_t *paddr, bool remap); int omap_gem_put_paddr(struct drm_gem_object *obj); +int omap_gem_get_pages(struct drm_gem_object *obj, struct page ***pages, + bool remap); +int omap_gem_put_pages(struct drm_gem_object *obj); +uint32_t omap_gem_flags(struct drm_gem_object *obj); uint64_t omap_gem_mmap_offset(struct drm_gem_object *obj); size_t omap_gem_mmap_size(struct drm_gem_object *obj); +struct dma_buf * omap_gem_prime_export(struct drm_device *dev, + struct drm_gem_object *obj, int flags); + static inline int align_pitch(int pitch, int width, int bpp) { int bytespp = (bpp + 7) / 8; diff --git a/drivers/staging/omapdrm/omap_gem.c b/drivers/staging/omapdrm/omap_gem.c index 921f058..c5ba334 100644 --- a/drivers/staging/omapdrm/omap_gem.c +++ b/drivers/staging/omapdrm/omap_gem.c @@ -266,6 +266,12 @@ static void omap_gem_detach_pages(struct drm_gem_object *obj) omap_obj->pages = NULL; } +/* get buffer flags */ +uint32_t omap_gem_flags(struct drm_gem_object *obj) +{ + return to_omap_bo(obj)->flags; +} + /** get mmap offset */ static uint64_t mmap_offset(struct drm_gem_object *obj) { @@ -764,9 +770,27 @@ static int get_pages(struct drm_gem_object *obj, struct page ***pages) return 0; } -int omap_gem_get_pages(struct drm_gem_object *obj, struct page ***pages) +/* if !remap, and we don't have pages backing, then fail, rather than + * increasing the pin count (which we don't really do yet anyways, + * because we don't support swapping pages back out). And 'remap' + * might not be quite the right name, but I wanted to keep it working + * similarly to omap_gem_get_paddr(). Note though that mutex is not + * aquired if !remap (because this can be called in atomic ctxt), + * but probably omap_gem_get_paddr() should be changed to work in the + * same way. If !remap, a matching omap_gem_put_pages() call is not + * required (and should not be made). + */ +int omap_gem_get_pages(struct drm_gem_object *obj, struct page ***pages, + bool remap) { int ret; + if (!remap) { + struct omap_gem_object *omap_obj = to_omap_bo(obj); + if (!omap_obj->pages) + return -ENOMEM; + *pages = omap_obj->pages; + return 0; + } mutex_lock(&obj->dev->struct_mutex); ret = get_pages(obj, pages); mutex_unlock(&obj->dev->struct_mutex); diff --git a/drivers/staging/omapdrm/omap_gem_dmabuf.c b/drivers/staging/omapdrm/omap_gem_dmabuf.c new file mode 100644 index 0000000..2fa39e8 --- /dev/null +++ b/drivers/staging/omapdrm/omap_gem_dmabuf.c @@ -0,0 +1,150 @@ +/* + * drivers/staging/omapdrm/omap_gem_dmabuf.c + * + * Copyright (C) 2011 Texas Instruments + * Author: Rob Clark + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * 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, see . + */ + +#include "omap_drv.h" + +#include + +static struct sg_table *omap_gem_map_dma_buf( + struct dma_buf_attachment *attachment, + enum dma_data_direction dir) +{ + struct drm_gem_object *obj = attachment->dmabuf->priv; + struct sg_table *sg; + dma_addr_t paddr; + int ret; + + sg = kzalloc(sizeof(*sg), GFP_KERNEL); + if (!sg) + return ERR_PTR(-ENOMEM); + + /* camera, etc, need physically contiguous.. but we need a + * better way to know this.. + */ + ret = omap_gem_get_paddr(obj, &paddr, true); + if (ret) + goto out; + + ret = sg_alloc_table(sg, 1, GFP_KERNEL); + if (ret) + goto out; + + sg_init_table(sg->sgl, 1); + sg_dma_len(sg->sgl) = obj->size; + sg_set_page(sg->sgl, pfn_to_page(PFN_DOWN(paddr)), obj->size, 0); + sg_dma_address(sg->sgl) = paddr; + +out: + if (ret) + return ERR_PTR(ret); + return sg; +} + +static void omap_gem_unmap_dma_buf(struct dma_buf_attachment *attachment, + struct sg_table *sg, enum dma_data_direction dir) +{ + struct drm_gem_object *obj = attachment->dmabuf->priv; + omap_gem_put_paddr(obj); + sg_free_table(sg); + kfree(sg); +} + +static void omap_gem_dmabuf_release(struct dma_buf *buffer) +{ + struct drm_gem_object *obj = buffer->priv; + /* release reference that was taken when dmabuf was exported + * in omap_gem_prime_set().. + */ + drm_gem_object_unreference_unlocked(obj); +} + + +static int omap_gem_dmabuf_begin_cpu_access(struct dma_buf *buffer, + size_t start, size_t len, enum dma_data_direction dir) +{ + struct drm_gem_object *obj = buffer->priv; + struct page **pages; + if (omap_gem_flags(obj) & OMAP_BO_TILED) { + /* TODO we would need to pin at least part of the buffer to + * get de-tiled view. For now just reject it. + */ + return -ENOMEM; + } + /* make sure we have the pages: */ + return omap_gem_get_pages(obj, &pages, true); +} + +static void omap_gem_dmabuf_end_cpu_access(struct dma_buf *buffer, + size_t start, size_t len, enum dma_data_direction dir) +{ + struct drm_gem_object *obj = buffer->priv; + omap_gem_put_pages(obj); +} + + +static void *omap_gem_dmabuf_kmap_atomic(struct dma_buf *buffer, + unsigned long page_num) +{ + struct drm_gem_object *obj = buffer->priv; + struct page **pages; + omap_gem_get_pages(obj, &pages, false); + return kmap_atomic(pages[page_num]); +} + +static void omap_gem_dmabuf_kunmap_atomic(struct dma_buf *buffer, + unsigned long page_num, void *addr) +{ + kunmap_atomic(addr); +} + +static void *omap_gem_dmabuf_kmap(struct dma_buf *buffer, + unsigned long page_num) +{ + struct drm_gem_object *obj = buffer->priv; + struct page **pages; + omap_gem_get_pages(obj, &pages, false); + return kmap(pages[page_num]); +} + +static void omap_gem_dmabuf_kunmap(struct dma_buf *buffer, + unsigned long page_num, void *addr) +{ + struct drm_gem_object *obj = buffer->priv; + struct page **pages; + omap_gem_get_pages(obj, &pages, false); + kunmap(pages[page_num]); +} + +struct dma_buf_ops omap_dmabuf_ops = { + .map_dma_buf = omap_gem_map_dma_buf, + .unmap_dma_buf = omap_gem_unmap_dma_buf, + .release = omap_gem_dmabuf_release, + .begin_cpu_access = omap_gem_dmabuf_begin_cpu_access, + .end_cpu_access = omap_gem_dmabuf_end_cpu_access, + .kmap_atomic = omap_gem_dmabuf_kmap_atomic, + .kunmap_atomic = omap_gem_dmabuf_kunmap_atomic, + .kmap = omap_gem_dmabuf_kmap, + .kunmap = omap_gem_dmabuf_kunmap, +}; + +struct dma_buf * omap_gem_prime_export(struct drm_device *dev, + struct drm_gem_object *obj, int flags) +{ + return dma_buf_export(obj, &omap_dmabuf_ops, obj->size, 0600); +} -- cgit v0.10.2 From 60e6d2689c2ab975a2ac3475b3ebd45c3edf905a Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Tue, 27 Mar 2012 19:07:11 -0400 Subject: staging: evict abandoned 68360serial.c driver from the kernel commit 3a0db7215c88077b61a673215756ec4a0dc0c7a5 "TTY: serial, move 68360 driver to staging" did so because the driver had remained broken since 2008. It also added this text to the TODO file: "If no one steps up to adopt any of these drivers, they will be removed in the 3.4 release." A quick search on the internet doesn't reveal anyone actively trying to update/fix this driver, so follow through on the above and remove it from the pending 3.4 release. Cc: Jiri Slaby Cc: Geert Uytterhoeven Cc: Alan Cox Cc: Greg Ungerer Signed-off-by: Paul Gortmaker Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 97d412d..4c99b4c 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -24,8 +24,6 @@ menuconfig STAGING if STAGING -source "drivers/staging/serial/Kconfig" - source "drivers/staging/et131x/Kconfig" source "drivers/staging/slicoss/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index ffe7d44..74662ce 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -3,7 +3,6 @@ # fix for build system bug... obj-$(CONFIG_STAGING) += staging.o -obj-y += serial/ obj-y += media/ obj-$(CONFIG_ET131X) += et131x/ obj-$(CONFIG_SLICOSS) += slicoss/ diff --git a/drivers/staging/serial/68360serial.c b/drivers/staging/serial/68360serial.c deleted file mode 100644 index daf0b1d..0000000 --- a/drivers/staging/serial/68360serial.c +++ /dev/null @@ -1,2979 +0,0 @@ -/* - * UART driver for 68360 CPM SCC or SMC - * Copyright (c) 2000 D. Jeff Dionne , - * Copyright (c) 2000 Michael Leslie - * Copyright (c) 1997 Dan Malek - * - * I used the serial.c driver as the framework for this driver. - * Give credit to those guys. - * The original code was written for the MBX860 board. I tried to make - * it generic, but there may be some assumptions in the structures that - * have to be fixed later. - * To save porting time, I did not bother to change any object names - * that are not accessed outside of this file. - * It still needs lots of work........When it was easy, I included code - * to support the SCCs, but this has never been tested, nor is it complete. - * Only the SCCs support modem control, so that is not complete either. - * - * This module exports the following rs232 io functions: - * - * int rs_360_init(void); - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#ifdef CONFIG_KGDB -extern void breakpoint(void); -extern void set_debug_traps(void); -extern int kgdb_output_string (const char* s, unsigned int count); -#endif - - -/* #ifdef CONFIG_SERIAL_CONSOLE */ /* This seems to be a post 2.0 thing - mles */ -#include -#include - -/* this defines the index into rs_table for the port to use - */ -#ifndef CONFIG_SERIAL_CONSOLE_PORT -#define CONFIG_SERIAL_CONSOLE_PORT 1 /* ie SMC2 - note USE_SMC2 must be defined */ -#endif -/* #endif */ - -#if 0 -/* SCC2 for console - */ -#undef CONFIG_SERIAL_CONSOLE_PORT -#define CONFIG_SERIAL_CONSOLE_PORT 2 -#endif - - -#define TX_WAKEUP ASYNC_SHARE_IRQ - -static char *serial_name = "CPM UART driver"; -static char *serial_version = "0.03"; - -static struct tty_driver *serial_driver; -int serial_console_setup(struct console *co, char *options); - -/* - * Serial driver configuration section. Here are the various options: - */ -#define SERIAL_PARANOIA_CHECK -#define CONFIG_SERIAL_NOPAUSE_IO -#define SERIAL_DO_RESTART - -/* Set of debugging defines */ - -#undef SERIAL_DEBUG_INTR -#undef SERIAL_DEBUG_OPEN -#undef SERIAL_DEBUG_FLOW -#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - -#define _INLINE_ inline - -#define DBG_CNT(s) - -/* We overload some of the items in the data structure to meet our - * needs. For example, the port address is the CPM parameter ram - * offset for the SCC or SMC. The maximum number of ports is 4 SCCs and - * 2 SMCs. The "hub6" field is used to indicate the channel number, with - * a flag indicating SCC or SMC, and the number is used as an index into - * the CPM parameter area for this device. - * The "type" field is currently set to 0, for PORT_UNKNOWN. It is - * not currently used. I should probably use it to indicate the port - * type of SMC or SCC. - * The SMCs do not support any modem control signals. - */ -#define smc_scc_num hub6 -#define NUM_IS_SCC ((int)0x00010000) -#define PORT_NUM(P) ((P) & 0x0000ffff) - - -#if defined (CONFIG_UCQUICC) - -volatile extern void *_periph_base; -/* sipex transceiver - * mode bits for are on pins - * - * SCC2 d16..19 - * SCC3 d20..23 - * SCC4 d24..27 - */ -#define SIPEX_MODE(n,m) ((m & 0x0f)<<(16+4*(n-1))) - -static uint sipex_mode_bits = 0x00000000; - -#endif - -/* There is no `serial_state' defined back here in 2.0. - * Try to get by with serial_struct - */ -/* #define serial_state serial_struct */ - -/* 2.4 -> 2.0 portability problem: async_icount in 2.4 has a few - * extras: */ - -#if 0 -struct async_icount_24 { - __u32 cts, dsr, rng, dcd, tx, rx; - __u32 frame, parity, overrun, brk; - __u32 buf_overrun; -} icount; -#endif - -#if 0 - -struct serial_state { - int magic; - int baud_base; - unsigned long port; - int irq; - int flags; - int hub6; - int type; - int line; - int revision; /* Chip revision (950) */ - int xmit_fifo_size; - int custom_divisor; - int count; - u8 *iomem_base; - u16 iomem_reg_shift; - unsigned short close_delay; - unsigned short closing_wait; /* time to wait before closing */ - struct async_icount_24 icount; - int io_type; - struct async_struct *info; -}; -#endif - -#define SSTATE_MAGIC 0x5302 - - - -/* SMC2 is sometimes used for low performance TDM interfaces. Define - * this as 1 if you want SMC2 as a serial port UART managed by this driver. - * Define this as 0 if you wish to use SMC2 for something else. - */ -#define USE_SMC2 1 - -#if 0 -/* Define SCC to ttySx mapping. */ -#define SCC_NUM_BASE (USE_SMC2 + 1) /* SCC base tty "number" */ - -/* Define which SCC is the first one to use for a serial port. These - * are 0-based numbers, i.e. this assumes the first SCC (SCC1) is used - * for Ethernet, and the first available SCC for serial UART is SCC2. - * NOTE: IF YOU CHANGE THIS, you have to change the PROFF_xxx and - * interrupt vectors in the table below to match. - */ -#define SCC_IDX_BASE 1 /* table index */ -#endif - - -/* Processors other than the 860 only get SMCs configured by default. - * Either they don't have SCCs or they are allocated somewhere else. - * Of course, there are now 860s without some SCCs, so we will need to - * address that someday. - * The Embedded Planet Multimedia I/O cards use TDM interfaces to the - * stereo codec parts, and we use SMC2 to help support that. - */ -static struct serial_state rs_table[] = { -/* type line PORT IRQ FLAGS smc_scc_num (F.K.A. hub6) */ - { 0, 0, PRSLOT_SMC1, CPMVEC_SMC1, 0, 0 } /* SMC1 ttyS0 */ -#if USE_SMC2 - ,{ 0, 0, PRSLOT_SMC2, CPMVEC_SMC2, 0, 1 } /* SMC2 ttyS1 */ -#endif - -#if defined(CONFIG_SERIAL_68360_SCC) - ,{ 0, 0, PRSLOT_SCC2, CPMVEC_SCC2, 0, (NUM_IS_SCC | 1) } /* SCC2 ttyS2 */ - ,{ 0, 0, PRSLOT_SCC3, CPMVEC_SCC3, 0, (NUM_IS_SCC | 2) } /* SCC3 ttyS3 */ - ,{ 0, 0, PRSLOT_SCC4, CPMVEC_SCC4, 0, (NUM_IS_SCC | 3) } /* SCC4 ttyS4 */ -#endif -}; - -#define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state)) - -/* The number of buffer descriptors and their sizes. - */ -#define RX_NUM_FIFO 4 -#define RX_BUF_SIZE 32 -#define TX_NUM_FIFO 4 -#define TX_BUF_SIZE 32 - -#define CONSOLE_NUM_FIFO 2 -#define CONSOLE_BUF_SIZE 4 - -char *console_fifos[CONSOLE_NUM_FIFO * CONSOLE_BUF_SIZE]; - -/* The async_struct in serial.h does not really give us what we - * need, so define our own here. - */ -typedef struct serial_info { - int magic; - int flags; - - struct serial_state *state; - /* struct serial_struct *state; */ - /* struct async_struct *state; */ - - struct tty_struct *tty; - int read_status_mask; - int ignore_status_mask; - int timeout; - int line; - int x_char; /* xon/xoff character */ - int close_delay; - unsigned short closing_wait; - unsigned short closing_wait2; - unsigned long event; - unsigned long last_active; - int blocked_open; /* # of blocked opens */ - struct work_struct tqueue; - struct work_struct tqueue_hangup; - wait_queue_head_t open_wait; - wait_queue_head_t close_wait; - - -/* CPM Buffer Descriptor pointers. - */ - QUICC_BD *rx_bd_base; - QUICC_BD *rx_cur; - QUICC_BD *tx_bd_base; - QUICC_BD *tx_cur; -} ser_info_t; - - -/* since kmalloc_init() does not get called until much after this initialization: */ -static ser_info_t quicc_ser_info[NR_PORTS]; -static char rx_buf_pool[NR_PORTS * RX_NUM_FIFO * RX_BUF_SIZE]; -static char tx_buf_pool[NR_PORTS * TX_NUM_FIFO * TX_BUF_SIZE]; - -static void change_speed(ser_info_t *info); -static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout); - -static inline int serial_paranoia_check(ser_info_t *info, - char *name, const char *routine) -{ -#ifdef SERIAL_PARANOIA_CHECK - static const char *badmagic = - "Warning: bad magic number for serial struct (%s) in %s\n"; - static const char *badinfo = - "Warning: null async_struct for (%s) in %s\n"; - - if (!info) { - printk(badinfo, name, routine); - return 1; - } - if (info->magic != SERIAL_MAGIC) { - printk(badmagic, name, routine); - return 1; - } -#endif - return 0; -} - -/* - * This is used to figure out the divisor speeds and the timeouts, - * indexed by the termio value. The generic CPM functions are responsible - * for setting and assigning baud rate generators for us. - */ -static int baud_table[] = { - 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, - 9600, 19200, 38400, 57600, 115200, 230400, 460800, 0 }; - -/* This sucks. There is a better way: */ -#if defined(CONFIG_CONSOLE_9600) - #define CONSOLE_BAUDRATE 9600 -#elif defined(CONFIG_CONSOLE_19200) - #define CONSOLE_BAUDRATE 19200 -#elif defined(CONFIG_CONSOLE_115200) - #define CONSOLE_BAUDRATE 115200 -#else - #warning "console baud rate undefined" - #define CONSOLE_BAUDRATE 9600 -#endif - -/* - * ------------------------------------------------------------ - * rs_stop() and rs_start() - * - * This routines are called before setting or resetting tty->stopped. - * They enable or disable transmitter interrupts, as necessary. - * ------------------------------------------------------------ - */ -static void rs_360_stop(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - int idx; - unsigned long flags; - volatile struct scc_regs *sccp; - volatile struct smc_regs *smcp; - - if (serial_paranoia_check(info, tty->name, "rs_stop")) - return; - - local_irq_save(flags); - idx = PORT_NUM(info->state->smc_scc_num); - if (info->state->smc_scc_num & NUM_IS_SCC) { - sccp = &pquicc->scc_regs[idx]; - sccp->scc_sccm &= ~UART_SCCM_TX; - } else { - /* smcp = &cpmp->cp_smc[idx]; */ - smcp = &pquicc->smc_regs[idx]; - smcp->smc_smcm &= ~SMCM_TX; - } - local_irq_restore(flags); -} - - -static void rs_360_start(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - int idx; - unsigned long flags; - volatile struct scc_regs *sccp; - volatile struct smc_regs *smcp; - - if (serial_paranoia_check(info, tty->name, "rs_stop")) - return; - - local_irq_save(flags); - idx = PORT_NUM(info->state->smc_scc_num); - if (info->state->smc_scc_num & NUM_IS_SCC) { - sccp = &pquicc->scc_regs[idx]; - sccp->scc_sccm |= UART_SCCM_TX; - } else { - smcp = &pquicc->smc_regs[idx]; - smcp->smc_smcm |= SMCM_TX; - } - local_irq_restore(flags); -} - -/* - * ---------------------------------------------------------------------- - * - * Here starts the interrupt handling routines. All of the following - * subroutines are declared as inline and are folded into - * rs_interrupt(). They were separated out for readability's sake. - * - * Note: rs_interrupt() is a "fast" interrupt, which means that it - * runs with interrupts turned off. People who may want to modify - * rs_interrupt() should try to keep the interrupt handler as fast as - * possible. After you are done making modifications, it is not a bad - * idea to do: - * - * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c - * - * and look at the resulting assemble code in serial.s. - * - * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 - * ----------------------------------------------------------------------- - */ - -static _INLINE_ void receive_chars(ser_info_t *info) -{ - struct tty_struct *tty = info->port.tty; - unsigned char ch, flag, *cp; - /*int ignored = 0;*/ - int i; - ushort status; - struct async_icount *icount; - /* struct async_icount_24 *icount; */ - volatile QUICC_BD *bdp; - - icount = &info->state->icount; - - /* Just loop through the closed BDs and copy the characters into - * the buffer. - */ - bdp = info->rx_cur; - for (;;) { - if (bdp->status & BD_SC_EMPTY) /* If this one is empty */ - break; /* we are all done */ - - /* The read status mask tell us what we should do with - * incoming characters, especially if errors occur. - * One special case is the use of BD_SC_EMPTY. If - * this is not set, we are supposed to be ignoring - * inputs. In this case, just mark the buffer empty and - * continue. - */ - if (!(info->read_status_mask & BD_SC_EMPTY)) { - bdp->status |= BD_SC_EMPTY; - bdp->status &= - ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV); - - if (bdp->status & BD_SC_WRAP) - bdp = info->rx_bd_base; - else - bdp++; - continue; - } - - /* Get the number of characters and the buffer pointer. - */ - i = bdp->length; - /* cp = (unsigned char *)__va(bdp->buf); */ - cp = (char *)bdp->buf; - status = bdp->status; - - while (i-- > 0) { - ch = *cp++; - icount->rx++; - -#ifdef SERIAL_DEBUG_INTR - printk("DR%02x:%02x...", ch, status); -#endif - flag = TTY_NORMAL; - - if (status & (BD_SC_BR | BD_SC_FR | - BD_SC_PR | BD_SC_OV)) { - /* - * For statistics only - */ - if (status & BD_SC_BR) - icount->brk++; - else if (status & BD_SC_PR) - icount->parity++; - else if (status & BD_SC_FR) - icount->frame++; - if (status & BD_SC_OV) - icount->overrun++; - - /* - * Now check to see if character should be - * ignored, and mask off conditions which - * should be ignored. - if (status & info->ignore_status_mask) { - if (++ignored > 100) - break; - continue; - } - */ - status &= info->read_status_mask; - - if (status & (BD_SC_BR)) { -#ifdef SERIAL_DEBUG_INTR - printk("handling break...."); -#endif - *tty->flip.flag_buf_ptr = TTY_BREAK; - if (info->flags & ASYNC_SAK) - do_SAK(tty); - } else if (status & BD_SC_PR) - flag = TTY_PARITY; - else if (status & BD_SC_FR) - flag = TTY_FRAME; - } - tty_insert_flip_char(tty, ch, flag); - if (status & BD_SC_OV) - /* - * Overrun is special, since it's - * reported immediately, and doesn't - * affect the current character - */ - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - } - - /* This BD is ready to be used again. Clear status. - * Get next BD. - */ - bdp->status |= BD_SC_EMPTY; - bdp->status &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV); - - if (bdp->status & BD_SC_WRAP) - bdp = info->rx_bd_base; - else - bdp++; - } - - info->rx_cur = (QUICC_BD *)bdp; - - tty_schedule_flip(tty); -} - -static _INLINE_ void receive_break(ser_info_t *info) -{ - struct tty_struct *tty = info->port.tty; - - info->state->icount.brk++; - /* Check to see if there is room in the tty buffer for - * the break. If not, we exit now, losing the break. FIXME - */ - tty_insert_flip_char(tty, 0, TTY_BREAK); - tty_schedule_flip(tty); -} - -static _INLINE_ void transmit_chars(ser_info_t *info) -{ - - if ((info->flags & TX_WAKEUP) || - (info->port.tty->flags & (1 << TTY_DO_WRITE_WAKEUP))) { - schedule_work(&info->tqueue); - } - -#ifdef SERIAL_DEBUG_INTR - printk("THRE..."); -#endif -} - -#ifdef notdef - /* I need to do this for the SCCs, so it is left as a reminder. - */ -static _INLINE_ void check_modem_status(struct async_struct *info) -{ - int status; - /* struct async_icount *icount; */ - struct async_icount_24 *icount; - - status = serial_in(info, UART_MSR); - - if (status & UART_MSR_ANY_DELTA) { - icount = &info->state->icount; - /* update input line counters */ - if (status & UART_MSR_TERI) - icount->rng++; - if (status & UART_MSR_DDSR) - icount->dsr++; - if (status & UART_MSR_DDCD) { - icount->dcd++; -#ifdef CONFIG_HARD_PPS - if ((info->flags & ASYNC_HARDPPS_CD) && - (status & UART_MSR_DCD)) - hardpps(); -#endif - } - if (status & UART_MSR_DCTS) - icount->cts++; - wake_up_interruptible(&info->delta_msr_wait); - } - - if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { -#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) - printk("ttys%d CD now %s...", info->line, - (status & UART_MSR_DCD) ? "on" : "off"); -#endif - if (status & UART_MSR_DCD) - wake_up_interruptible(&info->open_wait); - else { -#ifdef SERIAL_DEBUG_OPEN - printk("scheduling hangup..."); -#endif - queue_task(&info->tqueue_hangup, - &tq_scheduler); - } - } - if (info->flags & ASYNC_CTS_FLOW) { - if (info->port.tty->hw_stopped) { - if (status & UART_MSR_CTS) { -#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) - printk("CTS tx start..."); -#endif - info->port.tty->hw_stopped = 0; - info->IER |= UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); - return; - } - } else { - if (!(status & UART_MSR_CTS)) { -#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) - printk("CTS tx stop..."); -#endif - info->port.tty->hw_stopped = 1; - info->IER &= ~UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - } - } - } -} -#endif - -/* - * This is the serial driver's interrupt routine for a single port - */ -/* static void rs_360_interrupt(void *dev_id) */ /* until and if we start servicing irqs here */ -static void rs_360_interrupt(int vec, void *dev_id) -{ - u_char events; - int idx; - ser_info_t *info; - volatile struct smc_regs *smcp; - volatile struct scc_regs *sccp; - - info = dev_id; - - idx = PORT_NUM(info->state->smc_scc_num); - if (info->state->smc_scc_num & NUM_IS_SCC) { - sccp = &pquicc->scc_regs[idx]; - events = sccp->scc_scce; - if (events & SCCM_RX) - receive_chars(info); - if (events & SCCM_TX) - transmit_chars(info); - sccp->scc_scce = events; - } else { - smcp = &pquicc->smc_regs[idx]; - events = smcp->smc_smce; - if (events & SMCM_BRKE) - receive_break(info); - if (events & SMCM_RX) - receive_chars(info); - if (events & SMCM_TX) - transmit_chars(info); - smcp->smc_smce = events; - } - -#ifdef SERIAL_DEBUG_INTR - printk("rs_interrupt_single(%d, %x)...", - info->state->smc_scc_num, events); -#endif -#ifdef modem_control - check_modem_status(info); -#endif - info->last_active = jiffies; -#ifdef SERIAL_DEBUG_INTR - printk("end.\n"); -#endif -} - - -/* - * ------------------------------------------------------------------- - * Here ends the serial interrupt routines. - * ------------------------------------------------------------------- - */ - - -static void do_softint(void *private_) -{ - ser_info_t *info = (ser_info_t *) private_; - struct tty_struct *tty; - - tty = info->port.tty; - if (!tty) - return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) - tty_wakeup(tty); -} - - -/* - * This routine is called from the scheduler tqueue when the interrupt - * routine has signalled that a hangup has occurred. The path of - * hangup processing is: - * - * serial interrupt routine -> (scheduler tqueue) -> - * do_serial_hangup() -> tty->hangup() -> rs_hangup() - * - */ -static void do_serial_hangup(void *private_) -{ - struct async_struct *info = (struct async_struct *) private_; - struct tty_struct *tty; - - tty = info->port.tty; - if (!tty) - return; - - tty_hangup(tty); -} - - -static int startup(ser_info_t *info) -{ - unsigned long flags; - int retval=0; - int idx; - /*struct serial_state *state = info->state;*/ - volatile struct smc_regs *smcp; - volatile struct scc_regs *sccp; - volatile struct smc_uart_pram *up; - volatile struct uart_pram *scup; - - - local_irq_save(flags); - - if (info->flags & ASYNC_INITIALIZED) { - goto errout; - } - -#ifdef maybe - if (!state->port || !state->type) { - if (info->port.tty) - set_bit(TTY_IO_ERROR, &info->port.tty->flags); - goto errout; - } -#endif - -#ifdef SERIAL_DEBUG_OPEN - printk("starting up ttys%d (irq %d)...", info->line, state->irq); -#endif - - -#ifdef modem_control - info->MCR = 0; - if (info->port.tty->termios->c_cflag & CBAUD) - info->MCR = UART_MCR_DTR | UART_MCR_RTS; -#endif - - if (info->port.tty) - clear_bit(TTY_IO_ERROR, &info->port.tty->flags); - - /* - * and set the speed of the serial port - */ - change_speed(info); - - idx = PORT_NUM(info->state->smc_scc_num); - if (info->state->smc_scc_num & NUM_IS_SCC) { - sccp = &pquicc->scc_regs[idx]; - scup = &pquicc->pram[info->state->port].scc.pscc.u; - - scup->mrblr = RX_BUF_SIZE; - scup->max_idl = RX_BUF_SIZE; - - sccp->scc_sccm |= (UART_SCCM_TX | UART_SCCM_RX); - sccp->scc_gsmr.w.low |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); - - } else { - smcp = &pquicc->smc_regs[idx]; - - /* Enable interrupts and I/O. - */ - smcp->smc_smcm |= (SMCM_RX | SMCM_TX); - smcp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN); - - /* We can tune the buffer length and idle characters - * to take advantage of the entire incoming buffer size. - * If mrblr is something other than 1, maxidl has to be - * non-zero or we never get an interrupt. The maxidl - * is the number of character times we wait after reception - * of the last character before we decide no more characters - * are coming. - */ - /* up = (smc_uart_t *)&pquicc->cp_dparam[state->port]; */ - /* holy unionized structures, Batman: */ - up = &pquicc->pram[info->state->port].scc.pothers.idma_smc.psmc.u; - - up->mrblr = RX_BUF_SIZE; - up->max_idl = RX_BUF_SIZE; - - up->brkcr = 1; /* number of break chars */ - } - - info->flags |= ASYNC_INITIALIZED; - local_irq_restore(flags); - return 0; - -errout: - local_irq_restore(flags); - return retval; -} - -/* - * This routine will shutdown a serial port; interrupts are disabled, and - * DTR is dropped if the hangup on close termio flag is on. - */ -static void shutdown(ser_info_t *info) -{ - unsigned long flags; - struct serial_state *state; - int idx; - volatile struct smc_regs *smcp; - volatile struct scc_regs *sccp; - - if (!(info->flags & ASYNC_INITIALIZED)) - return; - - state = info->state; - -#ifdef SERIAL_DEBUG_OPEN - printk("Shutting down serial port %d (irq %d)....", info->line, - state->irq); -#endif - - local_irq_save(flags); - - idx = PORT_NUM(state->smc_scc_num); - if (state->smc_scc_num & NUM_IS_SCC) { - sccp = &pquicc->scc_regs[idx]; - sccp->scc_gsmr.w.low &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); -#ifdef CONFIG_SERIAL_CONSOLE - /* We can't disable the transmitter if this is the - * system console. - */ - if ((state - rs_table) != CONFIG_SERIAL_CONSOLE_PORT) -#endif - sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); - } else { - smcp = &pquicc->smc_regs[idx]; - - /* Disable interrupts and I/O. - */ - smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); -#ifdef CONFIG_SERIAL_CONSOLE - /* We can't disable the transmitter if this is the - * system console. - */ - if ((state - rs_table) != CONFIG_SERIAL_CONSOLE_PORT) -#endif - smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); - } - - if (info->port.tty) - set_bit(TTY_IO_ERROR, &info->port.tty->flags); - - info->flags &= ~ASYNC_INITIALIZED; - local_irq_restore(flags); -} - -/* - * This routine is called to set the UART divisor registers to match - * the specified baud rate for a serial port. - */ -static void change_speed(ser_info_t *info) -{ - int baud_rate; - unsigned cflag, cval, scval, prev_mode; - int i, bits, sbits, idx; - unsigned long flags; - struct serial_state *state; - volatile struct smc_regs *smcp; - volatile struct scc_regs *sccp; - - if (!info->port.tty || !info->port.tty->termios) - return; - cflag = info->port.tty->termios->c_cflag; - - state = info->state; - - /* Character length programmed into the mode register is the - * sum of: 1 start bit, number of data bits, 0 or 1 parity bit, - * 1 or 2 stop bits, minus 1. - * The value 'bits' counts this for us. - */ - cval = 0; - scval = 0; - - /* byte size and parity */ - switch (cflag & CSIZE) { - case CS5: bits = 5; break; - case CS6: bits = 6; break; - case CS7: bits = 7; break; - case CS8: bits = 8; break; - /* Never happens, but GCC is too dumb to figure it out */ - default: bits = 8; break; - } - sbits = bits - 5; - - if (cflag & CSTOPB) { - cval |= SMCMR_SL; /* Two stops */ - scval |= SCU_PMSR_SL; - bits++; - } - if (cflag & PARENB) { - cval |= SMCMR_PEN; - scval |= SCU_PMSR_PEN; - bits++; - } - if (!(cflag & PARODD)) { - cval |= SMCMR_PM_EVEN; - scval |= (SCU_PMSR_REVP | SCU_PMSR_TEVP); - } - - /* Determine divisor based on baud rate */ - i = cflag & CBAUD; - if (i >= (sizeof(baud_table)/sizeof(int))) - baud_rate = 9600; - else - baud_rate = baud_table[i]; - - info->timeout = (TX_BUF_SIZE*HZ*bits); - info->timeout += HZ/50; /* Add .02 seconds of slop */ - -#ifdef modem_control - /* CTS flow control flag and modem status interrupts */ - info->IER &= ~UART_IER_MSI; - if (info->flags & ASYNC_HARDPPS_CD) - info->IER |= UART_IER_MSI; - if (cflag & CRTSCTS) { - info->flags |= ASYNC_CTS_FLOW; - info->IER |= UART_IER_MSI; - } else - info->flags &= ~ASYNC_CTS_FLOW; - if (cflag & CLOCAL) - info->flags &= ~ASYNC_CHECK_CD; - else { - info->flags |= ASYNC_CHECK_CD; - info->IER |= UART_IER_MSI; - } - serial_out(info, UART_IER, info->IER); -#endif - - /* - * Set up parity check flag - */ - info->read_status_mask = (BD_SC_EMPTY | BD_SC_OV); - if (I_INPCK(info->port.tty)) - info->read_status_mask |= BD_SC_FR | BD_SC_PR; - if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty)) - info->read_status_mask |= BD_SC_BR; - - /* - * Characters to ignore - */ - info->ignore_status_mask = 0; - if (I_IGNPAR(info->port.tty)) - info->ignore_status_mask |= BD_SC_PR | BD_SC_FR; - if (I_IGNBRK(info->port.tty)) { - info->ignore_status_mask |= BD_SC_BR; - /* - * If we're ignore parity and break indicators, ignore - * overruns too. (For real raw support). - */ - if (I_IGNPAR(info->port.tty)) - info->ignore_status_mask |= BD_SC_OV; - } - /* - * !!! ignore all characters if CREAD is not set - */ - if ((cflag & CREAD) == 0) - info->read_status_mask &= ~BD_SC_EMPTY; - local_irq_save(flags); - - /* Start bit has not been added (so don't, because we would just - * subtract it later), and we need to add one for the number of - * stops bits (there is always at least one). - */ - bits++; - idx = PORT_NUM(state->smc_scc_num); - if (state->smc_scc_num & NUM_IS_SCC) { - sccp = &pquicc->scc_regs[idx]; - sccp->scc_psmr = (sbits << 12) | scval; - } else { - smcp = &pquicc->smc_regs[idx]; - - /* Set the mode register. We want to keep a copy of the - * enables, because we want to put them back if they were - * present. - */ - prev_mode = smcp->smc_smcmr; - smcp->smc_smcmr = smcr_mk_clen(bits) | cval | SMCMR_SM_UART; - smcp->smc_smcmr |= (prev_mode & (SMCMR_REN | SMCMR_TEN)); - } - - m360_cpm_setbrg((state - rs_table), baud_rate); - - local_irq_restore(flags); -} - -static void rs_360_put_char(struct tty_struct *tty, unsigned char ch) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - volatile QUICC_BD *bdp; - - if (serial_paranoia_check(info, tty->name, "rs_put_char")) - return 0; - - if (!tty) - return 0; - - bdp = info->tx_cur; - while (bdp->status & BD_SC_READY); - - /* *((char *)__va(bdp->buf)) = ch; */ - *((char *)bdp->buf) = ch; - bdp->length = 1; - bdp->status |= BD_SC_READY; - - /* Get next BD. - */ - if (bdp->status & BD_SC_WRAP) - bdp = info->tx_bd_base; - else - bdp++; - - info->tx_cur = (QUICC_BD *)bdp; - return 1; - -} - -static int rs_360_write(struct tty_struct * tty, - const unsigned char *buf, int count) -{ - int c, ret = 0; - ser_info_t *info = (ser_info_t *)tty->driver_data; - volatile QUICC_BD *bdp; - -#ifdef CONFIG_KGDB - /* Try to let stub handle output. Returns true if it did. */ - if (kgdb_output_string(buf, count)) - return ret; -#endif - - if (serial_paranoia_check(info, tty->name, "rs_write")) - return 0; - - if (!tty) - return 0; - - bdp = info->tx_cur; - - while (1) { - c = min(count, TX_BUF_SIZE); - - if (c <= 0) - break; - - if (bdp->status & BD_SC_READY) { - info->flags |= TX_WAKEUP; - break; - } - - /* memcpy(__va(bdp->buf), buf, c); */ - memcpy((void *)bdp->buf, buf, c); - - bdp->length = c; - bdp->status |= BD_SC_READY; - - buf += c; - count -= c; - ret += c; - - /* Get next BD. - */ - if (bdp->status & BD_SC_WRAP) - bdp = info->tx_bd_base; - else - bdp++; - info->tx_cur = (QUICC_BD *)bdp; - } - return ret; -} - -static int rs_360_write_room(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - int ret; - - if (serial_paranoia_check(info, tty->name, "rs_write_room")) - return 0; - - if ((info->tx_cur->status & BD_SC_READY) == 0) { - info->flags &= ~TX_WAKEUP; - ret = TX_BUF_SIZE; - } - else { - info->flags |= TX_WAKEUP; - ret = 0; - } - return ret; -} - -/* I could track this with transmit counters....maybe later. -*/ -static int rs_360_chars_in_buffer(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer")) - return 0; - return 0; -} - -static void rs_360_flush_buffer(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) - return; - - /* There is nothing to "flush", whatever we gave the CPM - * is on its way out. - */ - tty_wakeup(tty); - info->flags &= ~TX_WAKEUP; -} - -/* - * This function is used to send a high-priority XON/XOFF character to - * the device - */ -static void rs_360_send_xchar(struct tty_struct *tty, char ch) -{ - volatile QUICC_BD *bdp; - - ser_info_t *info = (ser_info_t *)tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_send_char")) - return; - - bdp = info->tx_cur; - while (bdp->status & BD_SC_READY); - - /* *((char *)__va(bdp->buf)) = ch; */ - *((char *)bdp->buf) = ch; - bdp->length = 1; - bdp->status |= BD_SC_READY; - - /* Get next BD. - */ - if (bdp->status & BD_SC_WRAP) - bdp = info->tx_bd_base; - else - bdp++; - - info->tx_cur = (QUICC_BD *)bdp; -} - -/* - * ------------------------------------------------------------ - * rs_throttle() - * - * This routine is called by the upper-layer tty layer to signal that - * incoming characters should be throttled. - * ------------------------------------------------------------ - */ -static void rs_360_throttle(struct tty_struct * tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("throttle %s: %d....\n", _tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->name, "rs_throttle")) - return; - - if (I_IXOFF(tty)) - rs_360_send_xchar(tty, STOP_CHAR(tty)); - -#ifdef modem_control - if (tty->termios->c_cflag & CRTSCTS) - info->MCR &= ~UART_MCR_RTS; - - local_irq_disable(); - serial_out(info, UART_MCR, info->MCR); - local_irq_enable(); -#endif -} - -static void rs_360_unthrottle(struct tty_struct * tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("unthrottle %s: %d....\n", _tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->name, "rs_unthrottle")) - return; - - if (I_IXOFF(tty)) { - if (info->x_char) - info->x_char = 0; - else - rs_360_send_xchar(tty, START_CHAR(tty)); - } -#ifdef modem_control - if (tty->termios->c_cflag & CRTSCTS) - info->MCR |= UART_MCR_RTS; - local_irq_disable(); - serial_out(info, UART_MCR, info->MCR); - local_irq_enable(); -#endif -} - -/* - * ------------------------------------------------------------ - * rs_ioctl() and friends - * ------------------------------------------------------------ - */ - -#ifdef maybe -/* - * get_lsr_info - get line status register info - * - * Purpose: Let user call ioctl() to get info when the UART physically - * is emptied. On bus types like RS485, the transmitter must - * release the bus after transmitting. This must be done when - * the transmit shift register is empty, not be done when the - * transmit holding register is empty. This functionality - * allows an RS485 driver to be written in user space. - */ -static int get_lsr_info(struct async_struct * info, unsigned int *value) -{ - unsigned char status; - unsigned int result; - - local_irq_disable(); - status = serial_in(info, UART_LSR); - local_irq_enable(); - result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); - return put_user(result,value); -} -#endif - -static int rs_360_tiocmget(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - unsigned int result = 0; -#ifdef modem_control - unsigned char control, status; - - if (serial_paranoia_check(info, tty->name, __func__)) - return -ENODEV; - - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - - control = info->MCR; - local_irq_disable(); - status = serial_in(info, UART_MSR); - local_irq_enable(); - result = ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) - | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) -#ifdef TIOCM_OUT1 - | ((control & UART_MCR_OUT1) ? TIOCM_OUT1 : 0) - | ((control & UART_MCR_OUT2) ? TIOCM_OUT2 : 0) -#endif - | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) - | ((status & UART_MSR_RI) ? TIOCM_RNG : 0) - | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0) - | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0); -#endif - return result; -} - -static int rs_360_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ -#ifdef modem_control - ser_info_t *info = (ser_info_t *)tty->driver_data; - unsigned int arg; - - if (serial_paranoia_check(info, tty->name, __func__)) - return -ENODEV; - - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - /* FIXME: locking on info->mcr */ - if (set & TIOCM_RTS) - info->mcr |= UART_MCR_RTS; - if (set & TIOCM_DTR) - info->mcr |= UART_MCR_DTR; - if (clear & TIOCM_RTS) - info->MCR &= ~UART_MCR_RTS; - if (clear & TIOCM_DTR) - info->MCR &= ~UART_MCR_DTR; - -#ifdef TIOCM_OUT1 - if (set & TIOCM_OUT1) - info->MCR |= UART_MCR_OUT1; - if (set & TIOCM_OUT2) - info->MCR |= UART_MCR_OUT2; - if (clear & TIOCM_OUT1) - info->MCR &= ~UART_MCR_OUT1; - if (clear & TIOCM_OUT2) - info->MCR &= ~UART_MCR_OUT2; -#endif - - local_irq_disable(); - serial_out(info, UART_MCR, info->MCR); - local_irq_enable(); -#endif - return 0; -} - -/* Sending a break is a two step process on the SMC/SCC. It is accomplished - * by sending a STOP TRANSMIT command followed by a RESTART TRANSMIT - * command. We take advantage of the begin/end functions to make this - * happen. - */ -static ushort smc_chan_map[] = { - CPM_CR_CH_SMC1, - CPM_CR_CH_SMC2 -}; - -static ushort scc_chan_map[] = { - CPM_CR_CH_SCC1, - CPM_CR_CH_SCC2, - CPM_CR_CH_SCC3, - CPM_CR_CH_SCC4 -}; - -static void begin_break(ser_info_t *info) -{ - volatile QUICC *cp; - ushort chan; - int idx; - - cp = pquicc; - - idx = PORT_NUM(info->state->smc_scc_num); - if (info->state->smc_scc_num & NUM_IS_SCC) - chan = scc_chan_map[idx]; - else - chan = smc_chan_map[idx]; - - cp->cp_cr = mk_cr_cmd(chan, CPM_CR_STOP_TX) | CPM_CR_FLG; - while (cp->cp_cr & CPM_CR_FLG); -} - -static void end_break(ser_info_t *info) -{ - volatile QUICC *cp; - ushort chan; - int idx; - - cp = pquicc; - - idx = PORT_NUM(info->state->smc_scc_num); - if (info->state->smc_scc_num & NUM_IS_SCC) - chan = scc_chan_map[idx]; - else - chan = smc_chan_map[idx]; - - cp->cp_cr = mk_cr_cmd(chan, CPM_CR_RESTART_TX) | CPM_CR_FLG; - while (cp->cp_cr & CPM_CR_FLG); -} - -/* - * This routine sends a break character out the serial port. - */ -static void send_break(ser_info_t *info, unsigned int duration) -{ -#ifdef SERIAL_DEBUG_SEND_BREAK - printk("rs_send_break(%d) jiff=%lu...", duration, jiffies); -#endif - begin_break(info); - msleep_interruptible(duration); - end_break(info); -#ifdef SERIAL_DEBUG_SEND_BREAK - printk("done jiffies=%lu\n", jiffies); -#endif -} - - -/* - * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) - * Return: write counters to the user passed counter struct - * NB: both 1->0 and 0->1 transitions are counted except for - * RI where only 0->1 is counted. - */ -static int rs_360_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - struct async_icount cnow; - - local_irq_disable(); - cnow = info->state->icount; - local_irq_enable(); - - icount->cts = cnow.cts; - icount->dsr = cnow.dsr; - icount->rng = cnow.rng; - icount->dcd = cnow.dcd; - - return 0; -} - -static int rs_360_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - int error; - ser_info_t *info = (ser_info_t *)tty->driver_data; - int retval; - struct async_icount cnow; - /* struct async_icount_24 cnow;*/ /* kernel counter temps */ - struct serial_icounter_struct *p_cuser; /* user space */ - - if (serial_paranoia_check(info, tty->name, "rs_ioctl")) - return -ENODEV; - - if (cmd != TIOCMIWAIT) { - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - } - - switch (cmd) { - case TCSBRK: /* SVID version: non-zero arg --> no break */ - retval = tty_check_change(tty); - if (retval) - return retval; - tty_wait_until_sent(tty, 0); - if (signal_pending(current)) - return -EINTR; - if (!arg) { - send_break(info, 250); /* 1/4 second */ - if (signal_pending(current)) - return -EINTR; - } - return 0; - case TCSBRKP: /* support for POSIX tcsendbreak() */ - retval = tty_check_change(tty); - if (retval) - return retval; - tty_wait_until_sent(tty, 0); - if (signal_pending(current)) - return -EINTR; - send_break(info, arg ? arg*100 : 250); - if (signal_pending(current)) - return -EINTR; - return 0; - case TIOCSBRK: - retval = tty_check_change(tty); - if (retval) - return retval; - tty_wait_until_sent(tty, 0); - begin_break(info); - return 0; - case TIOCCBRK: - retval = tty_check_change(tty); - if (retval) - return retval; - end_break(info); - return 0; -#ifdef maybe - case TIOCSERGETLSR: /* Get line status register */ - return get_lsr_info(info, (unsigned int *) arg); -#endif - /* - * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - * - mask passed in arg for lines of interest - * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) - * Caller should use TIOCGICOUNT to see which one it was - */ - case TIOCMIWAIT: -#ifdef modem_control - local_irq_disable(); - /* note the counters on entry */ - cprev = info->state->icount; - local_irq_enable(); - while (1) { - interruptible_sleep_on(&info->delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - local_irq_disable(); - cnow = info->state->icount; /* atomic copy */ - local_irq_enable(); - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) - return -EIO; /* no change => error */ - if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { - return 0; - } - cprev = cnow; - } - /* NOTREACHED */ -#else - return 0; -#endif - - - default: - return -ENOIOCTLCMD; - } - return 0; -} - -/* FIX UP modem control here someday...... -*/ -static void rs_360_set_termios(struct tty_struct *tty, struct ktermios *old_termios) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - - change_speed(info); - -#ifdef modem_control - /* Handle transition to B0 status */ - if ((old_termios->c_cflag & CBAUD) && - !(tty->termios->c_cflag & CBAUD)) { - info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); - local_irq_disable(); - serial_out(info, UART_MCR, info->MCR); - local_irq_enable(); - } - - /* Handle transition away from B0 status */ - if (!(old_termios->c_cflag & CBAUD) && - (tty->termios->c_cflag & CBAUD)) { - info->MCR |= UART_MCR_DTR; - if (!tty->hw_stopped || - !(tty->termios->c_cflag & CRTSCTS)) { - info->MCR |= UART_MCR_RTS; - } - local_irq_disable(); - serial_out(info, UART_MCR, info->MCR); - local_irq_enable(); - } - - /* Handle turning off CRTSCTS */ - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - rs_360_start(tty); - } -#endif - -#if 0 - /* - * No need to wake up processes in open wait, since they - * sample the CLOCAL flag once, and don't recheck it. - * XXX It's not clear whether the current behavior is correct - * or not. Hence, this may change..... - */ - if (!(old_termios->c_cflag & CLOCAL) && - (tty->termios->c_cflag & CLOCAL)) - wake_up_interruptible(&info->open_wait); -#endif -} - -/* - * ------------------------------------------------------------ - * rs_close() - * - * This routine is called when the serial port gets closed. First, we - * wait for the last remaining data to be sent. Then, we unlink its - * async structure from the interrupt chain if necessary, and we free - * that IRQ if nothing is left in the chain. - * ------------------------------------------------------------ - */ -static void rs_360_close(struct tty_struct *tty, struct file * filp) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - /* struct async_state *state; */ - struct serial_state *state; - unsigned long flags; - int idx; - volatile struct smc_regs *smcp; - volatile struct scc_regs *sccp; - - if (!info || serial_paranoia_check(info, tty->name, "rs_close")) - return; - - state = info->state; - - local_irq_save(flags); - - if (tty_hung_up_p(filp)) { - DBG_CNT("before DEC-hung"); - local_irq_restore(flags); - return; - } - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_close ttys%d, count = %d\n", info->line, state->count); -#endif - if ((tty->count == 1) && (state->count != 1)) { - /* - * Uh, oh. tty->count is 1, which means that the tty - * structure will be freed. state->count should always - * be one in these conditions. If it's greater than - * one, we've got real problems, since it means the - * serial port won't be shutdown. - */ - printk("rs_close: bad serial port count; tty->count is 1, " - "state->count is %d\n", state->count); - state->count = 1; - } - if (--state->count < 0) { - printk("rs_close: bad serial port count for ttys%d: %d\n", - info->line, state->count); - state->count = 0; - } - if (state->count) { - DBG_CNT("before DEC-2"); - local_irq_restore(flags); - return; - } - info->flags |= ASYNC_CLOSING; - /* - * Now we wait for the transmit buffer to clear; and we notify - * the line discipline to only process XON/XOFF characters. - */ - tty->closing = 1; - if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) - tty_wait_until_sent(tty, info->closing_wait); - /* - * At this point we stop accepting input. To do this, we - * disable the receive line status interrupts, and tell the - * interrupt driver to stop checking the data ready bit in the - * line status register. - */ - info->read_status_mask &= ~BD_SC_EMPTY; - if (info->flags & ASYNC_INITIALIZED) { - - idx = PORT_NUM(info->state->smc_scc_num); - if (info->state->smc_scc_num & NUM_IS_SCC) { - sccp = &pquicc->scc_regs[idx]; - sccp->scc_sccm &= ~UART_SCCM_RX; - sccp->scc_gsmr.w.low &= ~SCC_GSMRL_ENR; - } else { - smcp = &pquicc->smc_regs[idx]; - smcp->smc_smcm &= ~SMCM_RX; - smcp->smc_smcmr &= ~SMCMR_REN; - } - /* - * Before we drop DTR, make sure the UART transmitter - * has completely drained; this is especially - * important if there is a transmit FIFO! - */ - rs_360_wait_until_sent(tty, info->timeout); - } - shutdown(info); - rs_360_flush_buffer(tty); - tty_ldisc_flush(tty); - tty->closing = 0; - info->event = 0; - info->port.tty = NULL; - if (info->blocked_open) { - if (info->close_delay) { - msleep_interruptible(jiffies_to_msecs(info->close_delay)); - } - wake_up_interruptible(&info->open_wait); - } - info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); - wake_up_interruptible(&info->close_wait); - local_irq_restore(flags); -} - -/* - * rs_wait_until_sent() --- wait until the transmitter is empty - */ -static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - unsigned long orig_jiffies, char_time; - /*int lsr;*/ - volatile QUICC_BD *bdp; - - if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent")) - return; - -#ifdef maybe - if (info->state->type == PORT_UNKNOWN) - return; -#endif - - orig_jiffies = jiffies; - /* - * Set the check interval to be 1/5 of the estimated time to - * send a single character, and make it at least 1. The check - * interval should also be less than the timeout. - * - * Note: we have to use pretty tight timings here to satisfy - * the NIST-PCTS. - */ - char_time = 1; - if (timeout) - char_time = min(char_time, (unsigned long)timeout); -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time); - printk("jiff=%lu...", jiffies); -#endif - - /* We go through the loop at least once because we can't tell - * exactly when the last character exits the shifter. There can - * be at least two characters waiting to be sent after the buffers - * are empty. - */ - do { -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("lsr = %d (jiff=%lu)...", lsr, jiffies); -#endif -/* current->counter = 0; make us low-priority */ - msleep_interruptible(jiffies_to_msecs(char_time)); - if (signal_pending(current)) - break; - if (timeout && (time_after(jiffies, orig_jiffies + timeout))) - break; - /* The 'tx_cur' is really the next buffer to send. We - * have to back up to the previous BD and wait for it - * to go. This isn't perfect, because all this indicates - * is the buffer is available. There are still characters - * in the CPM FIFO. - */ - bdp = info->tx_cur; - if (bdp == info->tx_bd_base) - bdp += (TX_NUM_FIFO-1); - else - bdp--; - } while (bdp->status & BD_SC_READY); - current->state = TASK_RUNNING; -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); -#endif -} - -/* - * rs_hangup() --- called by tty_hangup() when a hangup is signaled. - */ -static void rs_360_hangup(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - struct serial_state *state = info->state; - - if (serial_paranoia_check(info, tty->name, "rs_hangup")) - return; - - state = info->state; - - rs_360_flush_buffer(tty); - shutdown(info); - info->event = 0; - state->count = 0; - info->flags &= ~ASYNC_NORMAL_ACTIVE; - info->port.tty = NULL; - wake_up_interruptible(&info->open_wait); -} - -/* - * ------------------------------------------------------------ - * rs_open() and friends - * ------------------------------------------------------------ - */ -static int block_til_ready(struct tty_struct *tty, struct file * filp, - ser_info_t *info) -{ -#ifdef DO_THIS_LATER - DECLARE_WAITQUEUE(wait, current); -#endif - struct serial_state *state = info->state; - int retval; - int do_clocal = 0; - - /* - * If the device is in the middle of being closed, then block - * until it's done, and then try again. - */ - if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); -#ifdef SERIAL_DO_RESTART - if (info->flags & ASYNC_HUP_NOTIFY) - return -EAGAIN; - else - return -ERESTARTSYS; -#else - return -EAGAIN; -#endif - } - - /* - * If non-blocking mode is set, or the port is not enabled, - * then make the check up front and then exit. - * If this is an SMC port, we don't have modem control to wait - * for, so just get out here. - */ - if ((filp->f_flags & O_NONBLOCK) || - (tty->flags & (1 << TTY_IO_ERROR)) || - !(info->state->smc_scc_num & NUM_IS_SCC)) { - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; - } - - if (tty->termios->c_cflag & CLOCAL) - do_clocal = 1; - - /* - * Block waiting for the carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, state->count is dropped by one, so that - * rs_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - retval = 0; -#ifdef DO_THIS_LATER - add_wait_queue(&info->open_wait, &wait); -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready before block: ttys%d, count = %d\n", - state->line, state->count); -#endif - local_irq_disable(); - if (!tty_hung_up_p(filp)) - state->count--; - local_irq_enable(); - info->blocked_open++; - while (1) { - local_irq_disable(); - if (tty->termios->c_cflag & CBAUD) - serial_out(info, UART_MCR, - serial_inp(info, UART_MCR) | - (UART_MCR_DTR | UART_MCR_RTS)); - local_irq_enable(); - set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || - !(info->flags & ASYNC_INITIALIZED)) { -#ifdef SERIAL_DO_RESTART - if (info->flags & ASYNC_HUP_NOTIFY) - retval = -EAGAIN; - else - retval = -ERESTARTSYS; -#else - retval = -EAGAIN; -#endif - break; - } - if (!(info->flags & ASYNC_CLOSING) && - (do_clocal || (serial_in(info, UART_MSR) & - UART_MSR_DCD))) - break; - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready blocking: ttys%d, count = %d\n", - info->line, state->count); -#endif - tty_unlock(); - schedule(); - tty_lock(); - } - current->state = TASK_RUNNING; - remove_wait_queue(&info->open_wait, &wait); - if (!tty_hung_up_p(filp)) - state->count++; - info->blocked_open--; -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready after blocking: ttys%d, count = %d\n", - info->line, state->count); -#endif -#endif /* DO_THIS_LATER */ - if (retval) - return retval; - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; -} - -static int get_async_struct(int line, ser_info_t **ret_info) -{ - struct serial_state *sstate; - - sstate = rs_table + line; - if (sstate->info) { - sstate->count++; - *ret_info = (ser_info_t *)sstate->info; - return 0; - } - else { - return -ENOMEM; - } -} - -/* - * This routine is called whenever a serial port is opened. It - * enables interrupts for a serial port, linking in its async structure into - * the IRQ chain. It also performs the serial-specific - * initialization for the tty structure. - */ -static int rs_360_open(struct tty_struct *tty, struct file * filp) -{ - ser_info_t *info; - int retval, line; - - line = tty->index; - if ((line < 0) || (line >= NR_PORTS)) - return -ENODEV; - retval = get_async_struct(line, &info); - if (retval) - return retval; - if (serial_paranoia_check(info, tty->name, "rs_open")) - return -ENODEV; - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open %s, count = %d\n", tty->name, info->state->count); -#endif - tty->driver_data = info; - info->port.tty = tty; - - /* - * Start up serial port - */ - retval = startup(info); - if (retval) - return retval; - - retval = block_til_ready(tty, filp, info); - if (retval) { -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open returning after block_til_ready with %d\n", - retval); -#endif - return retval; - } - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open %s successful...", tty->name); -#endif - return 0; -} - -/* - * /proc fs routines.... - */ - -static inline int line_info(char *buf, struct serial_state *state) -{ -#ifdef notdef - struct async_struct *info = state->info, scr_info; - char stat_buf[30], control, status; -#endif - int ret; - - ret = sprintf(buf, "%d: uart:%s port:%X irq:%d", - state->line, - (state->smc_scc_num & NUM_IS_SCC) ? "SCC" : "SMC", - (unsigned int)(state->port), state->irq); - - if (!state->port || (state->type == PORT_UNKNOWN)) { - ret += sprintf(buf+ret, "\n"); - return ret; - } - -#ifdef notdef - /* - * Figure out the current RS-232 lines - */ - if (!info) { - info = &scr_info; /* This is just for serial_{in,out} */ - - info->magic = SERIAL_MAGIC; - info->port = state->port; - info->flags = state->flags; - info->quot = 0; - info->port.tty = NULL; - } - local_irq_disable(); - status = serial_in(info, UART_MSR); - control = info ? info->MCR : serial_in(info, UART_MCR); - local_irq_enable(); - - stat_buf[0] = 0; - stat_buf[1] = 0; - if (control & UART_MCR_RTS) - strcat(stat_buf, "|RTS"); - if (status & UART_MSR_CTS) - strcat(stat_buf, "|CTS"); - if (control & UART_MCR_DTR) - strcat(stat_buf, "|DTR"); - if (status & UART_MSR_DSR) - strcat(stat_buf, "|DSR"); - if (status & UART_MSR_DCD) - strcat(stat_buf, "|CD"); - if (status & UART_MSR_RI) - strcat(stat_buf, "|RI"); - - if (info->quot) { - ret += sprintf(buf+ret, " baud:%d", - state->baud_base / info->quot); - } - - ret += sprintf(buf+ret, " tx:%d rx:%d", - state->icount.tx, state->icount.rx); - - if (state->icount.frame) - ret += sprintf(buf+ret, " fe:%d", state->icount.frame); - - if (state->icount.parity) - ret += sprintf(buf+ret, " pe:%d", state->icount.parity); - - if (state->icount.brk) - ret += sprintf(buf+ret, " brk:%d", state->icount.brk); - - if (state->icount.overrun) - ret += sprintf(buf+ret, " oe:%d", state->icount.overrun); - - /* - * Last thing is the RS-232 status lines - */ - ret += sprintf(buf+ret, " %s\n", stat_buf+1); -#endif - return ret; -} - -int rs_360_read_proc(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - int i, len = 0; - off_t begin = 0; - - len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version); - for (i = 0; i < NR_PORTS && len < 4000; i++) { - len += line_info(page + len, &rs_table[i]); - if (len+begin > off+count) - goto done; - if (len+begin < off) { - begin += len; - len = 0; - } - } - *eof = 1; -done: - if (off >= len+begin) - return 0; - *start = page + (begin-off); - return ((count < begin+len-off) ? count : begin+len-off); -} - -/* - * --------------------------------------------------------------------- - * rs_init() and friends - * - * rs_init() is called at boot-time to initialize the serial driver. - * --------------------------------------------------------------------- - */ - -/* - * This routine prints out the appropriate serial driver version - * number, and identifies which options were configured into this - * driver. - */ -static _INLINE_ void show_serial_version(void) -{ - printk(KERN_INFO "%s version %s\n", serial_name, serial_version); -} - - -/* - * The serial console driver used during boot. Note that these names - * clash with those found in "serial.c", so we currently can't support - * the 16xxx uarts and these at the same time. I will fix this to become - * an indirect function call from tty_io.c (or something). - */ - -#ifdef CONFIG_SERIAL_CONSOLE - -/* - * Print a string to the serial port trying not to disturb any possible - * real use of the port... - */ -static void my_console_write(int idx, const char *s, - unsigned count) -{ - struct serial_state *ser; - ser_info_t *info; - unsigned i; - QUICC_BD *bdp, *bdbase; - volatile struct smc_uart_pram *up; - volatile u_char *cp; - - ser = rs_table + idx; - - - /* If the port has been initialized for general use, we have - * to use the buffer descriptors allocated there. Otherwise, - * we simply use the single buffer allocated. - */ - if ((info = (ser_info_t *)ser->info) != NULL) { - bdp = info->tx_cur; - bdbase = info->tx_bd_base; - } - else { - /* Pointer to UART in parameter ram. - */ - /* up = (smc_uart_t *)&cpmp->cp_dparam[ser->port]; */ - up = &pquicc->pram[ser->port].scc.pothers.idma_smc.psmc.u; - - /* Get the address of the host memory buffer. - */ - bdp = bdbase = (QUICC_BD *)((uint)pquicc + (uint)up->tbase); - } - - /* - * We need to gracefully shut down the transmitter, disable - * interrupts, then send our bytes out. - */ - - /* - * Now, do each character. This is not as bad as it looks - * since this is a holding FIFO and not a transmitting FIFO. - * We could add the complexity of filling the entire transmit - * buffer, but we would just wait longer between accesses...... - */ - for (i = 0; i < count; i++, s++) { - /* Wait for transmitter fifo to empty. - * Ready indicates output is ready, and xmt is doing - * that, not that it is ready for us to send. - */ - while (bdp->status & BD_SC_READY); - - /* Send the character out. - */ - cp = bdp->buf; - *cp = *s; - - bdp->length = 1; - bdp->status |= BD_SC_READY; - - if (bdp->status & BD_SC_WRAP) - bdp = bdbase; - else - bdp++; - - /* if a LF, also do CR... */ - if (*s == 10) { - while (bdp->status & BD_SC_READY); - /* cp = __va(bdp->buf); */ - cp = bdp->buf; - *cp = 13; - bdp->length = 1; - bdp->status |= BD_SC_READY; - - if (bdp->status & BD_SC_WRAP) { - bdp = bdbase; - } - else { - bdp++; - } - } - } - - /* - * Finally, Wait for transmitter & holding register to empty - * and restore the IER - */ - while (bdp->status & BD_SC_READY); - - if (info) - info->tx_cur = (QUICC_BD *)bdp; -} - -static void serial_console_write(struct console *c, const char *s, - unsigned count) -{ -#ifdef CONFIG_KGDB - /* Try to let stub handle output. Returns true if it did. */ - if (kgdb_output_string(s, count)) - return; -#endif - my_console_write(c->index, s, count); -} - - - -/*void console_print_68360(const char *p) -{ - const char *cp = p; - int i; - - for (i=0;cp[i]!=0;i++); - - serial_console_write (p, i); - - //Comment this if you want to have a strict interrupt-driven output - //rs_fair_output(); - - return; -}*/ - - - - - - -#ifdef CONFIG_XMON -int -xmon_360_write(const char *s, unsigned count) -{ - my_console_write(0, s, count); - return(count); -} -#endif - -#ifdef CONFIG_KGDB -void -putDebugChar(char ch) -{ - my_console_write(0, &ch, 1); -} -#endif - -/* - * Receive character from the serial port. This only works well - * before the port is initialized for real use. - */ -static int my_console_wait_key(int idx, int xmon, char *obuf) -{ - struct serial_state *ser; - u_char c, *cp; - ser_info_t *info; - QUICC_BD *bdp; - volatile struct smc_uart_pram *up; - int i; - - ser = rs_table + idx; - - /* Get the address of the host memory buffer. - * If the port has been initialized for general use, we must - * use information from the port structure. - */ - if ((info = (ser_info_t *)ser->info)) - bdp = info->rx_cur; - else - /* bdp = (QUICC_BD *)&cpmp->cp_dpmem[up->smc_rbase]; */ - bdp = (QUICC_BD *)((uint)pquicc + (uint)up->tbase); - - /* Pointer to UART in parameter ram. - */ - /* up = (smc_uart_t *)&cpmp->cp_dparam[ser->port]; */ - up = &pquicc->pram[info->state->port].scc.pothers.idma_smc.psmc.u; - - /* - * We need to gracefully shut down the receiver, disable - * interrupts, then read the input. - * XMON just wants a poll. If no character, return -1, else - * return the character. - */ - if (!xmon) { - while (bdp->status & BD_SC_EMPTY); - } - else { - if (bdp->status & BD_SC_EMPTY) - return -1; - } - - cp = (char *)bdp->buf; - - if (obuf) { - i = c = bdp->length; - while (i-- > 0) - *obuf++ = *cp++; - } - else { - c = *cp; - } - bdp->status |= BD_SC_EMPTY; - - if (info) { - if (bdp->status & BD_SC_WRAP) { - bdp = info->rx_bd_base; - } - else { - bdp++; - } - info->rx_cur = (QUICC_BD *)bdp; - } - - return((int)c); -} - -static int serial_console_wait_key(struct console *co) -{ - return(my_console_wait_key(co->index, 0, NULL)); -} - -#ifdef CONFIG_XMON -int -xmon_360_read_poll(void) -{ - return(my_console_wait_key(0, 1, NULL)); -} - -int -xmon_360_read_char(void) -{ - return(my_console_wait_key(0, 0, NULL)); -} -#endif - -#ifdef CONFIG_KGDB -static char kgdb_buf[RX_BUF_SIZE], *kgdp; -static int kgdb_chars; - -unsigned char -getDebugChar(void) -{ - if (kgdb_chars <= 0) { - kgdb_chars = my_console_wait_key(0, 0, kgdb_buf); - kgdp = kgdb_buf; - } - kgdb_chars--; - - return(*kgdp++); -} - -void kgdb_interruptible(int state) -{ -} -void kgdb_map_scc(void) -{ - struct serial_state *ser; - uint mem_addr; - volatile QUICC_BD *bdp; - volatile smc_uart_t *up; - - cpmp = (cpm360_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); - - /* To avoid data cache CPM DMA coherency problems, allocate a - * buffer in the CPM DPRAM. This will work until the CPM and - * serial ports are initialized. At that time a memory buffer - * will be allocated. - * The port is already initialized from the boot procedure, all - * we do here is give it a different buffer and make it a FIFO. - */ - - ser = rs_table; - - /* Right now, assume we are using SMCs. - */ - up = (smc_uart_t *)&cpmp->cp_dparam[ser->port]; - - /* Allocate space for an input FIFO, plus a few bytes for output. - * Allocate bytes to maintain word alignment. - */ - mem_addr = (uint)(&cpmp->cp_dpmem[0x1000]); - - /* Set the physical address of the host memory buffers in - * the buffer descriptors. - */ - bdp = (QUICC_BD *)&cpmp->cp_dpmem[up->smc_rbase]; - bdp->buf = mem_addr; - - bdp = (QUICC_BD *)&cpmp->cp_dpmem[up->smc_tbase]; - bdp->buf = mem_addr+RX_BUF_SIZE; - - up->smc_mrblr = RX_BUF_SIZE; /* receive buffer length */ - up->smc_maxidl = RX_BUF_SIZE; -} -#endif - -static struct tty_struct *serial_console_device(struct console *c, int *index) -{ - *index = c->index; - return serial_driver; -} - - -struct console sercons = { - .name = "ttyS", - .write = serial_console_write, - .device = serial_console_device, - .wait_key = serial_console_wait_key, - .setup = serial_console_setup, - .flags = CON_PRINTBUFFER, - .index = CONFIG_SERIAL_CONSOLE_PORT, -}; - - - -/* - * Register console. - */ -long console_360_init(long kmem_start, long kmem_end) -{ - register_console(&sercons); - /*register_console (console_print_68360); - 2.0.38 only required a write - function pointer. */ - return kmem_start; -} - -#endif - -/* Index in baud rate table of the default console baud rate. -*/ -static int baud_idx; - -static const struct tty_operations rs_360_ops = { - .owner = THIS_MODULE, - .open = rs_360_open, - .close = rs_360_close, - .write = rs_360_write, - .put_char = rs_360_put_char, - .write_room = rs_360_write_room, - .chars_in_buffer = rs_360_chars_in_buffer, - .flush_buffer = rs_360_flush_buffer, - .ioctl = rs_360_ioctl, - .throttle = rs_360_throttle, - .unthrottle = rs_360_unthrottle, - /* .send_xchar = rs_360_send_xchar, */ - .set_termios = rs_360_set_termios, - .stop = rs_360_stop, - .start = rs_360_start, - .hangup = rs_360_hangup, - /* .wait_until_sent = rs_360_wait_until_sent, */ - /* .read_proc = rs_360_read_proc, */ - .tiocmget = rs_360_tiocmget, - .tiocmset = rs_360_tiocmset, - .get_icount = rs_360_get_icount, -}; - -static int __init rs_360_init(void) -{ - struct serial_state * state; - ser_info_t *info; - void *mem_addr; - uint dp_addr, iobits; - int i, j, idx; - ushort chan; - QUICC_BD *bdp; - volatile QUICC *cp; - volatile struct smc_regs *sp; - volatile struct smc_uart_pram *up; - volatile struct scc_regs *scp; - volatile struct uart_pram *sup; - /* volatile immap_t *immap; */ - - serial_driver = alloc_tty_driver(NR_PORTS); - if (!serial_driver) - return -1; - - show_serial_version(); - - serial_driver->name = "ttyS"; - serial_driver->major = TTY_MAJOR; - serial_driver->minor_start = 64; - serial_driver->type = TTY_DRIVER_TYPE_SERIAL; - serial_driver->subtype = SERIAL_TYPE_NORMAL; - serial_driver->init_termios = tty_std_termios; - serial_driver->init_termios.c_cflag = - baud_idx | CS8 | CREAD | HUPCL | CLOCAL; - serial_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(serial_driver, &rs_360_ops); - - if (tty_register_driver(serial_driver)) - panic("Couldn't register serial driver\n"); - - cp = pquicc; /* Get pointer to Communication Processor */ - /* immap = (immap_t *)IMAP_ADDR; */ /* and to internal registers */ - - - /* Configure SCC2, SCC3, and SCC4 instead of port A parallel I/O. - */ - /* The "standard" configuration through the 860. - */ -/* immap->im_ioport.iop_papar |= 0x00fc; */ -/* immap->im_ioport.iop_padir &= ~0x00fc; */ -/* immap->im_ioport.iop_paodr &= ~0x00fc; */ - cp->pio_papar |= 0x00fc; - cp->pio_padir &= ~0x00fc; - /* cp->pio_paodr &= ~0x00fc; */ - - - /* Since we don't yet do modem control, connect the port C pins - * as general purpose I/O. This will assert CTS and CD for the - * SCC ports. - */ - /* FIXME: see 360um p.7-365 and 860um p.34-12 - * I can't make sense of these bits - mleslie*/ -/* immap->im_ioport.iop_pcdir |= 0x03c6; */ -/* immap->im_ioport.iop_pcpar &= ~0x03c6; */ - -/* cp->pio_pcdir |= 0x03c6; */ -/* cp->pio_pcpar &= ~0x03c6; */ - - - - /* Connect SCC2 and SCC3 to NMSI. Connect BRG3 to SCC2 and - * BRG4 to SCC3. - */ - cp->si_sicr &= ~0x00ffff00; - cp->si_sicr |= 0x001b1200; - -#ifdef CONFIG_PP04 - /* Frequentis PP04 forced to RS-232 until we know better. - * Port C 12 and 13 low enables RS-232 on SCC3 and SCC4. - */ - immap->im_ioport.iop_pcdir |= 0x000c; - immap->im_ioport.iop_pcpar &= ~0x000c; - immap->im_ioport.iop_pcdat &= ~0x000c; - - /* This enables the TX driver. - */ - cp->cp_pbpar &= ~0x6000; - cp->cp_pbdat &= ~0x6000; -#endif - - for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { - state->magic = SSTATE_MAGIC; - state->line = i; - state->type = PORT_UNKNOWN; - state->custom_divisor = 0; - state->close_delay = 5*HZ/10; - state->closing_wait = 30*HZ; - state->icount.cts = state->icount.dsr = - state->icount.rng = state->icount.dcd = 0; - state->icount.rx = state->icount.tx = 0; - state->icount.frame = state->icount.parity = 0; - state->icount.overrun = state->icount.brk = 0; - printk(KERN_INFO "ttyS%d at irq 0x%02x is an %s\n", - i, (unsigned int)(state->irq), - (state->smc_scc_num & NUM_IS_SCC) ? "SCC" : "SMC"); - -#ifdef CONFIG_SERIAL_CONSOLE - /* If we just printed the message on the console port, and - * we are about to initialize it for general use, we have - * to wait a couple of character times for the CR/NL to - * make it out of the transmit buffer. - */ - if (i == CONFIG_SERIAL_CONSOLE_PORT) - mdelay(8); - - -/* idx = PORT_NUM(info->state->smc_scc_num); */ -/* if (info->state->smc_scc_num & NUM_IS_SCC) */ -/* chan = scc_chan_map[idx]; */ -/* else */ -/* chan = smc_chan_map[idx]; */ - -/* cp->cp_cr = mk_cr_cmd(chan, CPM_CR_STOP_TX) | CPM_CR_FLG; */ -/* while (cp->cp_cr & CPM_CR_FLG); */ - -#endif - /* info = kmalloc(sizeof(ser_info_t), GFP_KERNEL); */ - info = &quicc_ser_info[i]; - if (info) { - memset (info, 0, sizeof(ser_info_t)); - info->magic = SERIAL_MAGIC; - info->line = i; - info->flags = state->flags; - INIT_WORK(&info->tqueue, do_softint, info); - INIT_WORK(&info->tqueue_hangup, do_serial_hangup, info); - init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); - info->state = state; - state->info = (struct async_struct *)info; - - /* We need to allocate a transmit and receive buffer - * descriptors from dual port ram, and a character - * buffer area from host mem. - */ - dp_addr = m360_cpm_dpalloc(sizeof(QUICC_BD) * RX_NUM_FIFO); - - /* Allocate space for FIFOs in the host memory. - * (for now this is from a static array of buffers :( - */ - /* mem_addr = m360_cpm_hostalloc(RX_NUM_FIFO * RX_BUF_SIZE); */ - /* mem_addr = kmalloc (RX_NUM_FIFO * RX_BUF_SIZE, GFP_BUFFER); */ - mem_addr = &rx_buf_pool[i * RX_NUM_FIFO * RX_BUF_SIZE]; - - /* Set the physical address of the host memory - * buffers in the buffer descriptors, and the - * virtual address for us to work with. - */ - bdp = (QUICC_BD *)((uint)pquicc + dp_addr); - info->rx_cur = info->rx_bd_base = bdp; - - /* initialize rx buffer descriptors */ - for (j=0; j<(RX_NUM_FIFO-1); j++) { - bdp->buf = &rx_buf_pool[(i * RX_NUM_FIFO + j ) * RX_BUF_SIZE]; - bdp->status = BD_SC_EMPTY | BD_SC_INTRPT; - mem_addr += RX_BUF_SIZE; - bdp++; - } - bdp->buf = &rx_buf_pool[(i * RX_NUM_FIFO + j ) * RX_BUF_SIZE]; - bdp->status = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT; - - - idx = PORT_NUM(info->state->smc_scc_num); - if (info->state->smc_scc_num & NUM_IS_SCC) { - -#if defined (CONFIG_UCQUICC) && 1 - /* set the transceiver mode to RS232 */ - sipex_mode_bits &= ~(uint)SIPEX_MODE(idx,0x0f); /* clear current mode */ - sipex_mode_bits |= (uint)SIPEX_MODE(idx,0x02); - *(uint *)_periph_base = sipex_mode_bits; - /* printk ("sipex bits = 0x%08x\n", sipex_mode_bits); */ -#endif - } - - dp_addr = m360_cpm_dpalloc(sizeof(QUICC_BD) * TX_NUM_FIFO); - - /* Allocate space for FIFOs in the host memory. - */ - /* mem_addr = m360_cpm_hostalloc(TX_NUM_FIFO * TX_BUF_SIZE); */ - /* mem_addr = kmalloc (TX_NUM_FIFO * TX_BUF_SIZE, GFP_BUFFER); */ - mem_addr = &tx_buf_pool[i * TX_NUM_FIFO * TX_BUF_SIZE]; - - /* Set the physical address of the host memory - * buffers in the buffer descriptors, and the - * virtual address for us to work with. - */ - /* bdp = (QUICC_BD *)&cp->cp_dpmem[dp_addr]; */ - bdp = (QUICC_BD *)((uint)pquicc + dp_addr); - info->tx_cur = info->tx_bd_base = (QUICC_BD *)bdp; - - /* initialize tx buffer descriptors */ - for (j=0; j<(TX_NUM_FIFO-1); j++) { - bdp->buf = &tx_buf_pool[(i * TX_NUM_FIFO + j ) * TX_BUF_SIZE]; - bdp->status = BD_SC_INTRPT; - mem_addr += TX_BUF_SIZE; - bdp++; - } - bdp->buf = &tx_buf_pool[(i * TX_NUM_FIFO + j ) * TX_BUF_SIZE]; - bdp->status = (BD_SC_WRAP | BD_SC_INTRPT); - - if (info->state->smc_scc_num & NUM_IS_SCC) { - scp = &pquicc->scc_regs[idx]; - sup = &pquicc->pram[info->state->port].scc.pscc.u; - sup->rbase = dp_addr; - sup->tbase = dp_addr; - - /* Set up the uart parameters in the - * parameter ram. - */ - sup->rfcr = SMC_EB; - sup->tfcr = SMC_EB; - - /* Set this to 1 for now, so we get single - * character interrupts. Using idle character - * time requires some additional tuning. - */ - sup->mrblr = 1; - sup->max_idl = 0; - sup->brkcr = 1; - sup->parec = 0; - sup->frmer = 0; - sup->nosec = 0; - sup->brkec = 0; - sup->uaddr1 = 0; - sup->uaddr2 = 0; - sup->toseq = 0; - { - int i; - for (i=0;i<8;i++) - sup->cc[i] = 0x8000; - } - sup->rccm = 0xc0ff; - - /* Send the CPM an initialize command. - */ - chan = scc_chan_map[idx]; - - /* execute the INIT RX & TX PARAMS command for this channel. */ - cp->cp_cr = mk_cr_cmd(chan, CPM_CR_INIT_TRX) | CPM_CR_FLG; - while (cp->cp_cr & CPM_CR_FLG); - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - scp->scc_gsmr.w.high = 0; - scp->scc_gsmr.w.low = - (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); - - /* Disable all interrupts and clear all pending - * events. - */ - scp->scc_sccm = 0; - scp->scc_scce = 0xffff; - scp->scc_dsr = 0x7e7e; - scp->scc_psmr = 0x3000; - - /* If the port is the console, enable Rx and Tx. - */ -#ifdef CONFIG_SERIAL_CONSOLE - if (i == CONFIG_SERIAL_CONSOLE_PORT) - scp->scc_gsmr.w.low |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); -#endif - } - else { - /* Configure SMCs Tx/Rx instead of port B - * parallel I/O. - */ - up = &pquicc->pram[info->state->port].scc.pothers.idma_smc.psmc.u; - up->rbase = dp_addr; - - iobits = 0xc0 << (idx * 4); - cp->pip_pbpar |= iobits; - cp->pip_pbdir &= ~iobits; - cp->pip_pbodr &= ~iobits; - - - /* Connect the baud rate generator to the - * SMC based upon index in rs_table. Also - * make sure it is connected to NMSI. - */ - cp->si_simode &= ~(0xffff << (idx * 16)); - cp->si_simode |= (i << ((idx * 16) + 12)); - - up->tbase = dp_addr; - - /* Set up the uart parameters in the - * parameter ram. - */ - up->rfcr = SMC_EB; - up->tfcr = SMC_EB; - - /* Set this to 1 for now, so we get single - * character interrupts. Using idle character - * time requires some additional tuning. - */ - up->mrblr = 1; - up->max_idl = 0; - up->brkcr = 1; - - /* Send the CPM an initialize command. - */ - chan = smc_chan_map[idx]; - - cp->cp_cr = mk_cr_cmd(chan, - CPM_CR_INIT_TRX) | CPM_CR_FLG; -#ifdef CONFIG_SERIAL_CONSOLE - if (i == CONFIG_SERIAL_CONSOLE_PORT) - printk(""); -#endif - while (cp->cp_cr & CPM_CR_FLG); - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - sp = &cp->smc_regs[idx]; - sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; - - /* Disable all interrupts and clear all pending - * events. - */ - sp->smc_smcm = 0; - sp->smc_smce = 0xff; - - /* If the port is the console, enable Rx and Tx. - */ -#ifdef CONFIG_SERIAL_CONSOLE - if (i == CONFIG_SERIAL_CONSOLE_PORT) - sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; -#endif - } - - /* Install interrupt handler. - */ - /* cpm_install_handler(IRQ_MACHSPEC | state->irq, rs_360_interrupt, info); */ - /*request_irq(IRQ_MACHSPEC | state->irq, rs_360_interrupt, */ - request_irq(state->irq, rs_360_interrupt, 0, "ttyS", - (void *)info); - - /* Set up the baud rate generator. - */ - m360_cpm_setbrg(i, baud_table[baud_idx]); - - } - } - - return 0; -} -module_init(rs_360_init); - -/* This must always be called before the rs_360_init() function, otherwise - * it blows away the port control information. - */ -//static int __init serial_console_setup( struct console *co, char *options) -int serial_console_setup( struct console *co, char *options) -{ - struct serial_state *ser; - uint mem_addr, dp_addr, bidx, idx, iobits; - ushort chan; - QUICC_BD *bdp; - volatile QUICC *cp; - volatile struct smc_regs *sp; - volatile struct scc_regs *scp; - volatile struct smc_uart_pram *up; - volatile struct uart_pram *sup; - -/* mleslie TODO: - * add something to the 68k bootloader to store a desired initial console baud rate */ - -/* bd_t *bd; */ /* a board info struct used by EPPC-bug */ -/* bd = (bd_t *)__res; */ - - for (bidx = 0; bidx < (sizeof(baud_table) / sizeof(int)); bidx++) - /* if (bd->bi_baudrate == baud_table[bidx]) */ - if (CONSOLE_BAUDRATE == baud_table[bidx]) - break; - - /* co->cflag = CREAD|CLOCAL|bidx|CS8; */ - baud_idx = bidx; - - ser = rs_table + CONFIG_SERIAL_CONSOLE_PORT; - - cp = pquicc; /* Get pointer to Communication Processor */ - - idx = PORT_NUM(ser->smc_scc_num); - if (ser->smc_scc_num & NUM_IS_SCC) { - - /* TODO: need to set up SCC pin assignment etc. here */ - - } - else { - iobits = 0xc0 << (idx * 4); - cp->pip_pbpar |= iobits; - cp->pip_pbdir &= ~iobits; - cp->pip_pbodr &= ~iobits; - - /* Connect the baud rate generator to the - * SMC based upon index in rs_table. Also - * make sure it is connected to NMSI. - */ - cp->si_simode &= ~(0xffff << (idx * 16)); - cp->si_simode |= (idx << ((idx * 16) + 12)); - } - - /* When we get here, the CPM has been reset, so we need - * to configure the port. - * We need to allocate a transmit and receive buffer descriptor - * from dual port ram, and a character buffer area from host mem. - */ - - /* Allocate space for two buffer descriptors in the DP ram. - */ - dp_addr = m360_cpm_dpalloc(sizeof(QUICC_BD) * CONSOLE_NUM_FIFO); - - /* Allocate space for two 2 byte FIFOs in the host memory. - */ - /* mem_addr = m360_cpm_hostalloc(8); */ - mem_addr = (uint)console_fifos; - - - /* Set the physical address of the host memory buffers in - * the buffer descriptors. - */ - /* bdp = (QUICC_BD *)&cp->cp_dpmem[dp_addr]; */ - bdp = (QUICC_BD *)((uint)pquicc + dp_addr); - bdp->buf = (char *)mem_addr; - (bdp+1)->buf = (char *)(mem_addr+4); - - /* For the receive, set empty and wrap. - * For transmit, set wrap. - */ - bdp->status = BD_SC_EMPTY | BD_SC_WRAP; - (bdp+1)->status = BD_SC_WRAP; - - /* Set up the uart parameters in the parameter ram. - */ - if (ser->smc_scc_num & NUM_IS_SCC) { - scp = &cp->scc_regs[idx]; - /* sup = (scc_uart_t *)&cp->cp_dparam[ser->port]; */ - sup = &pquicc->pram[ser->port].scc.pscc.u; - - sup->rbase = dp_addr; - sup->tbase = dp_addr + sizeof(QUICC_BD); - - /* Set up the uart parameters in the - * parameter ram. - */ - sup->rfcr = SMC_EB; - sup->tfcr = SMC_EB; - - /* Set this to 1 for now, so we get single - * character interrupts. Using idle character - * time requires some additional tuning. - */ - sup->mrblr = 1; - sup->max_idl = 0; - sup->brkcr = 1; - sup->parec = 0; - sup->frmer = 0; - sup->nosec = 0; - sup->brkec = 0; - sup->uaddr1 = 0; - sup->uaddr2 = 0; - sup->toseq = 0; - { - int i; - for (i=0;i<8;i++) - sup->cc[i] = 0x8000; - } - sup->rccm = 0xc0ff; - - /* Send the CPM an initialize command. - */ - chan = scc_chan_map[idx]; - - cp->cp_cr = mk_cr_cmd(chan, CPM_CR_INIT_TRX) | CPM_CR_FLG; - while (cp->cp_cr & CPM_CR_FLG); - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - scp->scc_gsmr.w.high = 0; - scp->scc_gsmr.w.low = - (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); - - /* Disable all interrupts and clear all pending - * events. - */ - scp->scc_sccm = 0; - scp->scc_scce = 0xffff; - scp->scc_dsr = 0x7e7e; - scp->scc_psmr = 0x3000; - - scp->scc_gsmr.w.low |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); - - } - else { - /* up = (smc_uart_t *)&cp->cp_dparam[ser->port]; */ - up = &pquicc->pram[ser->port].scc.pothers.idma_smc.psmc.u; - - up->rbase = dp_addr; /* Base of receive buffer desc. */ - up->tbase = dp_addr+sizeof(QUICC_BD); /* Base of xmt buffer desc. */ - up->rfcr = SMC_EB; - up->tfcr = SMC_EB; - - /* Set this to 1 for now, so we get single character interrupts. - */ - up->mrblr = 1; /* receive buffer length */ - up->max_idl = 0; /* wait forever for next char */ - - /* Send the CPM an initialize command. - */ - chan = smc_chan_map[idx]; - cp->cp_cr = mk_cr_cmd(chan, CPM_CR_INIT_TRX) | CPM_CR_FLG; - while (cp->cp_cr & CPM_CR_FLG); - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - sp = &cp->smc_regs[idx]; - sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; - - /* And finally, enable Rx and Tx. - */ - sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; - } - - /* Set up the baud rate generator. - */ - /* m360_cpm_setbrg((ser - rs_table), bd->bi_baudrate); */ - m360_cpm_setbrg((ser - rs_table), CONSOLE_BAUDRATE); - - return 0; -} - -/* - * Local variables: - * c-indent-level: 4 - * c-basic-offset: 4 - * tab-width: 4 - * End: - */ diff --git a/drivers/staging/serial/Kconfig b/drivers/staging/serial/Kconfig deleted file mode 100644 index 9489688..0000000 --- a/drivers/staging/serial/Kconfig +++ /dev/null @@ -1,16 +0,0 @@ -config SERIAL_68360_SMC - bool "68360 SMC uart support" - depends on M68360 - help - This driver supports the SMC serial ports of the Motorola 68360 CPU. - -config SERIAL_68360_SCC - bool "68360 SCC uart support" - depends on M68360 - help - This driver supports the SCC serial ports of the Motorola 68360 CPU. - -config SERIAL_68360 - bool - depends on SERIAL_68360_SMC || SERIAL_68360_SCC - default y diff --git a/drivers/staging/serial/Makefile b/drivers/staging/serial/Makefile deleted file mode 100644 index 37a6a0b..0000000 --- a/drivers/staging/serial/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_SERIAL_68360) += 68360serial.o diff --git a/drivers/staging/serial/TODO b/drivers/staging/serial/TODO deleted file mode 100644 index a19cda8..0000000 --- a/drivers/staging/serial/TODO +++ /dev/null @@ -1,6 +0,0 @@ -These are a few serial drivers that either do not build, or do not work if they -do build, or if they seem to work, are for obsolete hardware, or are full of -unfixable races and no one uses them anymore. - -If no one steps up to adopt any of these drivers, they will be removed -in the 3.4 release. -- cgit v0.10.2 From 09f78be78afbdc8b164905e9a19698922fa45edb Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 10 Apr 2012 21:11:04 +0100 Subject: staging:iio:buffer example fix typos I have no idea how I managed to munge the previous patch related to this. Sorry all. Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/drivers/staging/iio/Documentation/generic_buffer.c index 69a05b9..bf55335 100644 --- a/drivers/staging/iio/Documentation/generic_buffer.c +++ b/drivers/staging/iio/Documentation/generic_buffer.c @@ -60,9 +60,9 @@ void print2byte(int input, struct iio_channel_info *info) /* First swap if incorrect endian */ if (info->be) - input = be16toh((uint_16t)input); + input = be16toh((uint16_t)input); else - input = le16toh((uint_16t)input); + input = le16toh((uint16_t)input); /* shift before conversion to avoid sign extension of left aligned data */ -- cgit v0.10.2 From a9ea1b178fbe66bc982c18ddaed018933b428137 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 10 Apr 2012 21:11:05 +0100 Subject: staging:iio:adc:max1363 fix missing update_scan_mask callback. When moving over to the new sw_ring_preenable I managed to add this callback to only one of the two iio_info structures. As such only some devices will currently work. Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index cf3e2ca..2536b63 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -830,6 +830,7 @@ static struct attribute_group max1363_event_attribute_group = { static const struct iio_info max1238_info = { .read_raw = &max1363_read_raw, .driver_module = THIS_MODULE, + .update_scan_mode = &max1363_update_scan_mode, }; static const struct iio_info max1363_info = { -- cgit v0.10.2 From ecbf20ca95546f6347afe3952e07850a8e4c48de Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 10 Apr 2012 21:11:06 +0100 Subject: staging:iio fill in some missing docs Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h index b9cd454..833a849 100644 --- a/drivers/staging/iio/iio.h +++ b/drivers/staging/iio/iio.h @@ -331,6 +331,8 @@ struct iio_buffer_setup_ops { * @name: [DRIVER] name of the device. * @info: [DRIVER] callbacks and constant info from driver * @info_exist_lock: [INTERN] lock to prevent use during removal + * @setup_ops: [DRIVER] callbacks to call before and after buffer + * enable/disable * @chrdev: [INTERN] associated character device * @groups: [INTERN] attribute groups * @groupcounter: [INTERN] index of next attribute group -- cgit v0.10.2 From 0b27d678c7fbeb88ab07b890b09c32a83121d9d6 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 10 Apr 2012 21:11:07 +0100 Subject: staging:iio:max1363 enable use with inkernel interfaces. Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index 2536b63..9d7db7f 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -36,6 +36,7 @@ #include "../sysfs.h" #include "../events.h" #include "../buffer.h" +#include "../driver.h" #include "max1363.h" @@ -1290,6 +1291,9 @@ static int __devinit max1363_probe(struct i2c_client *client, ret = -ENOMEM; goto error_disable_reg; } + ret = iio_map_array_register(indio_dev, client->dev.platform_data); + if (ret < 0) + goto error_free_device; st = iio_priv(indio_dev); st->reg = reg; /* this is only used for device removal purposes */ @@ -1300,7 +1304,7 @@ static int __devinit max1363_probe(struct i2c_client *client, ret = max1363_alloc_scan_masks(indio_dev); if (ret) - goto error_free_device; + goto error_unregister_map; /* Estabilish that the iio_dev is a child of the i2c device */ indio_dev->dev.parent = &client->dev; @@ -1350,6 +1354,8 @@ error_cleanup_ring: max1363_ring_cleanup(indio_dev); error_free_available_scan_masks: kfree(indio_dev->available_scan_masks); +error_unregister_map: + iio_map_array_unregister(indio_dev, client->dev.platform_data); error_free_device: iio_free_device(indio_dev); error_disable_reg: @@ -1376,6 +1382,7 @@ static int max1363_remove(struct i2c_client *client) regulator_disable(reg); regulator_put(reg); } + iio_map_array_unregister(indio_dev, client->dev.platform_data); iio_free_device(indio_dev); return 0; -- cgit v0.10.2 From 8b1f52278f544af608d576e8db2b79ed651a9414 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 10 Apr 2012 21:11:08 +0100 Subject: staging:iio:accel:lis3l02dq add symmetry to check for presence of trigger. Checking indio_dev->modes is uggly and not symmetric with the conditions on whether triggers are allowed in the first place. Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index 376da51..bcf4712 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -724,7 +724,7 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi) return 0; error_remove_trigger: - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) + if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq))) lis3l02dq_remove_trigger(indio_dev); error_free_interrupt: if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) -- cgit v0.10.2 From 487db48506513fa80138951f081db3d12b36b7e1 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 10 Apr 2012 21:11:09 +0100 Subject: staging:iio: use spi->irq valid rather than querying available modes Given these drivers only try to add the trigger if a valid irq is present it is clearer to check the same condition when deciding whether to remove it on a later trigger. Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index e73ad78..a027d6d 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -1172,7 +1172,7 @@ static int __devinit adis16400_probe(struct spi_device *spi) return 0; error_remove_trigger: - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) + if (spi->irq) adis16400_remove_trigger(indio_dev); error_uninitialize_ring: iio_buffer_unregister(indio_dev); diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c index dcb2029..9374d6b 100644 --- a/drivers/staging/iio/meter/ade7758_core.c +++ b/drivers/staging/iio/meter/ade7758_core.c @@ -800,7 +800,7 @@ static int __devinit ade7758_probe(struct spi_device *spi) return 0; error_remove_trigger: - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) + if (spi->irq) ade7758_remove_trigger(indio_dev); error_uninitialize_ring: ade7758_uninitialize_ring(indio_dev); -- cgit v0.10.2 From b330f606ed7591dc078acd856454e3a383299fb3 Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Tue, 10 Apr 2012 16:06:41 -0600 Subject: staging: replace open-coded ARRAY_SIZEs spatch http://coccinelle.lip6.fr/rules/array.cocci did these. Signed-off-by: Jim Cromie Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/bcm/DDRInit.c b/drivers/staging/bcm/DDRInit.c index 1c7db81..2b46f4d 100644 --- a/drivers/staging/bcm/DDRInit.c +++ b/drivers/staging/bcm/DDRInit.c @@ -1115,20 +1115,20 @@ int download_ddr_settings(PMINI_ADAPTER Adapter) { case DDR_80_MHZ: psDDRSetting = asT3LP_DDRSetting80MHz; - RegCount = (sizeof(asT3LP_DDRSetting80MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3LP_DDRSetting80MHz); RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ; psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; break; case DDR_100_MHZ: psDDRSetting = asT3LP_DDRSetting100MHz; - RegCount = (sizeof(asT3LP_DDRSetting100MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3LP_DDRSetting100MHz); RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ; psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; break; case DDR_133_MHZ: bOverrideSelfRefresh = TRUE; psDDRSetting = asT3LP_DDRSetting133MHz; - RegCount = (sizeof(asT3LP_DDRSetting133MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3LP_DDRSetting133MHz); RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; break; @@ -1146,20 +1146,20 @@ int download_ddr_settings(PMINI_ADAPTER Adapter) { case DDR_80_MHZ: psDDRSetting = asT3LPB_DDRSetting80MHz; - RegCount=(sizeof(asT3LPB_DDRSetting80MHz)/sizeof(DDR_SET_NODE)); + RegCount=ARRAY_SIZE(asT3LPB_DDRSetting80MHz); RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ; psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; break; case DDR_100_MHZ: psDDRSetting = asT3LPB_DDRSetting100MHz; - RegCount = (sizeof(asT3LPB_DDRSetting100MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3LPB_DDRSetting100MHz); RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ; psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; break; case DDR_133_MHZ: bOverrideSelfRefresh = TRUE; psDDRSetting = asT3LPB_DDRSetting133MHz; - RegCount = (sizeof(asT3LPB_DDRSetting133MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3LPB_DDRSetting133MHz); RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; break; @@ -1167,7 +1167,7 @@ int download_ddr_settings(PMINI_ADAPTER Adapter) case DDR_160_MHZ: bOverrideSelfRefresh = TRUE; psDDRSetting = asT3LPB_DDRSetting160MHz; - RegCount = sizeof(asT3LPB_DDRSetting160MHz)/sizeof(DDR_SET_NODE); + RegCount = ARRAY_SIZE(asT3LPB_DDRSetting160MHz); RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ; psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ; @@ -1181,19 +1181,19 @@ int download_ddr_settings(PMINI_ADAPTER Adapter) { case DDR_80_MHZ: psDDRSetting = asT3_DDRSetting80MHz; - RegCount = (sizeof(asT3_DDRSetting80MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3_DDRSetting80MHz); RegCount-=T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ; psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; break; case DDR_100_MHZ: psDDRSetting = asT3_DDRSetting100MHz; - RegCount = (sizeof(asT3_DDRSetting100MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3_DDRSetting100MHz); RegCount-=T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ; psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; break; case DDR_133_MHZ: psDDRSetting = asT3_DDRSetting133MHz; - RegCount = (sizeof(asT3_DDRSetting133MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3_DDRSetting133MHz); RegCount-=T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; break; @@ -1207,20 +1207,20 @@ int download_ddr_settings(PMINI_ADAPTER Adapter) { case DDR_80_MHZ: psDDRSetting = asT3B_DDRSetting80MHz; - RegCount = (sizeof(asT3B_DDRSetting80MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3B_DDRSetting80MHz); RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ; psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; break; case DDR_100_MHZ: psDDRSetting = asT3B_DDRSetting100MHz; - RegCount = (sizeof(asT3B_DDRSetting100MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3B_DDRSetting100MHz); RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ; psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; break; case DDR_133_MHZ: bOverrideSelfRefresh = TRUE; psDDRSetting = asT3B_DDRSetting133MHz; - RegCount = (sizeof(asT3B_DDRSetting133MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3B_DDRSetting133MHz); RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; break; diff --git a/drivers/staging/media/as102/as102_usb_drv.c b/drivers/staging/media/as102/as102_usb_drv.c index 0f6bfe7..36150e5 100644 --- a/drivers/staging/media/as102/as102_usb_drv.c +++ b/drivers/staging/media/as102/as102_usb_drv.c @@ -367,7 +367,7 @@ static int as102_usb_probe(struct usb_interface *intf, ENTER(); /* This should never actually happen */ - if ((sizeof(as102_usb_id_table) / sizeof(struct usb_device_id)) != + if (ARRAY_SIZE(as102_usb_id_table) != (sizeof(as102_device_names) / sizeof(const char *))) { pr_err("Device names table invalid size"); return -EINVAL; @@ -380,8 +380,7 @@ static int as102_usb_probe(struct usb_interface *intf, } /* Assign the user-friendly device name */ - for (i = 0; i < (sizeof(as102_usb_id_table) / - sizeof(struct usb_device_id)); i++) { + for (i = 0; i < ARRAY_SIZE(as102_usb_id_table); i++) { if (id == &as102_usb_id_table[i]) { as102_dev->name = as102_device_names[i]; as102_dev->elna_cfg = as102_elna_cfg[i]; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c index 4e93669..778d7ba 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c @@ -1322,9 +1322,9 @@ static struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev) struct iw_handler_def r8192_wx_handlers_def = { .standard = r8192_wx_handlers, - .num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler), + .num_standard = ARRAY_SIZE(r8192_wx_handlers), .private = r8192_private_handler, - .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler), + .num_private = ARRAY_SIZE(r8192_private_handler), .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args), .get_wireless_stats = r8192_get_wireless_stats, diff --git a/drivers/staging/rtl8192e/rtllib_wx.c b/drivers/staging/rtl8192e/rtllib_wx.c index c27ff7e..e5fe2e8 100644 --- a/drivers/staging/rtl8192e/rtllib_wx.c +++ b/drivers/staging/rtl8192e/rtllib_wx.c @@ -88,7 +88,7 @@ static inline char *rtl819x_translate_scan(struct rtllib_device *ieee, } /* Add the protocol name */ iwe.cmd = SIOCGIWNAME; - for (i = 0; i < (sizeof(rtllib_modes)/sizeof(rtllib_modes[0])); i++) { + for (i = 0; i < ARRAY_SIZE(rtllib_modes); i++) { if (network->mode&(1<= 17 .get_wireless_stats = r8192_get_wireless_stats, diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index ef35bc2..299350c 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -2389,10 +2389,10 @@ static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev) struct iw_handler_def r871x_handlers_def = { .standard = r8711_handlers, - .num_standard = sizeof(r8711_handlers) / sizeof(iw_handler), + .num_standard = ARRAY_SIZE(r8711_handlers), .private = r8711_private_handler, .private_args = (struct iw_priv_args *)r8711_private_args, - .num_private = sizeof(r8711_private_handler) / sizeof(iw_handler), + .num_private = ARRAY_SIZE(r8711_private_handler), .num_private_args = sizeof(r8711_private_args) / sizeof(struct iw_priv_args), .get_wireless_stats = r871x_get_wireless_stats diff --git a/drivers/staging/vt6655/wpa.c b/drivers/staging/vt6655/wpa.c index 61ac46f..0afb9fe 100644 --- a/drivers/staging/vt6655/wpa.c +++ b/drivers/staging/vt6655/wpa.c @@ -148,7 +148,7 @@ WPA_ParseRSN ( { j = 0; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d, sizeof(pBSSList->abyPKType): %zu\n", pRSN->wPKCount, sizeof(pBSSList->abyPKType)); - for(i = 0; (i < pRSN->wPKCount) && (j < sizeof(pBSSList->abyPKType)/sizeof(unsigned char)); i++) { + for(i = 0; (i < pRSN->wPKCount) && (j < ARRAY_SIZE(pBSSList->abyPKType)); i++) { if(pRSN->len >= 12+i*4+4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*i) if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI00, 4)) pBSSList->abyPKType[j++] = WPA_NONE; @@ -180,7 +180,7 @@ WPA_ParseRSN ( j = 0; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d, sizeof(pBSSList->abyAuthType): %zu\n", pIE_RSN_Auth->wAuthCount, sizeof(pBSSList->abyAuthType)); - for(i = 0; (i < pIE_RSN_Auth->wAuthCount) && (j < sizeof(pBSSList->abyAuthType)/sizeof(unsigned char)); i++) { + for(i = 0; (i < pIE_RSN_Auth->wAuthCount) && (j < ARRAY_SIZE(pBSSList->abyAuthType)); i++) { if(pRSN->len >= 14+4+(m+i)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*i) if ( !memcmp(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI01, 4)) pBSSList->abyAuthType[j++] = WPA_AUTH_IEEE802_1X; diff --git a/drivers/staging/vt6656/wpa.c b/drivers/staging/vt6656/wpa.c index 7dde3d6..b16d4dd 100644 --- a/drivers/staging/vt6656/wpa.c +++ b/drivers/staging/vt6656/wpa.c @@ -149,7 +149,7 @@ WPA_ParseRSN( j = 0; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d, sizeof(pBSSList->abyPKType): %zu\n", pRSN->wPKCount, sizeof(pBSSList->abyPKType)); for (i = 0; (i < pRSN->wPKCount) && - (j < sizeof(pBSSList->abyPKType)/sizeof(BYTE)); i++) { + (j < ARRAY_SIZE(pBSSList->abyPKType)); i++) { if(pRSN->len >= 12+i*4+4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*i) if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI00, 4)) pBSSList->abyPKType[j++] = WPA_NONE; @@ -182,7 +182,7 @@ WPA_ParseRSN( DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d, sizeof(pBSSList->abyAuthType): %zu\n", pIE_RSN_Auth->wAuthCount, sizeof(pBSSList->abyAuthType)); for (i = 0; (i < pIE_RSN_Auth->wAuthCount) && - (j < sizeof(pBSSList->abyAuthType)/sizeof(BYTE)); i++) { + (j < ARRAY_SIZE(pBSSList->abyAuthType)); i++) { if(pRSN->len >= 14+4+(m+i)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*i) if ( !memcmp(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI01, 4)) pBSSList->abyAuthType[j++] = WPA_AUTH_IEEE802_1X; -- cgit v0.10.2 From 91ceae374e1ece88c8f575259ee0ad7da28ae8ab Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 11 Apr 2012 11:14:57 +0200 Subject: NET: pc300, move to staging as it is broken It was marked as BROKEN back in 2008. It is because the tty handling in the driver is really broken. There was some activity in January 2012 to fix the driver, but the patch was commented to be bogus: https://lkml.org/lkml/2012/1/29/160 and we have not heard back from the author since then: https://lkml.org/lkml/2012/3/28/412 So since nobody stepped in and rewrote the driver, it is time to move it out of line now. And drop it some time later if nobody comes up with patches to fix the driver in staging. Signed-off-by: Jiri Slaby Acked-by: David S. Miller Cc: Alan Cox Cc: Andrea Shepard Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig index d70ede7..d58431e 100644 --- a/drivers/net/wan/Kconfig +++ b/drivers/net/wan/Kconfig @@ -203,37 +203,6 @@ config WANXL_BUILD_FIRMWARE You should never need this option, say N. -config PC300 - tristate "Cyclades-PC300 support (RS-232/V.35, X.21, T1/E1 boards)" - depends on HDLC && PCI && BROKEN - ---help--- - This driver is broken because of struct tty_driver change. - - Driver for the Cyclades-PC300 synchronous communication boards. - - These boards provide synchronous serial interfaces to your - Linux box (interfaces currently available are RS-232/V.35, X.21 and - T1/E1). If you wish to support Multilink PPP, please select the - option later and read the file README.mlppp provided by PC300 - package. - - To compile this as a module, choose M here: the module - will be called pc300. - - If unsure, say N. - -config PC300_MLPPP - bool "Cyclades-PC300 MLPPP support" - depends on PC300 && PPP_MULTILINK && PPP_SYNC_TTY && HDLC_PPP - help - Multilink PPP over the PC300 synchronous communication boards. - -comment "Cyclades-PC300 MLPPP support is disabled." - depends on HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP) - -comment "Refer to the file README.mlppp, provided by PC300 package." - depends on HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP) - config PC300TOO tristate "Cyclades PC300 RSV/X21 alternative support" depends on HDLC && PCI diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile index 19d14bc..eac709b 100644 --- a/drivers/net/wan/Makefile +++ b/drivers/net/wan/Makefile @@ -17,10 +17,6 @@ obj-$(CONFIG_HDLC_FR) += hdlc_fr.o obj-$(CONFIG_HDLC_PPP) += hdlc_ppp.o obj-$(CONFIG_HDLC_X25) += hdlc_x25.o -pc300-y := pc300_drv.o -pc300-$(CONFIG_PC300_MLPPP) += pc300_tty.o -pc300-objs := $(pc300-y) - obj-$(CONFIG_HOSTESS_SV11) += z85230.o hostess_sv11.o obj-$(CONFIG_SEALEVEL_4021) += z85230.o sealevel.o obj-$(CONFIG_COSA) += cosa.o @@ -35,7 +31,6 @@ obj-$(CONFIG_SDLA) += sdla.o obj-$(CONFIG_CYCLADES_SYNC) += cycx_drv.o cyclomx.o obj-$(CONFIG_LAPBETHER) += lapbether.o obj-$(CONFIG_SBNI) += sbni.o -obj-$(CONFIG_PC300) += pc300.o obj-$(CONFIG_N2) += n2.o obj-$(CONFIG_C101) += c101.o obj-$(CONFIG_WANXL) += wanxl.o diff --git a/drivers/net/wan/pc300-falc-lh.h b/drivers/net/wan/pc300-falc-lh.h deleted file mode 100644 index 01ed23c..0000000 --- a/drivers/net/wan/pc300-falc-lh.h +++ /dev/null @@ -1,1238 +0,0 @@ -/* - * falc.h Description of the Siemens FALC T1/E1 framer. - * - * Author: Ivan Passos - * - * Copyright: (c) 2000-2001 Cyclades Corp. - * - * 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. - * - * $Log: falc-lh.h,v $ - * Revision 3.1 2001/06/15 12:41:10 regina - * upping major version number - * - * Revision 1.1.1.1 2001/06/13 20:24:47 daniela - * PC300 initial CVS version (3.4.0-pre1) - * - * Revision 1.1 2000/05/15 ivan - * Included DJA bits for the LIM2 register. - * - * Revision 1.0 2000/02/22 ivan - * Initial version. - * - */ - -#ifndef _FALC_LH_H -#define _FALC_LH_H - -#define NUM_OF_T1_CHANNELS 24 -#define NUM_OF_E1_CHANNELS 32 - -/*>>>>>>>>>>>>>>>>> FALC Register Bits (Transmit Mode) <<<<<<<<<<<<<<<<<<< */ - -/* CMDR (Command Register) - ---------------- E1 & T1 ------------------------------ */ -#define CMDR_RMC 0x80 -#define CMDR_RRES 0x40 -#define CMDR_XREP 0x20 -#define CMDR_XRES 0x10 -#define CMDR_XHF 0x08 -#define CMDR_XTF 0x04 -#define CMDR_XME 0x02 -#define CMDR_SRES 0x01 - -/* MODE (Mode Register) - ----------------- E1 & T1 ----------------------------- */ -#define MODE_MDS2 0x80 -#define MODE_MDS1 0x40 -#define MODE_MDS0 0x20 -#define MODE_BRAC 0x10 -#define MODE_HRAC 0x08 - -/* IPC (Interrupt Port Configuration) - ----------------- E1 & T1 ----------------------------- */ -#define IPC_VIS 0x80 -#define IPC_SCI 0x04 -#define IPC_IC1 0x02 -#define IPC_IC0 0x01 - -/* CCR1 (Common Configuration Register 1) - ----------------- E1 & T1 ----------------------------- */ -#define CCR1_SFLG 0x80 -#define CCR1_XTS16RA 0x40 -#define CCR1_BRM 0x40 -#define CCR1_CASSYM 0x20 -#define CCR1_EDLX 0x20 -#define CCR1_EITS 0x10 -#define CCR1_ITF 0x08 -#define CCR1_RFT1 0x02 -#define CCR1_RFT0 0x01 - -/* CCR3 (Common Configuration Register 3) - ---------------- E1 & T1 ------------------------------ */ - -#define CCR3_PRE1 0x80 -#define CCR3_PRE0 0x40 -#define CCR3_EPT 0x20 -#define CCR3_RADD 0x10 -#define CCR3_RCRC 0x04 -#define CCR3_XCRC 0x02 - - -/* RTR1-4 (Receive Timeslot Register 1-4) - ---------------- E1 & T1 ------------------------------ */ - -#define RTR1_TS0 0x80 -#define RTR1_TS1 0x40 -#define RTR1_TS2 0x20 -#define RTR1_TS3 0x10 -#define RTR1_TS4 0x08 -#define RTR1_TS5 0x04 -#define RTR1_TS6 0x02 -#define RTR1_TS7 0x01 - -#define RTR2_TS8 0x80 -#define RTR2_TS9 0x40 -#define RTR2_TS10 0x20 -#define RTR2_TS11 0x10 -#define RTR2_TS12 0x08 -#define RTR2_TS13 0x04 -#define RTR2_TS14 0x02 -#define RTR2_TS15 0x01 - -#define RTR3_TS16 0x80 -#define RTR3_TS17 0x40 -#define RTR3_TS18 0x20 -#define RTR3_TS19 0x10 -#define RTR3_TS20 0x08 -#define RTR3_TS21 0x04 -#define RTR3_TS22 0x02 -#define RTR3_TS23 0x01 - -#define RTR4_TS24 0x80 -#define RTR4_TS25 0x40 -#define RTR4_TS26 0x20 -#define RTR4_TS27 0x10 -#define RTR4_TS28 0x08 -#define RTR4_TS29 0x04 -#define RTR4_TS30 0x02 -#define RTR4_TS31 0x01 - - -/* TTR1-4 (Transmit Timeslot Register 1-4) - ---------------- E1 & T1 ------------------------------ */ - -#define TTR1_TS0 0x80 -#define TTR1_TS1 0x40 -#define TTR1_TS2 0x20 -#define TTR1_TS3 0x10 -#define TTR1_TS4 0x08 -#define TTR1_TS5 0x04 -#define TTR1_TS6 0x02 -#define TTR1_TS7 0x01 - -#define TTR2_TS8 0x80 -#define TTR2_TS9 0x40 -#define TTR2_TS10 0x20 -#define TTR2_TS11 0x10 -#define TTR2_TS12 0x08 -#define TTR2_TS13 0x04 -#define TTR2_TS14 0x02 -#define TTR2_TS15 0x01 - -#define TTR3_TS16 0x80 -#define TTR3_TS17 0x40 -#define TTR3_TS18 0x20 -#define TTR3_TS19 0x10 -#define TTR3_TS20 0x08 -#define TTR3_TS21 0x04 -#define TTR3_TS22 0x02 -#define TTR3_TS23 0x01 - -#define TTR4_TS24 0x80 -#define TTR4_TS25 0x40 -#define TTR4_TS26 0x20 -#define TTR4_TS27 0x10 -#define TTR4_TS28 0x08 -#define TTR4_TS29 0x04 -#define TTR4_TS30 0x02 -#define TTR4_TS31 0x01 - - - -/* IMR0-4 (Interrupt Mask Register 0-4) - - ----------------- E1 & T1 ----------------------------- */ - -#define IMR0_RME 0x80 -#define IMR0_RFS 0x40 -#define IMR0_T8MS 0x20 -#define IMR0_ISF 0x20 -#define IMR0_RMB 0x10 -#define IMR0_CASC 0x08 -#define IMR0_RSC 0x08 -#define IMR0_CRC6 0x04 -#define IMR0_CRC4 0x04 -#define IMR0_PDEN 0x02 -#define IMR0_RPF 0x01 - -#define IMR1_CASE 0x80 -#define IMR1_RDO 0x40 -#define IMR1_ALLS 0x20 -#define IMR1_XDU 0x10 -#define IMR1_XMB 0x08 -#define IMR1_XLSC 0x02 -#define IMR1_XPR 0x01 -#define IMR1_LLBSC 0x80 - -#define IMR2_FAR 0x80 -#define IMR2_LFA 0x40 -#define IMR2_MFAR 0x20 -#define IMR2_T400MS 0x10 -#define IMR2_LMFA 0x10 -#define IMR2_AIS 0x08 -#define IMR2_LOS 0x04 -#define IMR2_RAR 0x02 -#define IMR2_RA 0x01 - -#define IMR3_ES 0x80 -#define IMR3_SEC 0x40 -#define IMR3_LMFA16 0x20 -#define IMR3_AIS16 0x10 -#define IMR3_RA16 0x08 -#define IMR3_API 0x04 -#define IMR3_XSLP 0x20 -#define IMR3_XSLN 0x10 -#define IMR3_LLBSC 0x08 -#define IMR3_XRS 0x04 -#define IMR3_SLN 0x02 -#define IMR3_SLP 0x01 - -#define IMR4_LFA 0x80 -#define IMR4_FER 0x40 -#define IMR4_CER 0x20 -#define IMR4_AIS 0x10 -#define IMR4_LOS 0x08 -#define IMR4_CVE 0x04 -#define IMR4_SLIP 0x02 -#define IMR4_EBE 0x01 - -/* FMR0-5 for E1 and T1 (Framer Mode Register ) */ - -#define FMR0_XC1 0x80 -#define FMR0_XC0 0x40 -#define FMR0_RC1 0x20 -#define FMR0_RC0 0x10 -#define FMR0_EXTD 0x08 -#define FMR0_ALM 0x04 -#define E1_FMR0_FRS 0x02 -#define T1_FMR0_FRS 0x08 -#define FMR0_SRAF 0x04 -#define FMR0_EXLS 0x02 -#define FMR0_SIM 0x01 - -#define FMR1_MFCS 0x80 -#define FMR1_AFR 0x40 -#define FMR1_ENSA 0x20 -#define FMR1_CTM 0x80 -#define FMR1_SIGM 0x40 -#define FMR1_EDL 0x20 -#define FMR1_PMOD 0x10 -#define FMR1_XFS 0x08 -#define FMR1_CRC 0x08 -#define FMR1_ECM 0x04 -#define FMR1_IMOD 0x02 -#define FMR1_XAIS 0x01 - -#define FMR2_RFS1 0x80 -#define FMR2_RFS0 0x40 -#define FMR2_MCSP 0x40 -#define FMR2_RTM 0x20 -#define FMR2_SSP 0x20 -#define FMR2_DAIS 0x10 -#define FMR2_SAIS 0x08 -#define FMR2_PLB 0x04 -#define FMR2_AXRA 0x02 -#define FMR2_ALMF 0x01 -#define FMR2_EXZE 0x01 - -#define LOOP_RTM 0x40 -#define LOOP_SFM 0x40 -#define LOOP_ECLB 0x20 -#define LOOP_CLA 0x1f - -/*--------------------- E1 ----------------------------*/ -#define FMR3_XLD 0x20 -#define FMR3_XLU 0x10 - -/*--------------------- T1 ----------------------------*/ -#define FMR4_AIS3 0x80 -#define FMR4_TM 0x40 -#define FMR4_XRA 0x20 -#define FMR4_SSC1 0x10 -#define FMR4_SSC0 0x08 -#define FMR4_AUTO 0x04 -#define FMR4_FM1 0x02 -#define FMR4_FM0 0x01 - -#define FMR5_SRS 0x80 -#define FMR5_EIBR 0x40 -#define FMR5_XLD 0x20 -#define FMR5_XLU 0x10 - - -/* LOOP (Channel Loop Back) - - ------------------ E1 & T1 ---------------------------- */ - -#define LOOP_SFM 0x40 -#define LOOP_ECLB 0x20 -#define LOOP_CLA4 0x10 -#define LOOP_CLA3 0x08 -#define LOOP_CLA2 0x04 -#define LOOP_CLA1 0x02 -#define LOOP_CLA0 0x01 - - - -/* XSW (Transmit Service Word Pulseframe) - - ------------------- E1 --------------------------- */ - -#define XSW_XSIS 0x80 -#define XSW_XTM 0x40 -#define XSW_XRA 0x20 -#define XSW_XY0 0x10 -#define XSW_XY1 0x08 -#define XSW_XY2 0x04 -#define XSW_XY3 0x02 -#define XSW_XY4 0x01 - - -/* XSP (Transmit Spare Bits) - - ------------------- E1 --------------------------- */ - -#define XSP_XAP 0x80 -#define XSP_CASEN 0x40 -#define XSP_TT0 0x20 -#define XSP_EBP 0x10 -#define XSP_AXS 0x08 -#define XSP_XSIF 0x04 -#define XSP_XS13 0x02 -#define XSP_XS15 0x01 - - -/* XC0/1 (Transmit Control 0/1) - ------------------ E1 & T1 ---------------------------- */ - -#define XC0_SA8E 0x80 -#define XC0_SA7E 0x40 -#define XC0_SA6E 0x20 -#define XC0_SA5E 0x10 -#define XC0_SA4E 0x08 -#define XC0_BRM 0x80 -#define XC0_MFBS 0x40 -#define XC0_SFRZ 0x10 -#define XC0_XCO2 0x04 -#define XC0_XCO1 0x02 -#define XC0_XCO0 0x01 - -#define XC1_XTO5 0x20 -#define XC1_XTO4 0x10 -#define XC1_XTO3 0x08 -#define XC1_XTO2 0x04 -#define XC1_XTO1 0x02 -#define XC1_XTO0 0x01 - - -/* RC0/1 (Receive Control 0/1) - ------------------ E1 & T1 ---------------------------- */ - -#define RC0_SICS 0x40 -#define RC0_CRCI 0x20 -#define RC0_XCRCI 0x10 -#define RC0_RDIS 0x08 -#define RC0_RCO2 0x04 -#define RC0_RCO1 0x02 -#define RC0_RCO0 0x01 - -#define RC1_SWD 0x80 -#define RC1_ASY4 0x40 -#define RC1_RRAM 0x40 -#define RC1_RTO5 0x20 -#define RC1_RTO4 0x10 -#define RC1_RTO3 0x08 -#define RC1_RTO2 0x04 -#define RC1_RTO1 0x02 -#define RC1_RTO0 0x01 - - - -/* XPM0-2 (Transmit Pulse Mask 0-2) - --------------------- E1 & T1 ------------------------- */ - -#define XPM0_XP12 0x80 -#define XPM0_XP11 0x40 -#define XPM0_XP10 0x20 -#define XPM0_XP04 0x10 -#define XPM0_XP03 0x08 -#define XPM0_XP02 0x04 -#define XPM0_XP01 0x02 -#define XPM0_XP00 0x01 - -#define XPM1_XP30 0x80 -#define XPM1_XP24 0x40 -#define XPM1_XP23 0x20 -#define XPM1_XP22 0x10 -#define XPM1_XP21 0x08 -#define XPM1_XP20 0x04 -#define XPM1_XP14 0x02 -#define XPM1_XP13 0x01 - -#define XPM2_XLHP 0x80 -#define XPM2_XLT 0x40 -#define XPM2_DAXLT 0x20 -#define XPM2_XP34 0x08 -#define XPM2_XP33 0x04 -#define XPM2_XP32 0x02 -#define XPM2_XP31 0x01 - - -/* TSWM (Transparent Service Word Mask) - ------------------ E1 ---------------------------- */ - -#define TSWM_TSIS 0x80 -#define TSWM_TSIF 0x40 -#define TSWM_TRA 0x20 -#define TSWM_TSA4 0x10 -#define TSWM_TSA5 0x08 -#define TSWM_TSA6 0x04 -#define TSWM_TSA7 0x02 -#define TSWM_TSA8 0x01 - -/* IDLE - - ------------------ E1 & T1 ----------------------- */ - -#define IDLE_IDL7 0x80 -#define IDLE_IDL6 0x40 -#define IDLE_IDL5 0x20 -#define IDLE_IDL4 0x10 -#define IDLE_IDL3 0x08 -#define IDLE_IDL2 0x04 -#define IDLE_IDL1 0x02 -#define IDLE_IDL0 0x01 - - -/* XSA4-8 - -------------------E1 ----------------------------- */ - -#define XSA4_XS47 0x80 -#define XSA4_XS46 0x40 -#define XSA4_XS45 0x20 -#define XSA4_XS44 0x10 -#define XSA4_XS43 0x08 -#define XSA4_XS42 0x04 -#define XSA4_XS41 0x02 -#define XSA4_XS40 0x01 - -#define XSA5_XS57 0x80 -#define XSA5_XS56 0x40 -#define XSA5_XS55 0x20 -#define XSA5_XS54 0x10 -#define XSA5_XS53 0x08 -#define XSA5_XS52 0x04 -#define XSA5_XS51 0x02 -#define XSA5_XS50 0x01 - -#define XSA6_XS67 0x80 -#define XSA6_XS66 0x40 -#define XSA6_XS65 0x20 -#define XSA6_XS64 0x10 -#define XSA6_XS63 0x08 -#define XSA6_XS62 0x04 -#define XSA6_XS61 0x02 -#define XSA6_XS60 0x01 - -#define XSA7_XS77 0x80 -#define XSA7_XS76 0x40 -#define XSA7_XS75 0x20 -#define XSA7_XS74 0x10 -#define XSA7_XS73 0x08 -#define XSA7_XS72 0x04 -#define XSA7_XS71 0x02 -#define XSA7_XS70 0x01 - -#define XSA8_XS87 0x80 -#define XSA8_XS86 0x40 -#define XSA8_XS85 0x20 -#define XSA8_XS84 0x10 -#define XSA8_XS83 0x08 -#define XSA8_XS82 0x04 -#define XSA8_XS81 0x02 -#define XSA8_XS80 0x01 - - -/* XDL1-3 (Transmit DL-Bit Register1-3 (read/write)) - ----------------------- T1 --------------------- */ - -#define XDL1_XDL17 0x80 -#define XDL1_XDL16 0x40 -#define XDL1_XDL15 0x20 -#define XDL1_XDL14 0x10 -#define XDL1_XDL13 0x08 -#define XDL1_XDL12 0x04 -#define XDL1_XDL11 0x02 -#define XDL1_XDL10 0x01 - -#define XDL2_XDL27 0x80 -#define XDL2_XDL26 0x40 -#define XDL2_XDL25 0x20 -#define XDL2_XDL24 0x10 -#define XDL2_XDL23 0x08 -#define XDL2_XDL22 0x04 -#define XDL2_XDL21 0x02 -#define XDL2_XDL20 0x01 - -#define XDL3_XDL37 0x80 -#define XDL3_XDL36 0x40 -#define XDL3_XDL35 0x20 -#define XDL3_XDL34 0x10 -#define XDL3_XDL33 0x08 -#define XDL3_XDL32 0x04 -#define XDL3_XDL31 0x02 -#define XDL3_XDL30 0x01 - - -/* ICB1-4 (Idle Channel Register 1-4) - ------------------ E1 ---------------------------- */ - -#define E1_ICB1_IC0 0x80 -#define E1_ICB1_IC1 0x40 -#define E1_ICB1_IC2 0x20 -#define E1_ICB1_IC3 0x10 -#define E1_ICB1_IC4 0x08 -#define E1_ICB1_IC5 0x04 -#define E1_ICB1_IC6 0x02 -#define E1_ICB1_IC7 0x01 - -#define E1_ICB2_IC8 0x80 -#define E1_ICB2_IC9 0x40 -#define E1_ICB2_IC10 0x20 -#define E1_ICB2_IC11 0x10 -#define E1_ICB2_IC12 0x08 -#define E1_ICB2_IC13 0x04 -#define E1_ICB2_IC14 0x02 -#define E1_ICB2_IC15 0x01 - -#define E1_ICB3_IC16 0x80 -#define E1_ICB3_IC17 0x40 -#define E1_ICB3_IC18 0x20 -#define E1_ICB3_IC19 0x10 -#define E1_ICB3_IC20 0x08 -#define E1_ICB3_IC21 0x04 -#define E1_ICB3_IC22 0x02 -#define E1_ICB3_IC23 0x01 - -#define E1_ICB4_IC24 0x80 -#define E1_ICB4_IC25 0x40 -#define E1_ICB4_IC26 0x20 -#define E1_ICB4_IC27 0x10 -#define E1_ICB4_IC28 0x08 -#define E1_ICB4_IC29 0x04 -#define E1_ICB4_IC30 0x02 -#define E1_ICB4_IC31 0x01 - -/* ICB1-4 (Idle Channel Register 1-4) - ------------------ T1 ---------------------------- */ - -#define T1_ICB1_IC1 0x80 -#define T1_ICB1_IC2 0x40 -#define T1_ICB1_IC3 0x20 -#define T1_ICB1_IC4 0x10 -#define T1_ICB1_IC5 0x08 -#define T1_ICB1_IC6 0x04 -#define T1_ICB1_IC7 0x02 -#define T1_ICB1_IC8 0x01 - -#define T1_ICB2_IC9 0x80 -#define T1_ICB2_IC10 0x40 -#define T1_ICB2_IC11 0x20 -#define T1_ICB2_IC12 0x10 -#define T1_ICB2_IC13 0x08 -#define T1_ICB2_IC14 0x04 -#define T1_ICB2_IC15 0x02 -#define T1_ICB2_IC16 0x01 - -#define T1_ICB3_IC17 0x80 -#define T1_ICB3_IC18 0x40 -#define T1_ICB3_IC19 0x20 -#define T1_ICB3_IC20 0x10 -#define T1_ICB3_IC21 0x08 -#define T1_ICB3_IC22 0x04 -#define T1_ICB3_IC23 0x02 -#define T1_ICB3_IC24 0x01 - -/* FMR3 (Framer Mode Register 3) - --------------------E1------------------------ */ - -#define FMR3_CMI 0x08 -#define FMR3_SYNSA 0x04 -#define FMR3_CFRZ 0x02 -#define FMR3_EXTIW 0x01 - - - -/* CCB1-3 (Clear Channel Register) - ------------------- T1 ----------------------- */ - -#define CCB1_CH1 0x80 -#define CCB1_CH2 0x40 -#define CCB1_CH3 0x20 -#define CCB1_CH4 0x10 -#define CCB1_CH5 0x08 -#define CCB1_CH6 0x04 -#define CCB1_CH7 0x02 -#define CCB1_CH8 0x01 - -#define CCB2_CH9 0x80 -#define CCB2_CH10 0x40 -#define CCB2_CH11 0x20 -#define CCB2_CH12 0x10 -#define CCB2_CH13 0x08 -#define CCB2_CH14 0x04 -#define CCB2_CH15 0x02 -#define CCB2_CH16 0x01 - -#define CCB3_CH17 0x80 -#define CCB3_CH18 0x40 -#define CCB3_CH19 0x20 -#define CCB3_CH20 0x10 -#define CCB3_CH21 0x08 -#define CCB3_CH22 0x04 -#define CCB3_CH23 0x02 -#define CCB3_CH24 0x01 - - -/* LIM0/1 (Line Interface Mode 0/1) - ------------------- E1 & T1 --------------------------- */ - -#define LIM0_XFB 0x80 -#define LIM0_XDOS 0x40 -#define LIM0_SCL1 0x20 -#define LIM0_SCL0 0x10 -#define LIM0_EQON 0x08 -#define LIM0_ELOS 0x04 -#define LIM0_LL 0x02 -#define LIM0_MAS 0x01 - -#define LIM1_EFSC 0x80 -#define LIM1_RIL2 0x40 -#define LIM1_RIL1 0x20 -#define LIM1_RIL0 0x10 -#define LIM1_DCOC 0x08 -#define LIM1_JATT 0x04 -#define LIM1_RL 0x02 -#define LIM1_DRS 0x01 - - -/* PCDR (Pulse Count Detection Register(Read/Write)) - ------------------ E1 & T1 ------------------------- */ - -#define PCDR_PCD7 0x80 -#define PCDR_PCD6 0x40 -#define PCDR_PCD5 0x20 -#define PCDR_PCD4 0x10 -#define PCDR_PCD3 0x08 -#define PCDR_PCD2 0x04 -#define PCDR_PCD1 0x02 -#define PCDR_PCD0 0x01 - -#define PCRR_PCR7 0x80 -#define PCRR_PCR6 0x40 -#define PCRR_PCR5 0x20 -#define PCRR_PCR4 0x10 -#define PCRR_PCR3 0x08 -#define PCRR_PCR2 0x04 -#define PCRR_PCR1 0x02 -#define PCRR_PCR0 0x01 - - -/* LIM2 (Line Interface Mode 2) - - ------------------ E1 & T1 ---------------------------- */ - -#define LIM2_DJA2 0x20 -#define LIM2_DJA1 0x10 -#define LIM2_LOS2 0x02 -#define LIM2_LOS1 0x01 - -/* LCR1 (Loop Code Register 1) */ - -#define LCR1_EPRM 0x80 -#define LCR1_XPRBS 0x40 - -/* SIC1 (System Interface Control 1) */ -#define SIC1_SRSC 0x80 -#define SIC1_RBS1 0x20 -#define SIC1_RBS0 0x10 -#define SIC1_SXSC 0x08 -#define SIC1_XBS1 0x02 -#define SIC1_XBS0 0x01 - -/* DEC (Disable Error Counter) - ------------------ E1 & T1 ---------------------------- */ - -#define DEC_DCEC3 0x20 -#define DEC_DBEC 0x10 -#define DEC_DCEC1 0x08 -#define DEC_DCEC 0x08 -#define DEC_DEBC 0x04 -#define DEC_DCVC 0x02 -#define DEC_DFEC 0x01 - - -/* FALC Register Bits (Receive Mode) - ---------------------------------------------------------------------------- */ - - -/* FRS0/1 (Framer Receive Status Register 0/1) - ----------------- E1 & T1 ---------------------------------- */ - -#define FRS0_LOS 0x80 -#define FRS0_AIS 0x40 -#define FRS0_LFA 0x20 -#define FRS0_RRA 0x10 -#define FRS0_API 0x08 -#define FRS0_NMF 0x04 -#define FRS0_LMFA 0x02 -#define FRS0_FSRF 0x01 - -#define FRS1_TS16RA 0x40 -#define FRS1_TS16LOS 0x20 -#define FRS1_TS16AIS 0x10 -#define FRS1_TS16LFA 0x08 -#define FRS1_EXZD 0x80 -#define FRS1_LLBDD 0x10 -#define FRS1_LLBAD 0x08 -#define FRS1_XLS 0x02 -#define FRS1_XLO 0x01 -#define FRS1_PDEN 0x40 - -/* FRS2/3 (Framer Receive Status Register 2/3) - ----------------- T1 ---------------------------------- */ - -#define FRS2_ESC2 0x80 -#define FRS2_ESC1 0x40 -#define FRS2_ESC0 0x20 - -#define FRS3_FEH5 0x20 -#define FRS3_FEH4 0x10 -#define FRS3_FEH3 0x08 -#define FRS3_FEH2 0x04 -#define FRS3_FEH1 0x02 -#define FRS3_FEH0 0x01 - - -/* RSW (Receive Service Word Pulseframe) - ----------------- E1 ------------------------------ */ - -#define RSW_RSI 0x80 -#define RSW_RRA 0x20 -#define RSW_RYO 0x10 -#define RSW_RY1 0x08 -#define RSW_RY2 0x04 -#define RSW_RY3 0x02 -#define RSW_RY4 0x01 - - -/* RSP (Receive Spare Bits / Additional Status) - ---------------- E1 ------------------------------- */ - -#define RSP_SI1 0x80 -#define RSP_SI2 0x40 -#define RSP_LLBDD 0x10 -#define RSP_LLBAD 0x08 -#define RSP_RSIF 0x04 -#define RSP_RS13 0x02 -#define RSP_RS15 0x01 - - -/* FECL (Framing Error Counter) - ---------------- E1 & T1 -------------------------- */ - -#define FECL_FE7 0x80 -#define FECL_FE6 0x40 -#define FECL_FE5 0x20 -#define FECL_FE4 0x10 -#define FECL_FE3 0x08 -#define FECL_FE2 0x04 -#define FECL_FE1 0x02 -#define FECL_FE0 0x01 - -#define FECH_FE15 0x80 -#define FECH_FE14 0x40 -#define FECH_FE13 0x20 -#define FECH_FE12 0x10 -#define FECH_FE11 0x08 -#define FECH_FE10 0x04 -#define FECH_FE9 0x02 -#define FECH_FE8 0x01 - - -/* CVCl (Code Violation Counter) - ----------------- E1 ------------------------- */ - -#define CVCL_CV7 0x80 -#define CVCL_CV6 0x40 -#define CVCL_CV5 0x20 -#define CVCL_CV4 0x10 -#define CVCL_CV3 0x08 -#define CVCL_CV2 0x04 -#define CVCL_CV1 0x02 -#define CVCL_CV0 0x01 - -#define CVCH_CV15 0x80 -#define CVCH_CV14 0x40 -#define CVCH_CV13 0x20 -#define CVCH_CV12 0x10 -#define CVCH_CV11 0x08 -#define CVCH_CV10 0x04 -#define CVCH_CV9 0x02 -#define CVCH_CV8 0x01 - - -/* CEC1-3L (CRC Error Counter) - ------------------ E1 ----------------------------- */ - -#define CEC1L_CR7 0x80 -#define CEC1L_CR6 0x40 -#define CEC1L_CR5 0x20 -#define CEC1L_CR4 0x10 -#define CEC1L_CR3 0x08 -#define CEC1L_CR2 0x04 -#define CEC1L_CR1 0x02 -#define CEC1L_CR0 0x01 - -#define CEC1H_CR15 0x80 -#define CEC1H_CR14 0x40 -#define CEC1H_CR13 0x20 -#define CEC1H_CR12 0x10 -#define CEC1H_CR11 0x08 -#define CEC1H_CR10 0x04 -#define CEC1H_CR9 0x02 -#define CEC1H_CR8 0x01 - -#define CEC2L_CR7 0x80 -#define CEC2L_CR6 0x40 -#define CEC2L_CR5 0x20 -#define CEC2L_CR4 0x10 -#define CEC2L_CR3 0x08 -#define CEC2L_CR2 0x04 -#define CEC2L_CR1 0x02 -#define CEC2L_CR0 0x01 - -#define CEC2H_CR15 0x80 -#define CEC2H_CR14 0x40 -#define CEC2H_CR13 0x20 -#define CEC2H_CR12 0x10 -#define CEC2H_CR11 0x08 -#define CEC2H_CR10 0x04 -#define CEC2H_CR9 0x02 -#define CEC2H_CR8 0x01 - -#define CEC3L_CR7 0x80 -#define CEC3L_CR6 0x40 -#define CEC3L_CR5 0x20 -#define CEC3L_CR4 0x10 -#define CEC3L_CR3 0x08 -#define CEC3L_CR2 0x04 -#define CEC3L_CR1 0x02 -#define CEC3L_CR0 0x01 - -#define CEC3H_CR15 0x80 -#define CEC3H_CR14 0x40 -#define CEC3H_CR13 0x20 -#define CEC3H_CR12 0x10 -#define CEC3H_CR11 0x08 -#define CEC3H_CR10 0x04 -#define CEC3H_CR9 0x02 -#define CEC3H_CR8 0x01 - - -/* CECL (CRC Error Counter) - - ------------------ T1 ----------------------------- */ - -#define CECL_CR7 0x80 -#define CECL_CR6 0x40 -#define CECL_CR5 0x20 -#define CECL_CR4 0x10 -#define CECL_CR3 0x08 -#define CECL_CR2 0x04 -#define CECL_CR1 0x02 -#define CECL_CR0 0x01 - -#define CECH_CR15 0x80 -#define CECH_CR14 0x40 -#define CECH_CR13 0x20 -#define CECH_CR12 0x10 -#define CECH_CR11 0x08 -#define CECH_CR10 0x04 -#define CECH_CR9 0x02 -#define CECH_CR8 0x01 - -/* EBCL (E Bit Error Counter) - ------------------- E1 & T1 ------------------------- */ - -#define EBCL_EB7 0x80 -#define EBCL_EB6 0x40 -#define EBCL_EB5 0x20 -#define EBCL_EB4 0x10 -#define EBCL_EB3 0x08 -#define EBCL_EB2 0x04 -#define EBCL_EB1 0x02 -#define EBCL_EB0 0x01 - -#define EBCH_EB15 0x80 -#define EBCH_EB14 0x40 -#define EBCH_EB13 0x20 -#define EBCH_EB12 0x10 -#define EBCH_EB11 0x08 -#define EBCH_EB10 0x04 -#define EBCH_EB9 0x02 -#define EBCH_EB8 0x01 - - -/* RSA4-8 (Receive Sa4-8-Bit Register) - -------------------- E1 --------------------------- */ - -#define RSA4_RS47 0x80 -#define RSA4_RS46 0x40 -#define RSA4_RS45 0x20 -#define RSA4_RS44 0x10 -#define RSA4_RS43 0x08 -#define RSA4_RS42 0x04 -#define RSA4_RS41 0x02 -#define RSA4_RS40 0x01 - -#define RSA5_RS57 0x80 -#define RSA5_RS56 0x40 -#define RSA5_RS55 0x20 -#define RSA5_RS54 0x10 -#define RSA5_RS53 0x08 -#define RSA5_RS52 0x04 -#define RSA5_RS51 0x02 -#define RSA5_RS50 0x01 - -#define RSA6_RS67 0x80 -#define RSA6_RS66 0x40 -#define RSA6_RS65 0x20 -#define RSA6_RS64 0x10 -#define RSA6_RS63 0x08 -#define RSA6_RS62 0x04 -#define RSA6_RS61 0x02 -#define RSA6_RS60 0x01 - -#define RSA7_RS77 0x80 -#define RSA7_RS76 0x40 -#define RSA7_RS75 0x20 -#define RSA7_RS74 0x10 -#define RSA7_RS73 0x08 -#define RSA7_RS72 0x04 -#define RSA7_RS71 0x02 -#define RSA7_RS70 0x01 - -#define RSA8_RS87 0x80 -#define RSA8_RS86 0x40 -#define RSA8_RS85 0x20 -#define RSA8_RS84 0x10 -#define RSA8_RS83 0x08 -#define RSA8_RS82 0x04 -#define RSA8_RS81 0x02 -#define RSA8_RS80 0x01 - -/* RSA6S (Receive Sa6 Bit Status Register) - ------------------------ T1 ------------------------- */ - -#define RSA6S_SX 0x20 -#define RSA6S_SF 0x10 -#define RSA6S_SE 0x08 -#define RSA6S_SC 0x04 -#define RSA6S_SA 0x02 -#define RSA6S_S8 0x01 - - -/* RDL1-3 Receive DL-Bit Register1-3) - ------------------------ T1 ------------------------- */ - -#define RDL1_RDL17 0x80 -#define RDL1_RDL16 0x40 -#define RDL1_RDL15 0x20 -#define RDL1_RDL14 0x10 -#define RDL1_RDL13 0x08 -#define RDL1_RDL12 0x04 -#define RDL1_RDL11 0x02 -#define RDL1_RDL10 0x01 - -#define RDL2_RDL27 0x80 -#define RDL2_RDL26 0x40 -#define RDL2_RDL25 0x20 -#define RDL2_RDL24 0x10 -#define RDL2_RDL23 0x08 -#define RDL2_RDL22 0x04 -#define RDL2_RDL21 0x02 -#define RDL2_RDL20 0x01 - -#define RDL3_RDL37 0x80 -#define RDL3_RDL36 0x40 -#define RDL3_RDL35 0x20 -#define RDL3_RDL34 0x10 -#define RDL3_RDL33 0x08 -#define RDL3_RDL32 0x04 -#define RDL3_RDL31 0x02 -#define RDL3_RDL30 0x01 - - -/* SIS (Signaling Status Register) - - -------------------- E1 & T1 -------------------------- */ - -#define SIS_XDOV 0x80 -#define SIS_XFW 0x40 -#define SIS_XREP 0x20 -#define SIS_RLI 0x08 -#define SIS_CEC 0x04 -#define SIS_BOM 0x01 - - -/* RSIS (Receive Signaling Status Register) - - -------------------- E1 & T1 --------------------------- */ - -#define RSIS_VFR 0x80 -#define RSIS_RDO 0x40 -#define RSIS_CRC16 0x20 -#define RSIS_RAB 0x10 -#define RSIS_HA1 0x08 -#define RSIS_HA0 0x04 -#define RSIS_HFR 0x02 -#define RSIS_LA 0x01 - - -/* RBCL/H (Receive Byte Count Low/High) - - ------------------- E1 & T1 ----------------------- */ - -#define RBCL_RBC7 0x80 -#define RBCL_RBC6 0x40 -#define RBCL_RBC5 0x20 -#define RBCL_RBC4 0x10 -#define RBCL_RBC3 0x08 -#define RBCL_RBC2 0x04 -#define RBCL_RBC1 0x02 -#define RBCL_RBC0 0x01 - -#define RBCH_OV 0x10 -#define RBCH_RBC11 0x08 -#define RBCH_RBC10 0x04 -#define RBCH_RBC9 0x02 -#define RBCH_RBC8 0x01 - - -/* ISR1-3 (Interrupt Status Register 1-3) - - ------------------ E1 & T1 ------------------------------ */ - -#define FISR0_RME 0x80 -#define FISR0_RFS 0x40 -#define FISR0_T8MS 0x20 -#define FISR0_ISF 0x20 -#define FISR0_RMB 0x10 -#define FISR0_CASC 0x08 -#define FISR0_RSC 0x08 -#define FISR0_CRC6 0x04 -#define FISR0_CRC4 0x04 -#define FISR0_PDEN 0x02 -#define FISR0_RPF 0x01 - -#define FISR1_CASE 0x80 -#define FISR1_LLBSC 0x80 -#define FISR1_RDO 0x40 -#define FISR1_ALLS 0x20 -#define FISR1_XDU 0x10 -#define FISR1_XMB 0x08 -#define FISR1_XLSC 0x02 -#define FISR1_XPR 0x01 - -#define FISR2_FAR 0x80 -#define FISR2_LFA 0x40 -#define FISR2_MFAR 0x20 -#define FISR2_T400MS 0x10 -#define FISR2_LMFA 0x10 -#define FISR2_AIS 0x08 -#define FISR2_LOS 0x04 -#define FISR2_RAR 0x02 -#define FISR2_RA 0x01 - -#define FISR3_ES 0x80 -#define FISR3_SEC 0x40 -#define FISR3_LMFA16 0x20 -#define FISR3_AIS16 0x10 -#define FISR3_RA16 0x08 -#define FISR3_API 0x04 -#define FISR3_XSLP 0x20 -#define FISR3_XSLN 0x10 -#define FISR3_LLBSC 0x08 -#define FISR3_XRS 0x04 -#define FISR3_SLN 0x02 -#define FISR3_SLP 0x01 - - -/* GIS (Global Interrupt Status Register) - - --------------------- E1 & T1 --------------------- */ - -#define GIS_ISR3 0x08 -#define GIS_ISR2 0x04 -#define GIS_ISR1 0x02 -#define GIS_ISR0 0x01 - - -/* VSTR (Version Status Register) - - --------------------- E1 & T1 --------------------- */ - -#define VSTR_VN3 0x08 -#define VSTR_VN2 0x04 -#define VSTR_VN1 0x02 -#define VSTR_VN0 0x01 - - -/*>>>>>>>>>>>>>>>>>>>>> Local Control Structures <<<<<<<<<<<<<<<<<<<<<<<<< */ - -/* Write-only Registers (E1/T1 control mode write registers) */ -#define XFIFOH 0x00 /* Tx FIFO High Byte */ -#define XFIFOL 0x01 /* Tx FIFO Low Byte */ -#define CMDR 0x02 /* Command Reg */ -#define DEC 0x60 /* Disable Error Counter */ -#define TEST2 0x62 /* Manuf. Test Reg 2 */ -#define XS(nbr) (0x70 + (nbr)) /* Tx CAS Reg (0 to 15) */ - -/* Read-write Registers (E1/T1 status mode read registers) */ -#define MODE 0x03 /* Mode Reg */ -#define RAH1 0x04 /* Receive Address High 1 */ -#define RAH2 0x05 /* Receive Address High 2 */ -#define RAL1 0x06 /* Receive Address Low 1 */ -#define RAL2 0x07 /* Receive Address Low 2 */ -#define IPC 0x08 /* Interrupt Port Configuration */ -#define CCR1 0x09 /* Common Configuration Reg 1 */ -#define CCR3 0x0A /* Common Configuration Reg 3 */ -#define PRE 0x0B /* Preamble Reg */ -#define RTR1 0x0C /* Receive Timeslot Reg 1 */ -#define RTR2 0x0D /* Receive Timeslot Reg 2 */ -#define RTR3 0x0E /* Receive Timeslot Reg 3 */ -#define RTR4 0x0F /* Receive Timeslot Reg 4 */ -#define TTR1 0x10 /* Transmit Timeslot Reg 1 */ -#define TTR2 0x11 /* Transmit Timeslot Reg 2 */ -#define TTR3 0x12 /* Transmit Timeslot Reg 3 */ -#define TTR4 0x13 /* Transmit Timeslot Reg 4 */ -#define IMR0 0x14 /* Interrupt Mask Reg 0 */ -#define IMR1 0x15 /* Interrupt Mask Reg 1 */ -#define IMR2 0x16 /* Interrupt Mask Reg 2 */ -#define IMR3 0x17 /* Interrupt Mask Reg 3 */ -#define IMR4 0x18 /* Interrupt Mask Reg 4 */ -#define IMR5 0x19 /* Interrupt Mask Reg 5 */ -#define FMR0 0x1A /* Framer Mode Reigster 0 */ -#define FMR1 0x1B /* Framer Mode Reigster 1 */ -#define FMR2 0x1C /* Framer Mode Reigster 2 */ -#define LOOP 0x1D /* Channel Loop Back */ -#define XSW 0x1E /* Transmit Service Word */ -#define FMR4 0x1E /* Framer Mode Reg 4 */ -#define XSP 0x1F /* Transmit Spare Bits */ -#define FMR5 0x1F /* Framer Mode Reg 5 */ -#define XC0 0x20 /* Transmit Control 0 */ -#define XC1 0x21 /* Transmit Control 1 */ -#define RC0 0x22 /* Receive Control 0 */ -#define RC1 0x23 /* Receive Control 1 */ -#define XPM0 0x24 /* Transmit Pulse Mask 0 */ -#define XPM1 0x25 /* Transmit Pulse Mask 1 */ -#define XPM2 0x26 /* Transmit Pulse Mask 2 */ -#define TSWM 0x27 /* Transparent Service Word Mask */ -#define TEST1 0x28 /* Manuf. Test Reg 1 */ -#define IDLE 0x29 /* Idle Channel Code */ -#define XSA4 0x2A /* Transmit SA4 Bit Reg */ -#define XDL1 0x2A /* Transmit DL-Bit Reg 2 */ -#define XSA5 0x2B /* Transmit SA4 Bit Reg */ -#define XDL2 0x2B /* Transmit DL-Bit Reg 2 */ -#define XSA6 0x2C /* Transmit SA4 Bit Reg */ -#define XDL3 0x2C /* Transmit DL-Bit Reg 2 */ -#define XSA7 0x2D /* Transmit SA4 Bit Reg */ -#define CCB1 0x2D /* Clear Channel Reg 1 */ -#define XSA8 0x2E /* Transmit SA4 Bit Reg */ -#define CCB2 0x2E /* Clear Channel Reg 2 */ -#define FMR3 0x2F /* Framer Mode Reg. 3 */ -#define CCB3 0x2F /* Clear Channel Reg 3 */ -#define ICB1 0x30 /* Idle Channel Reg 1 */ -#define ICB2 0x31 /* Idle Channel Reg 2 */ -#define ICB3 0x32 /* Idle Channel Reg 3 */ -#define ICB4 0x33 /* Idle Channel Reg 4 */ -#define LIM0 0x34 /* Line Interface Mode 0 */ -#define LIM1 0x35 /* Line Interface Mode 1 */ -#define PCDR 0x36 /* Pulse Count Detection */ -#define PCRR 0x37 /* Pulse Count Recovery */ -#define LIM2 0x38 /* Line Interface Mode Reg 2 */ -#define LCR1 0x39 /* Loop Code Reg 1 */ -#define LCR2 0x3A /* Loop Code Reg 2 */ -#define LCR3 0x3B /* Loop Code Reg 3 */ -#define SIC1 0x3C /* System Interface Control 1 */ - -/* Read-only Registers (E1/T1 control mode read registers) */ -#define RFIFOH 0x00 /* Receive FIFO */ -#define RFIFOL 0x01 /* Receive FIFO */ -#define FRS0 0x4C /* Framer Receive Status 0 */ -#define FRS1 0x4D /* Framer Receive Status 1 */ -#define RSW 0x4E /* Receive Service Word */ -#define FRS2 0x4E /* Framer Receive Status 2 */ -#define RSP 0x4F /* Receive Spare Bits */ -#define FRS3 0x4F /* Framer Receive Status 3 */ -#define FECL 0x50 /* Framing Error Counter */ -#define FECH 0x51 /* Framing Error Counter */ -#define CVCL 0x52 /* Code Violation Counter */ -#define CVCH 0x53 /* Code Violation Counter */ -#define CECL 0x54 /* CRC Error Counter 1 */ -#define CECH 0x55 /* CRC Error Counter 1 */ -#define EBCL 0x56 /* E-Bit Error Counter */ -#define EBCH 0x57 /* E-Bit Error Counter */ -#define BECL 0x58 /* Bit Error Counter Low */ -#define BECH 0x59 /* Bit Error Counter Low */ -#define CEC3 0x5A /* CRC Error Counter 3 (16-bit) */ -#define RSA4 0x5C /* Receive SA4 Bit Reg */ -#define RDL1 0x5C /* Receive DL-Bit Reg 1 */ -#define RSA5 0x5D /* Receive SA5 Bit Reg */ -#define RDL2 0x5D /* Receive DL-Bit Reg 2 */ -#define RSA6 0x5E /* Receive SA6 Bit Reg */ -#define RDL3 0x5E /* Receive DL-Bit Reg 3 */ -#define RSA7 0x5F /* Receive SA7 Bit Reg */ -#define RSA8 0x60 /* Receive SA8 Bit Reg */ -#define RSA6S 0x61 /* Receive SA6 Bit Status Reg */ -#define TSR0 0x62 /* Manuf. Test Reg 0 */ -#define TSR1 0x63 /* Manuf. Test Reg 1 */ -#define SIS 0x64 /* Signaling Status Reg */ -#define RSIS 0x65 /* Receive Signaling Status Reg */ -#define RBCL 0x66 /* Receive Byte Control */ -#define RBCH 0x67 /* Receive Byte Control */ -#define FISR0 0x68 /* Interrupt Status Reg 0 */ -#define FISR1 0x69 /* Interrupt Status Reg 1 */ -#define FISR2 0x6A /* Interrupt Status Reg 2 */ -#define FISR3 0x6B /* Interrupt Status Reg 3 */ -#define GIS 0x6E /* Global Interrupt Status */ -#define VSTR 0x6F /* Version Status */ -#define RS(nbr) (0x70 + (nbr)) /* Rx CAS Reg (0 to 15) */ - -#endif /* _FALC_LH_H */ - diff --git a/drivers/net/wan/pc300.h b/drivers/net/wan/pc300.h deleted file mode 100644 index 2e4f84f..0000000 --- a/drivers/net/wan/pc300.h +++ /dev/null @@ -1,436 +0,0 @@ -/* - * pc300.h Cyclades-PC300(tm) Kernel API Definitions. - * - * Author: Ivan Passos - * - * Copyright: (c) 1999-2002 Cyclades Corp. - * - * 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. - * - * $Log: pc300.h,v $ - * Revision 3.12 2002/03/07 14:17:09 henrique - * License data fixed - * - * Revision 3.11 2002/01/28 21:09:39 daniela - * Included ';' after pc300hw.bus. - * - * Revision 3.10 2002/01/17 17:58:52 ivan - * Support for PC300-TE/M (PMC). - * - * Revision 3.9 2001/09/28 13:30:53 daniela - * Renamed dma_start routine to rx_dma_start. - * - * Revision 3.8 2001/09/24 13:03:45 daniela - * Fixed BOF interrupt treatment. Created dma_start routine. - * - * Revision 3.7 2001/08/10 17:19:58 daniela - * Fixed IOCTLs defines. - * - * Revision 3.6 2001/07/18 19:24:42 daniela - * Included kernel version. - * - * Revision 3.5 2001/07/05 18:38:08 daniela - * DMA transmission bug fix. - * - * Revision 3.4 2001/06/26 17:10:40 daniela - * New configuration parameters (line code, CRC calculation and clock). - * - * Revision 3.3 2001/06/22 13:13:02 regina - * MLPPP implementation - * - * Revision 3.2 2001/06/18 17:56:09 daniela - * Increased DEF_MTU and TX_QUEUE_LEN. - * - * Revision 3.1 2001/06/15 12:41:10 regina - * upping major version number - * - * Revision 1.1.1.1 2001/06/13 20:25:06 daniela - * PC300 initial CVS version (3.4.0-pre1) - * - * Revision 2.3 2001/03/05 daniela - * Created struct pc300conf, to provide the hardware information to pc300util. - * Inclusion of 'alloc_ramsize' field on structure 'pc300hw'. - * - * Revision 2.2 2000/12/22 daniela - * Structures and defines to support pc300util: statistics, status, - * loopback tests, trace. - * - * Revision 2.1 2000/09/28 ivan - * Inclusion of 'iophys' and 'iosize' fields on structure 'pc300hw', to - * allow release of I/O region at module unload. - * Changed location of include files. - * - * Revision 2.0 2000/03/27 ivan - * Added support for the PC300/TE cards. - * - * Revision 1.1 2000/01/31 ivan - * Replaced 'pc300[drv|sca].h' former PC300 driver include files. - * - * Revision 1.0 1999/12/16 ivan - * First official release. - * Inclusion of 'nchan' field on structure 'pc300hw', to allow variable - * number of ports per card. - * Inclusion of 'if_ptr' field on structure 'pc300dev'. - * - * Revision 0.6 1999/11/17 ivan - * Changed X.25-specific function names to comply with adopted convention. - * - * Revision 0.5 1999/11/16 Daniela Squassoni - * X.25 support. - * - * Revision 0.4 1999/11/15 ivan - * Inclusion of 'clock' field on structure 'pc300hw'. - * - * Revision 0.3 1999/11/10 ivan - * IOCTL name changing. - * Inclusion of driver function prototypes. - * - * Revision 0.2 1999/11/03 ivan - * Inclusion of 'tx_skb' and union 'ifu' on structure 'pc300dev'. - * - * Revision 0.1 1999/01/15 ivan - * Initial version. - * - */ - -#ifndef _PC300_H -#define _PC300_H - -#include -#include "hd64572.h" -#include "pc300-falc-lh.h" - -#define PC300_PROTO_MLPPP 1 - -#define PC300_MAXCHAN 2 /* Number of channels per card */ - -#define PC300_RAMSIZE 0x40000 /* RAM window size (256Kb) */ -#define PC300_FALCSIZE 0x400 /* FALC window size (1Kb) */ - -#define PC300_OSC_CLOCK 24576000 -#define PC300_PCI_CLOCK 33000000 - -#define BD_DEF_LEN 0x0800 /* DMA buffer length (2KB) */ -#define DMA_TX_MEMSZ 0x8000 /* Total DMA Tx memory size (32KB/ch) */ -#define DMA_RX_MEMSZ 0x10000 /* Total DMA Rx memory size (64KB/ch) */ - -#define N_DMA_TX_BUF (DMA_TX_MEMSZ / BD_DEF_LEN) /* DMA Tx buffers */ -#define N_DMA_RX_BUF (DMA_RX_MEMSZ / BD_DEF_LEN) /* DMA Rx buffers */ - -/* DMA Buffer Offsets */ -#define DMA_TX_BASE ((N_DMA_TX_BUF + N_DMA_RX_BUF) * \ - PC300_MAXCHAN * sizeof(pcsca_bd_t)) -#define DMA_RX_BASE (DMA_TX_BASE + PC300_MAXCHAN*DMA_TX_MEMSZ) - -/* DMA Descriptor Offsets */ -#define DMA_TX_BD_BASE 0x0000 -#define DMA_RX_BD_BASE (DMA_TX_BD_BASE + ((PC300_MAXCHAN*DMA_TX_MEMSZ / \ - BD_DEF_LEN) * sizeof(pcsca_bd_t))) - -/* DMA Descriptor Macros */ -#define TX_BD_ADDR(chan, n) (DMA_TX_BD_BASE + \ - ((N_DMA_TX_BUF*chan) + n) * sizeof(pcsca_bd_t)) -#define RX_BD_ADDR(chan, n) (DMA_RX_BD_BASE + \ - ((N_DMA_RX_BUF*chan) + n) * sizeof(pcsca_bd_t)) - -/* Macro to access the FALC registers (TE only) */ -#define F_REG(reg, chan) (0x200*(chan) + ((reg)<<2)) - -/*************************************** - * Memory access functions/macros * - * (required to support Alpha systems) * - ***************************************/ -#define cpc_writeb(port,val) {writeb((u8)(val),(port)); mb();} -#define cpc_writew(port,val) {writew((ushort)(val),(port)); mb();} -#define cpc_writel(port,val) {writel((u32)(val),(port)); mb();} - -#define cpc_readb(port) readb(port) -#define cpc_readw(port) readw(port) -#define cpc_readl(port) readl(port) - -/****** Data Structures *****************************************************/ - -/* - * RUNTIME_9050 - PLX PCI9050-1 local configuration and shared runtime - * registers. This structure can be used to access the 9050 registers - * (memory mapped). - */ -struct RUNTIME_9050 { - u32 loc_addr_range[4]; /* 00-0Ch : Local Address Ranges */ - u32 loc_rom_range; /* 10h : Local ROM Range */ - u32 loc_addr_base[4]; /* 14-20h : Local Address Base Addrs */ - u32 loc_rom_base; /* 24h : Local ROM Base */ - u32 loc_bus_descr[4]; /* 28-34h : Local Bus Descriptors */ - u32 rom_bus_descr; /* 38h : ROM Bus Descriptor */ - u32 cs_base[4]; /* 3C-48h : Chip Select Base Addrs */ - u32 intr_ctrl_stat; /* 4Ch : Interrupt Control/Status */ - u32 init_ctrl; /* 50h : EEPROM ctrl, Init Ctrl, etc */ -}; - -#define PLX_9050_LINT1_ENABLE 0x01 -#define PLX_9050_LINT1_POL 0x02 -#define PLX_9050_LINT1_STATUS 0x04 -#define PLX_9050_LINT2_ENABLE 0x08 -#define PLX_9050_LINT2_POL 0x10 -#define PLX_9050_LINT2_STATUS 0x20 -#define PLX_9050_INTR_ENABLE 0x40 -#define PLX_9050_SW_INTR 0x80 - -/* Masks to access the init_ctrl PLX register */ -#define PC300_CLKSEL_MASK (0x00000004UL) -#define PC300_CHMEDIA_MASK(chan) (0x00000020UL<<(chan*3)) -#define PC300_CTYPE_MASK (0x00000800UL) - -/* CPLD Registers (base addr = falcbase, TE only) */ -/* CPLD v. 0 */ -#define CPLD_REG1 0x140 /* Chip resets, DCD/CTS status */ -#define CPLD_REG2 0x144 /* Clock enable , LED control */ -/* CPLD v. 2 or higher */ -#define CPLD_V2_REG1 0x100 /* Chip resets, DCD/CTS status */ -#define CPLD_V2_REG2 0x104 /* Clock enable , LED control */ -#define CPLD_ID_REG 0x108 /* CPLD version */ - -/* CPLD Register bit description: for the FALC bits, they should always be - set based on the channel (use (bit<<(2*ch)) to access the correct bit for - that channel) */ -#define CPLD_REG1_FALC_RESET 0x01 -#define CPLD_REG1_SCA_RESET 0x02 -#define CPLD_REG1_GLOBAL_CLK 0x08 -#define CPLD_REG1_FALC_DCD 0x10 -#define CPLD_REG1_FALC_CTS 0x20 - -#define CPLD_REG2_FALC_TX_CLK 0x01 -#define CPLD_REG2_FALC_RX_CLK 0x02 -#define CPLD_REG2_FALC_LED1 0x10 -#define CPLD_REG2_FALC_LED2 0x20 - -/* Structure with FALC-related fields (TE only) */ -#define PC300_FALC_MAXLOOP 0x0000ffff /* for falc_issue_cmd() */ - -typedef struct falc { - u8 sync; /* If true FALC is synchronized */ - u8 active; /* if TRUE then already active */ - u8 loop_active; /* if TRUE a line loopback UP was received */ - u8 loop_gen; /* if TRUE a line loopback UP was issued */ - - u8 num_channels; - u8 offset; /* 1 for T1, 0 for E1 */ - u8 full_bandwidth; - - u8 xmb_cause; - u8 multiframe_mode; - - /* Statistics */ - u16 pden; /* Pulse Density violation count */ - u16 los; /* Loss of Signal count */ - u16 losr; /* Loss of Signal recovery count */ - u16 lfa; /* Loss of frame alignment count */ - u16 farec; /* Frame Alignment Recovery count */ - u16 lmfa; /* Loss of multiframe alignment count */ - u16 ais; /* Remote Alarm indication Signal count */ - u16 sec; /* One-second timer */ - u16 es; /* Errored second */ - u16 rai; /* remote alarm received */ - u16 bec; - u16 fec; - u16 cvc; - u16 cec; - u16 ebc; - - /* Status */ - u8 red_alarm; - u8 blue_alarm; - u8 loss_fa; - u8 yellow_alarm; - u8 loss_mfa; - u8 prbs; -} falc_t; - -typedef struct falc_status { - u8 sync; /* If true FALC is synchronized */ - u8 red_alarm; - u8 blue_alarm; - u8 loss_fa; - u8 yellow_alarm; - u8 loss_mfa; - u8 prbs; -} falc_status_t; - -typedef struct rsv_x21_status { - u8 dcd; - u8 dsr; - u8 cts; - u8 rts; - u8 dtr; -} rsv_x21_status_t; - -typedef struct pc300stats { - int hw_type; - u32 line_on; - u32 line_off; - struct net_device_stats gen_stats; - falc_t te_stats; -} pc300stats_t; - -typedef struct pc300status { - int hw_type; - rsv_x21_status_t gen_status; - falc_status_t te_status; -} pc300status_t; - -typedef struct pc300loopback { - char loop_type; - char loop_on; -} pc300loopback_t; - -typedef struct pc300patterntst { - char patrntst_on; /* 0 - off; 1 - on; 2 - read num_errors */ - u16 num_errors; -} pc300patterntst_t; - -typedef struct pc300dev { - struct pc300ch *chan; - u8 trace_on; - u32 line_on; /* DCD(X.21, RSV) / sync(TE) change counters */ - u32 line_off; - char name[16]; - struct net_device *dev; -#ifdef CONFIG_PC300_MLPPP - void *cpc_tty; /* information to PC300 TTY driver */ -#endif -}pc300dev_t; - -typedef struct pc300hw { - int type; /* RSV, X21, etc. */ - int bus; /* Bus (PCI, PMC, etc.) */ - int nchan; /* number of channels */ - int irq; /* interrupt request level */ - u32 clock; /* Board clock */ - u8 cpld_id; /* CPLD ID (TE only) */ - u16 cpld_reg1; /* CPLD reg 1 (TE only) */ - u16 cpld_reg2; /* CPLD reg 2 (TE only) */ - u16 gpioc_reg; /* PLX GPIOC reg */ - u16 intctl_reg; /* PLX Int Ctrl/Status reg */ - u32 iophys; /* PLX registers I/O base */ - u32 iosize; /* PLX registers I/O size */ - u32 plxphys; /* PLX registers MMIO base (physical) */ - void __iomem * plxbase; /* PLX registers MMIO base (virtual) */ - u32 plxsize; /* PLX registers MMIO size */ - u32 scaphys; /* SCA registers MMIO base (physical) */ - void __iomem * scabase; /* SCA registers MMIO base (virtual) */ - u32 scasize; /* SCA registers MMIO size */ - u32 ramphys; /* On-board RAM MMIO base (physical) */ - void __iomem * rambase; /* On-board RAM MMIO base (virtual) */ - u32 alloc_ramsize; /* RAM MMIO size allocated by the PCI bridge */ - u32 ramsize; /* On-board RAM MMIO size */ - u32 falcphys; /* FALC registers MMIO base (physical) */ - void __iomem * falcbase;/* FALC registers MMIO base (virtual) */ - u32 falcsize; /* FALC registers MMIO size */ -} pc300hw_t; - -typedef struct pc300chconf { - sync_serial_settings phys_settings; /* Clock type/rate (in bps), - loopback mode */ - raw_hdlc_proto proto_settings; /* Encoding, parity (CRC) */ - u32 media; /* HW media (RS232, V.35, etc.) */ - u32 proto; /* Protocol (PPP, X.25, etc.) */ - - /* TE-specific parameters */ - u8 lcode; /* Line Code (AMI, B8ZS, etc.) */ - u8 fr_mode; /* Frame Mode (ESF, D4, etc.) */ - u8 lbo; /* Line Build Out */ - u8 rx_sens; /* Rx Sensitivity (long- or short-haul) */ - u32 tslot_bitmap; /* bit[i]=1 => timeslot _i_ is active */ -} pc300chconf_t; - -typedef struct pc300ch { - struct pc300 *card; - int channel; - pc300dev_t d; - pc300chconf_t conf; - u8 tx_first_bd; /* First TX DMA block descr. w/ data */ - u8 tx_next_bd; /* Next free TX DMA block descriptor */ - u8 rx_first_bd; /* First free RX DMA block descriptor */ - u8 rx_last_bd; /* Last free RX DMA block descriptor */ - u8 nfree_tx_bd; /* Number of free TX DMA block descriptors */ - falc_t falc; /* FALC structure (TE only) */ -} pc300ch_t; - -typedef struct pc300 { - pc300hw_t hw; /* hardware config. */ - pc300ch_t chan[PC300_MAXCHAN]; - spinlock_t card_lock; -} pc300_t; - -typedef struct pc300conf { - pc300hw_t hw; - pc300chconf_t conf; -} pc300conf_t; - -/* DEV ioctl() commands */ -#define N_SPPP_IOCTLS 2 - -enum pc300_ioctl_cmds { - SIOCCPCRESERVED = (SIOCDEVPRIVATE + N_SPPP_IOCTLS), - SIOCGPC300CONF, - SIOCSPC300CONF, - SIOCGPC300STATUS, - SIOCGPC300FALCSTATUS, - SIOCGPC300UTILSTATS, - SIOCGPC300UTILSTATUS, - SIOCSPC300TRACE, - SIOCSPC300LOOPBACK, - SIOCSPC300PATTERNTEST, -}; - -/* Loopback types - PC300/TE boards */ -enum pc300_loopback_cmds { - PC300LOCLOOP = 1, - PC300REMLOOP, - PC300PAYLOADLOOP, - PC300GENLOOPUP, - PC300GENLOOPDOWN, -}; - -/* Control Constant Definitions */ -#define PC300_RSV 0x01 -#define PC300_X21 0x02 -#define PC300_TE 0x03 - -#define PC300_PCI 0x00 -#define PC300_PMC 0x01 - -#define PC300_LC_AMI 0x01 -#define PC300_LC_B8ZS 0x02 -#define PC300_LC_NRZ 0x03 -#define PC300_LC_HDB3 0x04 - -/* Framing (T1) */ -#define PC300_FR_ESF 0x01 -#define PC300_FR_D4 0x02 -#define PC300_FR_ESF_JAPAN 0x03 - -/* Framing (E1) */ -#define PC300_FR_MF_CRC4 0x04 -#define PC300_FR_MF_NON_CRC4 0x05 -#define PC300_FR_UNFRAMED 0x06 - -#define PC300_LBO_0_DB 0x00 -#define PC300_LBO_7_5_DB 0x01 -#define PC300_LBO_15_DB 0x02 -#define PC300_LBO_22_5_DB 0x03 - -#define PC300_RX_SENS_SH 0x01 -#define PC300_RX_SENS_LH 0x02 - -#define PC300_TX_TIMEOUT (2*HZ) -#define PC300_TX_QUEUE_LEN 100 -#define PC300_DEF_MTU 1600 - -/* Function Prototypes */ -int cpc_open(struct net_device *dev); - -#endif /* _PC300_H */ diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c deleted file mode 100644 index cb0f8d9..0000000 --- a/drivers/net/wan/pc300_drv.c +++ /dev/null @@ -1,3670 +0,0 @@ -#define USE_PCI_CLOCK -static const char rcsid[] = -"Revision: 3.4.5 Date: 2002/03/07 "; - -/* - * pc300.c Cyclades-PC300(tm) Driver. - * - * Author: Ivan Passos - * Maintainer: PC300 Maintainer - * - * Copyright: (c) 1999-2003 Cyclades Corp. - * - * 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. - * - * Using tabstop = 4. - * - * $Log: pc300_drv.c,v $ - * Revision 3.23 2002/03/20 13:58:40 henrique - * Fixed ortographic mistakes - * - * Revision 3.22 2002/03/13 16:56:56 henrique - * Take out the debug messages - * - * Revision 3.21 2002/03/07 14:17:09 henrique - * License data fixed - * - * Revision 3.20 2002/01/17 17:58:52 ivan - * Support for PC300-TE/M (PMC). - * - * Revision 3.19 2002/01/03 17:08:47 daniela - * Enables DMA reception when the SCA-II disables it improperly. - * - * Revision 3.18 2001/12/03 18:47:50 daniela - * Esthetic changes. - * - * Revision 3.17 2001/10/19 16:50:13 henrique - * Patch to kernel 2.4.12 and new generic hdlc. - * - * Revision 3.16 2001/10/16 15:12:31 regina - * clear statistics - * - * Revision 3.11 to 3.15 2001/10/11 20:26:04 daniela - * More DMA fixes for noisy lines. - * Return the size of bad frames in dma_get_rx_frame_size, so that the Rx buffer - * descriptors can be cleaned by dma_buf_read (called in cpc_net_rx). - * Renamed dma_start routine to rx_dma_start. Improved Rx statistics. - * Fixed BOF interrupt treatment. Created dma_start routine. - * Changed min and max to cpc_min and cpc_max. - * - * Revision 3.10 2001/08/06 12:01:51 regina - * Fixed problem in DSR_DE bit. - * - * Revision 3.9 2001/07/18 19:27:26 daniela - * Added some history comments. - * - * Revision 3.8 2001/07/12 13:11:19 regina - * bug fix - DCD-OFF in pc300 tty driver - * - * Revision 3.3 to 3.7 2001/07/06 15:00:20 daniela - * Removing kernel 2.4.3 and previous support. - * DMA transmission bug fix. - * MTU check in cpc_net_rx fixed. - * Boot messages reviewed. - * New configuration parameters (line code, CRC calculation and clock). - * - * Revision 3.2 2001/06/22 13:13:02 regina - * MLPPP implementation. Changed the header of message trace to include - * the device name. New format : "hdlcX[R/T]: ". - * Default configuration changed. - * - * Revision 3.1 2001/06/15 regina - * in cpc_queue_xmit, netif_stop_queue is called if don't have free descriptor - * upping major version number - * - * Revision 1.1.1.1 2001/06/13 20:25:04 daniela - * PC300 initial CVS version (3.4.0-pre1) - * - * Revision 3.0.1.2 2001/06/08 daniela - * Did some changes in the DMA programming implementation to avoid the - * occurrence of a SCA-II bug when CDA is accessed during a DMA transfer. - * - * Revision 3.0.1.1 2001/05/02 daniela - * Added kernel 2.4.3 support. - * - * Revision 3.0.1.0 2001/03/13 daniela, henrique - * Added Frame Relay Support. - * Driver now uses HDLC generic driver to provide protocol support. - * - * Revision 3.0.0.8 2001/03/02 daniela - * Fixed ram size detection. - * Changed SIOCGPC300CONF ioctl, to give hw information to pc300util. - * - * Revision 3.0.0.7 2001/02/23 daniela - * netif_stop_queue called before the SCA-II transmition commands in - * cpc_queue_xmit, and with interrupts disabled to avoid race conditions with - * transmition interrupts. - * Fixed falc_check_status for Unframed E1. - * - * Revision 3.0.0.6 2000/12/13 daniela - * Implemented pc300util support: trace, statistics, status and loopback - * tests for the PC300 TE boards. - * - * Revision 3.0.0.5 2000/12/12 ivan - * Added support for Unframed E1. - * Implemented monitor mode. - * Fixed DCD sensitivity on the second channel. - * Driver now complies with new PCI kernel architecture. - * - * Revision 3.0.0.4 2000/09/28 ivan - * Implemented DCD sensitivity. - * Moved hardware-specific open to the end of cpc_open, to avoid race - * conditions with early reception interrupts. - * Included code for [request|release]_mem_region(). - * Changed location of pc300.h . - * Minor code revision (contrib. of Jeff Garzik). - * - * Revision 3.0.0.3 2000/07/03 ivan - * Previous bugfix for the framing errors with external clock made X21 - * boards stop working. This version fixes it. - * - * Revision 3.0.0.2 2000/06/23 ivan - * Revisited cpc_queue_xmit to prevent race conditions on Tx DMA buffer - * handling when Tx timeouts occur. - * Revisited Rx statistics. - * Fixed a bug in the SCA-II programming that would cause framing errors - * when external clock was configured. - * - * Revision 3.0.0.1 2000/05/26 ivan - * Added logic in the SCA interrupt handler so that no board can monopolize - * the driver. - * Request PLX I/O region, although driver doesn't use it, to avoid - * problems with other drivers accessing it. - * - * Revision 3.0.0.0 2000/05/15 ivan - * Did some changes in the DMA programming implementation to avoid the - * occurrence of a SCA-II bug in the second channel. - * Implemented workaround for PLX9050 bug that would cause a system lockup - * in certain systems, depending on the MMIO addresses allocated to the - * board. - * Fixed the FALC chip programming to avoid synchronization problems in the - * second channel (TE only). - * Implemented a cleaner and faster Tx DMA descriptor cleanup procedure in - * cpc_queue_xmit(). - * Changed the built-in driver implementation so that the driver can use the - * general 'hdlcN' naming convention instead of proprietary device names. - * Driver load messages are now device-centric, instead of board-centric. - * Dynamic allocation of net_device structures. - * Code is now compliant with the new module interface (module_[init|exit]). - * Make use of the PCI helper functions to access PCI resources. - * - * Revision 2.0.0.0 2000/04/15 ivan - * Added support for the PC300/TE boards (T1/FT1/E1/FE1). - * - * Revision 1.1.0.0 2000/02/28 ivan - * Major changes in the driver architecture. - * Softnet compliancy implemented. - * Driver now reports physical instead of virtual memory addresses. - * Added cpc_change_mtu function. - * - * Revision 1.0.0.0 1999/12/16 ivan - * First official release. - * Support for 1- and 2-channel boards (which use distinct PCI Device ID's). - * Support for monolythic installation (i.e., drv built into the kernel). - * X.25 additional checking when lapb_[dis]connect_request returns an error. - * SCA programming now covers X.21 as well. - * - * Revision 0.3.1.0 1999/11/18 ivan - * Made X.25 support configuration-dependent (as it depends on external - * modules to work). - * Changed X.25-specific function names to comply with adopted convention. - * Fixed typos in X.25 functions that would cause compile errors (Daniela). - * Fixed bug in ch_config that would disable interrupts on a previously - * enabled channel if the other channel on the same board was enabled later. - * - * Revision 0.3.0.0 1999/11/16 daniela - * X.25 support. - * - * Revision 0.2.3.0 1999/11/15 ivan - * Function cpc_ch_status now provides more detailed information. - * Added support for X.21 clock configuration. - * Changed TNR1 setting in order to prevent Tx FIFO overaccesses by the SCA. - * Now using PCI clock instead of internal oscillator clock for the SCA. - * - * Revision 0.2.2.0 1999/11/10 ivan - * Changed the *_dma_buf_check functions so that they would print only - * the useful info instead of the whole buffer descriptor bank. - * Fixed bug in cpc_queue_xmit that would eventually crash the system - * in case of a packet drop. - * Implemented TX underrun handling. - * Improved SCA fine tuning to boost up its performance. - * - * Revision 0.2.1.0 1999/11/03 ivan - * Added functions *dma_buf_pt_init to allow independent initialization - * of the next-descr. and DMA buffer pointers on the DMA descriptors. - * Kernel buffer release and tbusy clearing is now done in the interrupt - * handler. - * Fixed bug in cpc_open that would cause an interface reopen to fail. - * Added a protocol-specific code section in cpc_net_rx. - * Removed printk level defs (they might be added back after the beta phase). - * - * Revision 0.2.0.0 1999/10/28 ivan - * Revisited the code so that new protocols can be easily added / supported. - * - * Revision 0.1.0.1 1999/10/20 ivan - * Mostly "esthetic" changes. - * - * Revision 0.1.0.0 1999/10/11 ivan - * Initial version. - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "pc300.h" - -#define CPC_LOCK(card,flags) \ - do { \ - spin_lock_irqsave(&card->card_lock, flags); \ - } while (0) - -#define CPC_UNLOCK(card,flags) \ - do { \ - spin_unlock_irqrestore(&card->card_lock, flags); \ - } while (0) - -#undef PC300_DEBUG_PCI -#undef PC300_DEBUG_INTR -#undef PC300_DEBUG_TX -#undef PC300_DEBUG_RX -#undef PC300_DEBUG_OTHER - -static DEFINE_PCI_DEVICE_TABLE(cpc_pci_dev_id) = { - /* PC300/RSV or PC300/X21, 2 chan */ - {0x120e, 0x300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x300}, - /* PC300/RSV or PC300/X21, 1 chan */ - {0x120e, 0x301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x301}, - /* PC300/TE, 2 chan */ - {0x120e, 0x310, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x310}, - /* PC300/TE, 1 chan */ - {0x120e, 0x311, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x311}, - /* PC300/TE-M, 2 chan */ - {0x120e, 0x320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x320}, - /* PC300/TE-M, 1 chan */ - {0x120e, 0x321, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x321}, - /* End of table */ - {0,}, -}; -MODULE_DEVICE_TABLE(pci, cpc_pci_dev_id); - -#ifndef cpc_min -#define cpc_min(a,b) (((a)<(b))?(a):(b)) -#endif -#ifndef cpc_max -#define cpc_max(a,b) (((a)>(b))?(a):(b)) -#endif - -/* prototypes */ -static void tx_dma_buf_pt_init(pc300_t *, int); -static void tx_dma_buf_init(pc300_t *, int); -static void rx_dma_buf_pt_init(pc300_t *, int); -static void rx_dma_buf_init(pc300_t *, int); -static void tx_dma_buf_check(pc300_t *, int); -static void rx_dma_buf_check(pc300_t *, int); -static irqreturn_t cpc_intr(int, void *); -static int clock_rate_calc(u32, u32, int *); -static u32 detect_ram(pc300_t *); -static void plx_init(pc300_t *); -static void cpc_trace(struct net_device *, struct sk_buff *, char); -static int cpc_attach(struct net_device *, unsigned short, unsigned short); -static int cpc_close(struct net_device *dev); - -#ifdef CONFIG_PC300_MLPPP -void cpc_tty_init(pc300dev_t * dev); -void cpc_tty_unregister_service(pc300dev_t * pc300dev); -void cpc_tty_receive(pc300dev_t * pc300dev); -void cpc_tty_trigger_poll(pc300dev_t * pc300dev); -#endif - -/************************/ -/*** DMA Routines ***/ -/************************/ -static void tx_dma_buf_pt_init(pc300_t * card, int ch) -{ - int i; - int ch_factor = ch * N_DMA_TX_BUF; - volatile pcsca_bd_t __iomem *ptdescr = (card->hw.rambase - + DMA_TX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); - - for (i = 0; i < N_DMA_TX_BUF; i++, ptdescr++) { - cpc_writel(&ptdescr->next, (u32)(DMA_TX_BD_BASE + - (ch_factor + ((i + 1) & (N_DMA_TX_BUF - 1))) * sizeof(pcsca_bd_t))); - cpc_writel(&ptdescr->ptbuf, - (u32)(DMA_TX_BASE + (ch_factor + i) * BD_DEF_LEN)); - } -} - -static void tx_dma_buf_init(pc300_t * card, int ch) -{ - int i; - int ch_factor = ch * N_DMA_TX_BUF; - volatile pcsca_bd_t __iomem *ptdescr = (card->hw.rambase - + DMA_TX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); - - for (i = 0; i < N_DMA_TX_BUF; i++, ptdescr++) { - memset_io(ptdescr, 0, sizeof(pcsca_bd_t)); - cpc_writew(&ptdescr->len, 0); - cpc_writeb(&ptdescr->status, DST_OSB); - } - tx_dma_buf_pt_init(card, ch); -} - -static void rx_dma_buf_pt_init(pc300_t * card, int ch) -{ - int i; - int ch_factor = ch * N_DMA_RX_BUF; - volatile pcsca_bd_t __iomem *ptdescr = (card->hw.rambase - + DMA_RX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); - - for (i = 0; i < N_DMA_RX_BUF; i++, ptdescr++) { - cpc_writel(&ptdescr->next, (u32)(DMA_RX_BD_BASE + - (ch_factor + ((i + 1) & (N_DMA_RX_BUF - 1))) * sizeof(pcsca_bd_t))); - cpc_writel(&ptdescr->ptbuf, - (u32)(DMA_RX_BASE + (ch_factor + i) * BD_DEF_LEN)); - } -} - -static void rx_dma_buf_init(pc300_t * card, int ch) -{ - int i; - int ch_factor = ch * N_DMA_RX_BUF; - volatile pcsca_bd_t __iomem *ptdescr = (card->hw.rambase - + DMA_RX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); - - for (i = 0; i < N_DMA_RX_BUF; i++, ptdescr++) { - memset_io(ptdescr, 0, sizeof(pcsca_bd_t)); - cpc_writew(&ptdescr->len, 0); - cpc_writeb(&ptdescr->status, 0); - } - rx_dma_buf_pt_init(card, ch); -} - -static void tx_dma_buf_check(pc300_t * card, int ch) -{ - volatile pcsca_bd_t __iomem *ptdescr; - int i; - u16 first_bd = card->chan[ch].tx_first_bd; - u16 next_bd = card->chan[ch].tx_next_bd; - - printk("#CH%d: f_bd = %d(0x%08zx), n_bd = %d(0x%08zx)\n", ch, - first_bd, TX_BD_ADDR(ch, first_bd), - next_bd, TX_BD_ADDR(ch, next_bd)); - for (i = first_bd, - ptdescr = (card->hw.rambase + TX_BD_ADDR(ch, first_bd)); - i != ((next_bd + 1) & (N_DMA_TX_BUF - 1)); - i = (i + 1) & (N_DMA_TX_BUF - 1), - ptdescr = (card->hw.rambase + TX_BD_ADDR(ch, i))) { - printk("\n CH%d TX%d: next=0x%x, ptbuf=0x%x, ST=0x%x, len=%d", - ch, i, cpc_readl(&ptdescr->next), - cpc_readl(&ptdescr->ptbuf), - cpc_readb(&ptdescr->status), cpc_readw(&ptdescr->len)); - } - printk("\n"); -} - -#ifdef PC300_DEBUG_OTHER -/* Show all TX buffer descriptors */ -static void tx1_dma_buf_check(pc300_t * card, int ch) -{ - volatile pcsca_bd_t __iomem *ptdescr; - int i; - u16 first_bd = card->chan[ch].tx_first_bd; - u16 next_bd = card->chan[ch].tx_next_bd; - u32 scabase = card->hw.scabase; - - printk ("\nnfree_tx_bd = %d\n", card->chan[ch].nfree_tx_bd); - printk("#CH%d: f_bd = %d(0x%08x), n_bd = %d(0x%08x)\n", ch, - first_bd, TX_BD_ADDR(ch, first_bd), - next_bd, TX_BD_ADDR(ch, next_bd)); - printk("TX_CDA=0x%08x, TX_EDA=0x%08x\n", - cpc_readl(scabase + DTX_REG(CDAL, ch)), - cpc_readl(scabase + DTX_REG(EDAL, ch))); - for (i = 0; i < N_DMA_TX_BUF; i++) { - ptdescr = (card->hw.rambase + TX_BD_ADDR(ch, i)); - printk("\n CH%d TX%d: next=0x%x, ptbuf=0x%x, ST=0x%x, len=%d", - ch, i, cpc_readl(&ptdescr->next), - cpc_readl(&ptdescr->ptbuf), - cpc_readb(&ptdescr->status), cpc_readw(&ptdescr->len)); - } - printk("\n"); -} -#endif - -static void rx_dma_buf_check(pc300_t * card, int ch) -{ - volatile pcsca_bd_t __iomem *ptdescr; - int i; - u16 first_bd = card->chan[ch].rx_first_bd; - u16 last_bd = card->chan[ch].rx_last_bd; - int ch_factor; - - ch_factor = ch * N_DMA_RX_BUF; - printk("#CH%d: f_bd = %d, l_bd = %d\n", ch, first_bd, last_bd); - for (i = 0, ptdescr = (card->hw.rambase + - DMA_RX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); - i < N_DMA_RX_BUF; i++, ptdescr++) { - if (cpc_readb(&ptdescr->status) & DST_OSB) - printk ("\n CH%d RX%d: next=0x%x, ptbuf=0x%x, ST=0x%x, len=%d", - ch, i, cpc_readl(&ptdescr->next), - cpc_readl(&ptdescr->ptbuf), - cpc_readb(&ptdescr->status), - cpc_readw(&ptdescr->len)); - } - printk("\n"); -} - -static int dma_get_rx_frame_size(pc300_t * card, int ch) -{ - volatile pcsca_bd_t __iomem *ptdescr; - u16 first_bd = card->chan[ch].rx_first_bd; - int rcvd = 0; - volatile u8 status; - - ptdescr = (card->hw.rambase + RX_BD_ADDR(ch, first_bd)); - while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) { - rcvd += cpc_readw(&ptdescr->len); - first_bd = (first_bd + 1) & (N_DMA_RX_BUF - 1); - if ((status & DST_EOM) || (first_bd == card->chan[ch].rx_last_bd)) { - /* Return the size of a good frame or incomplete bad frame - * (dma_buf_read will clean the buffer descriptors in this case). */ - return rcvd; - } - ptdescr = (card->hw.rambase + cpc_readl(&ptdescr->next)); - } - return -1; -} - -/* - * dma_buf_write: writes a frame to the Tx DMA buffers - * NOTE: this function writes one frame at a time. - */ -static int dma_buf_write(pc300_t *card, int ch, u8 *ptdata, int len) -{ - int i, nchar; - volatile pcsca_bd_t __iomem *ptdescr; - int tosend = len; - u8 nbuf = ((len - 1) / BD_DEF_LEN) + 1; - - if (nbuf >= card->chan[ch].nfree_tx_bd) { - return -ENOMEM; - } - - for (i = 0; i < nbuf; i++) { - ptdescr = (card->hw.rambase + - TX_BD_ADDR(ch, card->chan[ch].tx_next_bd)); - nchar = cpc_min(BD_DEF_LEN, tosend); - if (cpc_readb(&ptdescr->status) & DST_OSB) { - memcpy_toio((card->hw.rambase + cpc_readl(&ptdescr->ptbuf)), - &ptdata[len - tosend], nchar); - cpc_writew(&ptdescr->len, nchar); - card->chan[ch].nfree_tx_bd--; - if ((i + 1) == nbuf) { - /* This must be the last BD to be used */ - cpc_writeb(&ptdescr->status, DST_EOM); - } else { - cpc_writeb(&ptdescr->status, 0); - } - } else { - return -ENOMEM; - } - tosend -= nchar; - card->chan[ch].tx_next_bd = - (card->chan[ch].tx_next_bd + 1) & (N_DMA_TX_BUF - 1); - } - /* If it gets to here, it means we have sent the whole frame */ - return 0; -} - -/* - * dma_buf_read: reads a frame from the Rx DMA buffers - * NOTE: this function reads one frame at a time. - */ -static int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb) -{ - int nchar; - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - volatile pcsca_bd_t __iomem *ptdescr; - int rcvd = 0; - volatile u8 status; - - ptdescr = (card->hw.rambase + - RX_BD_ADDR(ch, chan->rx_first_bd)); - while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) { - nchar = cpc_readw(&ptdescr->len); - if ((status & (DST_OVR | DST_CRC | DST_RBIT | DST_SHRT | DST_ABT)) || - (nchar > BD_DEF_LEN)) { - - if (nchar > BD_DEF_LEN) - status |= DST_RBIT; - rcvd = -status; - /* Discard remaining descriptors used by the bad frame */ - while (chan->rx_first_bd != chan->rx_last_bd) { - cpc_writeb(&ptdescr->status, 0); - chan->rx_first_bd = (chan->rx_first_bd+1) & (N_DMA_RX_BUF-1); - if (status & DST_EOM) - break; - ptdescr = (card->hw.rambase + - cpc_readl(&ptdescr->next)); - status = cpc_readb(&ptdescr->status); - } - break; - } - if (nchar != 0) { - if (skb) { - memcpy_fromio(skb_put(skb, nchar), - (card->hw.rambase+cpc_readl(&ptdescr->ptbuf)),nchar); - } - rcvd += nchar; - } - cpc_writeb(&ptdescr->status, 0); - cpc_writeb(&ptdescr->len, 0); - chan->rx_first_bd = (chan->rx_first_bd + 1) & (N_DMA_RX_BUF - 1); - - if (status & DST_EOM) - break; - - ptdescr = (card->hw.rambase + cpc_readl(&ptdescr->next)); - } - - if (rcvd != 0) { - /* Update pointer */ - chan->rx_last_bd = (chan->rx_first_bd - 1) & (N_DMA_RX_BUF - 1); - /* Update EDA */ - cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), - RX_BD_ADDR(ch, chan->rx_last_bd)); - } - return rcvd; -} - -static void tx_dma_stop(pc300_t * card, int ch) -{ - void __iomem *scabase = card->hw.scabase; - u8 drr_ena_bit = 1 << (5 + 2 * ch); - u8 drr_rst_bit = 1 << (1 + 2 * ch); - - /* Disable DMA */ - cpc_writeb(scabase + DRR, drr_ena_bit); - cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit); -} - -static void rx_dma_stop(pc300_t * card, int ch) -{ - void __iomem *scabase = card->hw.scabase; - u8 drr_ena_bit = 1 << (4 + 2 * ch); - u8 drr_rst_bit = 1 << (2 * ch); - - /* Disable DMA */ - cpc_writeb(scabase + DRR, drr_ena_bit); - cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit); -} - -static void rx_dma_start(pc300_t * card, int ch) -{ - void __iomem *scabase = card->hw.scabase; - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - - /* Start DMA */ - cpc_writel(scabase + DRX_REG(CDAL, ch), - RX_BD_ADDR(ch, chan->rx_first_bd)); - if (cpc_readl(scabase + DRX_REG(CDAL,ch)) != - RX_BD_ADDR(ch, chan->rx_first_bd)) { - cpc_writel(scabase + DRX_REG(CDAL, ch), - RX_BD_ADDR(ch, chan->rx_first_bd)); - } - cpc_writel(scabase + DRX_REG(EDAL, ch), - RX_BD_ADDR(ch, chan->rx_last_bd)); - cpc_writew(scabase + DRX_REG(BFLL, ch), BD_DEF_LEN); - cpc_writeb(scabase + DSR_RX(ch), DSR_DE); - if (!(cpc_readb(scabase + DSR_RX(ch)) & DSR_DE)) { - cpc_writeb(scabase + DSR_RX(ch), DSR_DE); - } -} - -/*************************/ -/*** FALC Routines ***/ -/*************************/ -static void falc_issue_cmd(pc300_t *card, int ch, u8 cmd) -{ - void __iomem *falcbase = card->hw.falcbase; - unsigned long i = 0; - - while (cpc_readb(falcbase + F_REG(SIS, ch)) & SIS_CEC) { - if (i++ >= PC300_FALC_MAXLOOP) { - printk("%s: FALC command locked(cmd=0x%x).\n", - card->chan[ch].d.name, cmd); - break; - } - } - cpc_writeb(falcbase + F_REG(CMDR, ch), cmd); -} - -static void falc_intr_enable(pc300_t * card, int ch) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; - falc_t *pfalc = (falc_t *) & chan->falc; - void __iomem *falcbase = card->hw.falcbase; - - /* Interrupt pins are open-drain */ - cpc_writeb(falcbase + F_REG(IPC, ch), - cpc_readb(falcbase + F_REG(IPC, ch)) & ~IPC_IC0); - /* Conters updated each second */ - cpc_writeb(falcbase + F_REG(FMR1, ch), - cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_ECM); - /* Enable SEC and ES interrupts */ - cpc_writeb(falcbase + F_REG(IMR3, ch), - cpc_readb(falcbase + F_REG(IMR3, ch)) & ~(IMR3_SEC | IMR3_ES)); - if (conf->fr_mode == PC300_FR_UNFRAMED) { - cpc_writeb(falcbase + F_REG(IMR4, ch), - cpc_readb(falcbase + F_REG(IMR4, ch)) & ~(IMR4_LOS)); - } else { - cpc_writeb(falcbase + F_REG(IMR4, ch), - cpc_readb(falcbase + F_REG(IMR4, ch)) & - ~(IMR4_LFA | IMR4_AIS | IMR4_LOS | IMR4_SLIP)); - } - if (conf->media == IF_IFACE_T1) { - cpc_writeb(falcbase + F_REG(IMR3, ch), - cpc_readb(falcbase + F_REG(IMR3, ch)) & ~IMR3_LLBSC); - } else { - cpc_writeb(falcbase + F_REG(IPC, ch), - cpc_readb(falcbase + F_REG(IPC, ch)) | IPC_SCI); - if (conf->fr_mode == PC300_FR_UNFRAMED) { - cpc_writeb(falcbase + F_REG(IMR2, ch), - cpc_readb(falcbase + F_REG(IMR2, ch)) & ~(IMR2_LOS)); - } else { - cpc_writeb(falcbase + F_REG(IMR2, ch), - cpc_readb(falcbase + F_REG(IMR2, ch)) & - ~(IMR2_FAR | IMR2_LFA | IMR2_AIS | IMR2_LOS)); - if (pfalc->multiframe_mode) { - cpc_writeb(falcbase + F_REG(IMR2, ch), - cpc_readb(falcbase + F_REG(IMR2, ch)) & - ~(IMR2_T400MS | IMR2_MFAR)); - } else { - cpc_writeb(falcbase + F_REG(IMR2, ch), - cpc_readb(falcbase + F_REG(IMR2, ch)) | - IMR2_T400MS | IMR2_MFAR); - } - } - } -} - -static void falc_open_timeslot(pc300_t * card, int ch, int timeslot) -{ - void __iomem *falcbase = card->hw.falcbase; - u8 tshf = card->chan[ch].falc.offset; - - cpc_writeb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch), - cpc_readb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch)) & - ~(0x80 >> ((timeslot - tshf) & 0x07))); - cpc_writeb(falcbase + F_REG((TTR1 + timeslot / 8), ch), - cpc_readb(falcbase + F_REG((TTR1 + timeslot / 8), ch)) | - (0x80 >> (timeslot & 0x07))); - cpc_writeb(falcbase + F_REG((RTR1 + timeslot / 8), ch), - cpc_readb(falcbase + F_REG((RTR1 + timeslot / 8), ch)) | - (0x80 >> (timeslot & 0x07))); -} - -static void falc_close_timeslot(pc300_t * card, int ch, int timeslot) -{ - void __iomem *falcbase = card->hw.falcbase; - u8 tshf = card->chan[ch].falc.offset; - - cpc_writeb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch), - cpc_readb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch)) | - (0x80 >> ((timeslot - tshf) & 0x07))); - cpc_writeb(falcbase + F_REG((TTR1 + timeslot / 8), ch), - cpc_readb(falcbase + F_REG((TTR1 + timeslot / 8), ch)) & - ~(0x80 >> (timeslot & 0x07))); - cpc_writeb(falcbase + F_REG((RTR1 + timeslot / 8), ch), - cpc_readb(falcbase + F_REG((RTR1 + timeslot / 8), ch)) & - ~(0x80 >> (timeslot & 0x07))); -} - -static void falc_close_all_timeslots(pc300_t * card, int ch) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; - void __iomem *falcbase = card->hw.falcbase; - - cpc_writeb(falcbase + F_REG(ICB1, ch), 0xff); - cpc_writeb(falcbase + F_REG(TTR1, ch), 0); - cpc_writeb(falcbase + F_REG(RTR1, ch), 0); - cpc_writeb(falcbase + F_REG(ICB2, ch), 0xff); - cpc_writeb(falcbase + F_REG(TTR2, ch), 0); - cpc_writeb(falcbase + F_REG(RTR2, ch), 0); - cpc_writeb(falcbase + F_REG(ICB3, ch), 0xff); - cpc_writeb(falcbase + F_REG(TTR3, ch), 0); - cpc_writeb(falcbase + F_REG(RTR3, ch), 0); - if (conf->media == IF_IFACE_E1) { - cpc_writeb(falcbase + F_REG(ICB4, ch), 0xff); - cpc_writeb(falcbase + F_REG(TTR4, ch), 0); - cpc_writeb(falcbase + F_REG(RTR4, ch), 0); - } -} - -static void falc_open_all_timeslots(pc300_t * card, int ch) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; - void __iomem *falcbase = card->hw.falcbase; - - cpc_writeb(falcbase + F_REG(ICB1, ch), 0); - if (conf->fr_mode == PC300_FR_UNFRAMED) { - cpc_writeb(falcbase + F_REG(TTR1, ch), 0xff); - cpc_writeb(falcbase + F_REG(RTR1, ch), 0xff); - } else { - /* Timeslot 0 is never enabled */ - cpc_writeb(falcbase + F_REG(TTR1, ch), 0x7f); - cpc_writeb(falcbase + F_REG(RTR1, ch), 0x7f); - } - cpc_writeb(falcbase + F_REG(ICB2, ch), 0); - cpc_writeb(falcbase + F_REG(TTR2, ch), 0xff); - cpc_writeb(falcbase + F_REG(RTR2, ch), 0xff); - cpc_writeb(falcbase + F_REG(ICB3, ch), 0); - cpc_writeb(falcbase + F_REG(TTR3, ch), 0xff); - cpc_writeb(falcbase + F_REG(RTR3, ch), 0xff); - if (conf->media == IF_IFACE_E1) { - cpc_writeb(falcbase + F_REG(ICB4, ch), 0); - cpc_writeb(falcbase + F_REG(TTR4, ch), 0xff); - cpc_writeb(falcbase + F_REG(RTR4, ch), 0xff); - } else { - cpc_writeb(falcbase + F_REG(ICB4, ch), 0xff); - cpc_writeb(falcbase + F_REG(TTR4, ch), 0x80); - cpc_writeb(falcbase + F_REG(RTR4, ch), 0x80); - } -} - -static void falc_init_timeslot(pc300_t * card, int ch) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; - falc_t *pfalc = (falc_t *) & chan->falc; - int tslot; - - for (tslot = 0; tslot < pfalc->num_channels; tslot++) { - if (conf->tslot_bitmap & (1 << tslot)) { - // Channel enabled - falc_open_timeslot(card, ch, tslot + 1); - } else { - // Channel disabled - falc_close_timeslot(card, ch, tslot + 1); - } - } -} - -static void falc_enable_comm(pc300_t * card, int ch) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - falc_t *pfalc = (falc_t *) & chan->falc; - - if (pfalc->full_bandwidth) { - falc_open_all_timeslots(card, ch); - } else { - falc_init_timeslot(card, ch); - } - // CTS/DCD ON - cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, - cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) & - ~((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch))); -} - -static void falc_disable_comm(pc300_t * card, int ch) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - falc_t *pfalc = (falc_t *) & chan->falc; - - if (pfalc->loop_active != 2) { - falc_close_all_timeslots(card, ch); - } - // CTS/DCD OFF - cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, - cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) | - ((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch))); -} - -static void falc_init_t1(pc300_t * card, int ch) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; - falc_t *pfalc = (falc_t *) & chan->falc; - void __iomem *falcbase = card->hw.falcbase; - u8 dja = (ch ? (LIM2_DJA2 | LIM2_DJA1) : 0); - - /* Switch to T1 mode (PCM 24) */ - cpc_writeb(falcbase + F_REG(FMR1, ch), FMR1_PMOD); - - /* Wait 20 us for setup */ - udelay(20); - - /* Transmit Buffer Size (1 frame) */ - cpc_writeb(falcbase + F_REG(SIC1, ch), SIC1_XBS0); - - /* Clock mode */ - if (conf->phys_settings.clock_type == CLOCK_INT) { /* Master mode */ - cpc_writeb(falcbase + F_REG(LIM0, ch), - cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_MAS); - } else { /* Slave mode */ - cpc_writeb(falcbase + F_REG(LIM0, ch), - cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_MAS); - cpc_writeb(falcbase + F_REG(LOOP, ch), - cpc_readb(falcbase + F_REG(LOOP, ch)) & ~LOOP_RTM); - } - - cpc_writeb(falcbase + F_REG(IPC, ch), IPC_SCI); - cpc_writeb(falcbase + F_REG(FMR0, ch), - cpc_readb(falcbase + F_REG(FMR0, ch)) & - ~(FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1)); - - switch (conf->lcode) { - case PC300_LC_AMI: - cpc_writeb(falcbase + F_REG(FMR0, ch), - cpc_readb(falcbase + F_REG(FMR0, ch)) | - FMR0_XC1 | FMR0_RC1); - /* Clear Channel register to ON for all channels */ - cpc_writeb(falcbase + F_REG(CCB1, ch), 0xff); - cpc_writeb(falcbase + F_REG(CCB2, ch), 0xff); - cpc_writeb(falcbase + F_REG(CCB3, ch), 0xff); - break; - - case PC300_LC_B8ZS: - cpc_writeb(falcbase + F_REG(FMR0, ch), - cpc_readb(falcbase + F_REG(FMR0, ch)) | - FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1); - break; - - case PC300_LC_NRZ: - cpc_writeb(falcbase + F_REG(FMR0, ch), - cpc_readb(falcbase + F_REG(FMR0, ch)) | 0x00); - break; - } - - cpc_writeb(falcbase + F_REG(LIM0, ch), - cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_ELOS); - cpc_writeb(falcbase + F_REG(LIM0, ch), - cpc_readb(falcbase + F_REG(LIM0, ch)) & ~(LIM0_SCL1 | LIM0_SCL0)); - /* Set interface mode to 2 MBPS */ - cpc_writeb(falcbase + F_REG(FMR1, ch), - cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_IMOD); - - switch (conf->fr_mode) { - case PC300_FR_ESF: - pfalc->multiframe_mode = 0; - cpc_writeb(falcbase + F_REG(FMR4, ch), - cpc_readb(falcbase + F_REG(FMR4, ch)) | FMR4_FM1); - cpc_writeb(falcbase + F_REG(FMR1, ch), - cpc_readb(falcbase + F_REG(FMR1, ch)) | - FMR1_CRC | FMR1_EDL); - cpc_writeb(falcbase + F_REG(XDL1, ch), 0); - cpc_writeb(falcbase + F_REG(XDL2, ch), 0); - cpc_writeb(falcbase + F_REG(XDL3, ch), 0); - cpc_writeb(falcbase + F_REG(FMR0, ch), - cpc_readb(falcbase + F_REG(FMR0, ch)) & ~FMR0_SRAF); - cpc_writeb(falcbase + F_REG(FMR2, ch), - cpc_readb(falcbase + F_REG(FMR2,ch)) | FMR2_MCSP | FMR2_SSP); - break; - - case PC300_FR_D4: - pfalc->multiframe_mode = 1; - cpc_writeb(falcbase + F_REG(FMR4, ch), - cpc_readb(falcbase + F_REG(FMR4, ch)) & - ~(FMR4_FM1 | FMR4_FM0)); - cpc_writeb(falcbase + F_REG(FMR0, ch), - cpc_readb(falcbase + F_REG(FMR0, ch)) | FMR0_SRAF); - cpc_writeb(falcbase + F_REG(FMR2, ch), - cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_SSP); - break; - } - - /* Enable Automatic Resynchronization */ - cpc_writeb(falcbase + F_REG(FMR4, ch), - cpc_readb(falcbase + F_REG(FMR4, ch)) | FMR4_AUTO); - - /* Transmit Automatic Remote Alarm */ - cpc_writeb(falcbase + F_REG(FMR2, ch), - cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_AXRA); - - /* Channel translation mode 1 : one to one */ - cpc_writeb(falcbase + F_REG(FMR1, ch), - cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_CTM); - - /* No signaling */ - cpc_writeb(falcbase + F_REG(FMR1, ch), - cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_SIGM); - cpc_writeb(falcbase + F_REG(FMR5, ch), - cpc_readb(falcbase + F_REG(FMR5, ch)) & - ~(FMR5_EIBR | FMR5_SRS)); - cpc_writeb(falcbase + F_REG(CCR1, ch), 0); - - cpc_writeb(falcbase + F_REG(LIM1, ch), - cpc_readb(falcbase + F_REG(LIM1, ch)) | LIM1_RIL0 | LIM1_RIL1); - - switch (conf->lbo) { - /* Provides proper Line Build Out */ - case PC300_LBO_0_DB: - cpc_writeb(falcbase + F_REG(LIM2, ch), (LIM2_LOS1 | dja)); - cpc_writeb(falcbase + F_REG(XPM0, ch), 0x5a); - cpc_writeb(falcbase + F_REG(XPM1, ch), 0x8f); - cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20); - break; - case PC300_LBO_7_5_DB: - cpc_writeb(falcbase + F_REG(LIM2, ch), (0x40 | LIM2_LOS1 | dja)); - cpc_writeb(falcbase + F_REG(XPM0, ch), 0x11); - cpc_writeb(falcbase + F_REG(XPM1, ch), 0x02); - cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20); - break; - case PC300_LBO_15_DB: - cpc_writeb(falcbase + F_REG(LIM2, ch), (0x80 | LIM2_LOS1 | dja)); - cpc_writeb(falcbase + F_REG(XPM0, ch), 0x8e); - cpc_writeb(falcbase + F_REG(XPM1, ch), 0x01); - cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20); - break; - case PC300_LBO_22_5_DB: - cpc_writeb(falcbase + F_REG(LIM2, ch), (0xc0 | LIM2_LOS1 | dja)); - cpc_writeb(falcbase + F_REG(XPM0, ch), 0x09); - cpc_writeb(falcbase + F_REG(XPM1, ch), 0x01); - cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20); - break; - } - - /* Transmit Clock-Slot Offset */ - cpc_writeb(falcbase + F_REG(XC0, ch), - cpc_readb(falcbase + F_REG(XC0, ch)) | 0x01); - /* Transmit Time-slot Offset */ - cpc_writeb(falcbase + F_REG(XC1, ch), 0x3e); - /* Receive Clock-Slot offset */ - cpc_writeb(falcbase + F_REG(RC0, ch), 0x05); - /* Receive Time-slot offset */ - cpc_writeb(falcbase + F_REG(RC1, ch), 0x00); - - /* LOS Detection after 176 consecutive 0s */ - cpc_writeb(falcbase + F_REG(PCDR, ch), 0x0a); - /* LOS Recovery after 22 ones in the time window of PCD */ - cpc_writeb(falcbase + F_REG(PCRR, ch), 0x15); - - cpc_writeb(falcbase + F_REG(IDLE, ch), 0x7f); - - if (conf->fr_mode == PC300_FR_ESF_JAPAN) { - cpc_writeb(falcbase + F_REG(RC1, ch), - cpc_readb(falcbase + F_REG(RC1, ch)) | 0x80); - } - - falc_close_all_timeslots(card, ch); -} - -static void falc_init_e1(pc300_t * card, int ch) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; - falc_t *pfalc = (falc_t *) & chan->falc; - void __iomem *falcbase = card->hw.falcbase; - u8 dja = (ch ? (LIM2_DJA2 | LIM2_DJA1) : 0); - - /* Switch to E1 mode (PCM 30) */ - cpc_writeb(falcbase + F_REG(FMR1, ch), - cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_PMOD); - - /* Clock mode */ - if (conf->phys_settings.clock_type == CLOCK_INT) { /* Master mode */ - cpc_writeb(falcbase + F_REG(LIM0, ch), - cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_MAS); - } else { /* Slave mode */ - cpc_writeb(falcbase + F_REG(LIM0, ch), - cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_MAS); - } - cpc_writeb(falcbase + F_REG(LOOP, ch), - cpc_readb(falcbase + F_REG(LOOP, ch)) & ~LOOP_SFM); - - cpc_writeb(falcbase + F_REG(IPC, ch), IPC_SCI); - cpc_writeb(falcbase + F_REG(FMR0, ch), - cpc_readb(falcbase + F_REG(FMR0, ch)) & - ~(FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1)); - - switch (conf->lcode) { - case PC300_LC_AMI: - cpc_writeb(falcbase + F_REG(FMR0, ch), - cpc_readb(falcbase + F_REG(FMR0, ch)) | - FMR0_XC1 | FMR0_RC1); - break; - - case PC300_LC_HDB3: - cpc_writeb(falcbase + F_REG(FMR0, ch), - cpc_readb(falcbase + F_REG(FMR0, ch)) | - FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1); - break; - - case PC300_LC_NRZ: - break; - } - - cpc_writeb(falcbase + F_REG(LIM0, ch), - cpc_readb(falcbase + F_REG(LIM0, ch)) & ~(LIM0_SCL1 | LIM0_SCL0)); - /* Set interface mode to 2 MBPS */ - cpc_writeb(falcbase + F_REG(FMR1, ch), - cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_IMOD); - - cpc_writeb(falcbase + F_REG(XPM0, ch), 0x18); - cpc_writeb(falcbase + F_REG(XPM1, ch), 0x03); - cpc_writeb(falcbase + F_REG(XPM2, ch), 0x00); - - switch (conf->fr_mode) { - case PC300_FR_MF_CRC4: - pfalc->multiframe_mode = 1; - cpc_writeb(falcbase + F_REG(FMR1, ch), - cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_XFS); - cpc_writeb(falcbase + F_REG(FMR2, ch), - cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_RFS1); - cpc_writeb(falcbase + F_REG(FMR2, ch), - cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_RFS0); - cpc_writeb(falcbase + F_REG(FMR3, ch), - cpc_readb(falcbase + F_REG(FMR3, ch)) & ~FMR3_EXTIW); - - /* MultiFrame Resynchronization */ - cpc_writeb(falcbase + F_REG(FMR1, ch), - cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_MFCS); - - /* Automatic Loss of Multiframe > 914 CRC errors */ - cpc_writeb(falcbase + F_REG(FMR2, ch), - cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_ALMF); - - /* S1 and SI1/SI2 spare Bits set to 1 */ - cpc_writeb(falcbase + F_REG(XSP, ch), - cpc_readb(falcbase + F_REG(XSP, ch)) & ~XSP_AXS); - cpc_writeb(falcbase + F_REG(XSP, ch), - cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_EBP); - cpc_writeb(falcbase + F_REG(XSP, ch), - cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_XS13 | XSP_XS15); - - /* Automatic Force Resynchronization */ - cpc_writeb(falcbase + F_REG(FMR1, ch), - cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_AFR); - - /* Transmit Automatic Remote Alarm */ - cpc_writeb(falcbase + F_REG(FMR2, ch), - cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_AXRA); - - /* Transmit Spare Bits for National Use (Y, Sn, Sa) */ - cpc_writeb(falcbase + F_REG(XSW, ch), - cpc_readb(falcbase + F_REG(XSW, ch)) | - XSW_XY0 | XSW_XY1 | XSW_XY2 | XSW_XY3 | XSW_XY4); - break; - - case PC300_FR_MF_NON_CRC4: - case PC300_FR_D4: - pfalc->multiframe_mode = 0; - cpc_writeb(falcbase + F_REG(FMR1, ch), - cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_XFS); - cpc_writeb(falcbase + F_REG(FMR2, ch), - cpc_readb(falcbase + F_REG(FMR2, ch)) & - ~(FMR2_RFS1 | FMR2_RFS0)); - cpc_writeb(falcbase + F_REG(XSW, ch), - cpc_readb(falcbase + F_REG(XSW, ch)) | XSW_XSIS); - cpc_writeb(falcbase + F_REG(XSP, ch), - cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_XSIF); - - /* Automatic Force Resynchronization */ - cpc_writeb(falcbase + F_REG(FMR1, ch), - cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_AFR); - - /* Transmit Automatic Remote Alarm */ - cpc_writeb(falcbase + F_REG(FMR2, ch), - cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_AXRA); - - /* Transmit Spare Bits for National Use (Y, Sn, Sa) */ - cpc_writeb(falcbase + F_REG(XSW, ch), - cpc_readb(falcbase + F_REG(XSW, ch)) | - XSW_XY0 | XSW_XY1 | XSW_XY2 | XSW_XY3 | XSW_XY4); - break; - - case PC300_FR_UNFRAMED: - pfalc->multiframe_mode = 0; - cpc_writeb(falcbase + F_REG(FMR1, ch), - cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_XFS); - cpc_writeb(falcbase + F_REG(FMR2, ch), - cpc_readb(falcbase + F_REG(FMR2, ch)) & - ~(FMR2_RFS1 | FMR2_RFS0)); - cpc_writeb(falcbase + F_REG(XSP, ch), - cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_TT0); - cpc_writeb(falcbase + F_REG(XSW, ch), - cpc_readb(falcbase + F_REG(XSW, ch)) & - ~(XSW_XTM|XSW_XY0|XSW_XY1|XSW_XY2|XSW_XY3|XSW_XY4)); - cpc_writeb(falcbase + F_REG(TSWM, ch), 0xff); - cpc_writeb(falcbase + F_REG(FMR2, ch), - cpc_readb(falcbase + F_REG(FMR2, ch)) | - (FMR2_RTM | FMR2_DAIS)); - cpc_writeb(falcbase + F_REG(FMR2, ch), - cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_AXRA); - cpc_writeb(falcbase + F_REG(FMR1, ch), - cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_AFR); - pfalc->sync = 1; - cpc_writeb(falcbase + card->hw.cpld_reg2, - cpc_readb(falcbase + card->hw.cpld_reg2) | - (CPLD_REG2_FALC_LED2 << (2 * ch))); - break; - } - - /* No signaling */ - cpc_writeb(falcbase + F_REG(XSP, ch), - cpc_readb(falcbase + F_REG(XSP, ch)) & ~XSP_CASEN); - cpc_writeb(falcbase + F_REG(CCR1, ch), 0); - - cpc_writeb(falcbase + F_REG(LIM1, ch), - cpc_readb(falcbase + F_REG(LIM1, ch)) | LIM1_RIL0 | LIM1_RIL1); - cpc_writeb(falcbase + F_REG(LIM2, ch), (LIM2_LOS1 | dja)); - - /* Transmit Clock-Slot Offset */ - cpc_writeb(falcbase + F_REG(XC0, ch), - cpc_readb(falcbase + F_REG(XC0, ch)) | 0x01); - /* Transmit Time-slot Offset */ - cpc_writeb(falcbase + F_REG(XC1, ch), 0x3e); - /* Receive Clock-Slot offset */ - cpc_writeb(falcbase + F_REG(RC0, ch), 0x05); - /* Receive Time-slot offset */ - cpc_writeb(falcbase + F_REG(RC1, ch), 0x00); - - /* LOS Detection after 176 consecutive 0s */ - cpc_writeb(falcbase + F_REG(PCDR, ch), 0x0a); - /* LOS Recovery after 22 ones in the time window of PCD */ - cpc_writeb(falcbase + F_REG(PCRR, ch), 0x15); - - cpc_writeb(falcbase + F_REG(IDLE, ch), 0x7f); - - falc_close_all_timeslots(card, ch); -} - -static void falc_init_hdlc(pc300_t * card, int ch) -{ - void __iomem *falcbase = card->hw.falcbase; - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; - - /* Enable transparent data transfer */ - if (conf->fr_mode == PC300_FR_UNFRAMED) { - cpc_writeb(falcbase + F_REG(MODE, ch), 0); - } else { - cpc_writeb(falcbase + F_REG(MODE, ch), - cpc_readb(falcbase + F_REG(MODE, ch)) | - (MODE_HRAC | MODE_MDS2)); - cpc_writeb(falcbase + F_REG(RAH2, ch), 0xff); - cpc_writeb(falcbase + F_REG(RAH1, ch), 0xff); - cpc_writeb(falcbase + F_REG(RAL2, ch), 0xff); - cpc_writeb(falcbase + F_REG(RAL1, ch), 0xff); - } - - /* Tx/Rx reset */ - falc_issue_cmd(card, ch, CMDR_RRES | CMDR_XRES | CMDR_SRES); - - /* Enable interrupt sources */ - falc_intr_enable(card, ch); -} - -static void te_config(pc300_t * card, int ch) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; - falc_t *pfalc = (falc_t *) & chan->falc; - void __iomem *falcbase = card->hw.falcbase; - u8 dummy; - unsigned long flags; - - memset(pfalc, 0, sizeof(falc_t)); - switch (conf->media) { - case IF_IFACE_T1: - pfalc->num_channels = NUM_OF_T1_CHANNELS; - pfalc->offset = 1; - break; - case IF_IFACE_E1: - pfalc->num_channels = NUM_OF_E1_CHANNELS; - pfalc->offset = 0; - break; - } - if (conf->tslot_bitmap == 0xffffffffUL) - pfalc->full_bandwidth = 1; - else - pfalc->full_bandwidth = 0; - - CPC_LOCK(card, flags); - /* Reset the FALC chip */ - cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, - cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) | - (CPLD_REG1_FALC_RESET << (2 * ch))); - udelay(10000); - cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, - cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) & - ~(CPLD_REG1_FALC_RESET << (2 * ch))); - - if (conf->media == IF_IFACE_T1) { - falc_init_t1(card, ch); - } else { - falc_init_e1(card, ch); - } - falc_init_hdlc(card, ch); - if (conf->rx_sens == PC300_RX_SENS_SH) { - cpc_writeb(falcbase + F_REG(LIM0, ch), - cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_EQON); - } else { - cpc_writeb(falcbase + F_REG(LIM0, ch), - cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_EQON); - } - cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, - cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) | - ((CPLD_REG2_FALC_TX_CLK | CPLD_REG2_FALC_RX_CLK) << (2 * ch))); - - /* Clear all interrupt registers */ - dummy = cpc_readb(falcbase + F_REG(FISR0, ch)) + - cpc_readb(falcbase + F_REG(FISR1, ch)) + - cpc_readb(falcbase + F_REG(FISR2, ch)) + - cpc_readb(falcbase + F_REG(FISR3, ch)); - CPC_UNLOCK(card, flags); -} - -static void falc_check_status(pc300_t * card, int ch, unsigned char frs0) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; - falc_t *pfalc = (falc_t *) & chan->falc; - void __iomem *falcbase = card->hw.falcbase; - - /* Verify LOS */ - if (frs0 & FRS0_LOS) { - if (!pfalc->red_alarm) { - pfalc->red_alarm = 1; - pfalc->los++; - if (!pfalc->blue_alarm) { - // EVENT_FALC_ABNORMAL - if (conf->media == IF_IFACE_T1) { - /* Disable this interrupt as it may otherwise interfere - * with other working boards. */ - cpc_writeb(falcbase + F_REG(IMR0, ch), - cpc_readb(falcbase + F_REG(IMR0, ch)) - | IMR0_PDEN); - } - falc_disable_comm(card, ch); - // EVENT_FALC_ABNORMAL - } - } - } else { - if (pfalc->red_alarm) { - pfalc->red_alarm = 0; - pfalc->losr++; - } - } - - if (conf->fr_mode != PC300_FR_UNFRAMED) { - /* Verify AIS alarm */ - if (frs0 & FRS0_AIS) { - if (!pfalc->blue_alarm) { - pfalc->blue_alarm = 1; - pfalc->ais++; - // EVENT_AIS - if (conf->media == IF_IFACE_T1) { - /* Disable this interrupt as it may otherwise interfere with other working boards. */ - cpc_writeb(falcbase + F_REG(IMR0, ch), - cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN); - } - falc_disable_comm(card, ch); - // EVENT_AIS - } - } else { - pfalc->blue_alarm = 0; - } - - /* Verify LFA */ - if (frs0 & FRS0_LFA) { - if (!pfalc->loss_fa) { - pfalc->loss_fa = 1; - pfalc->lfa++; - if (!pfalc->blue_alarm && !pfalc->red_alarm) { - // EVENT_FALC_ABNORMAL - if (conf->media == IF_IFACE_T1) { - /* Disable this interrupt as it may otherwise - * interfere with other working boards. */ - cpc_writeb(falcbase + F_REG(IMR0, ch), - cpc_readb(falcbase + F_REG(IMR0, ch)) - | IMR0_PDEN); - } - falc_disable_comm(card, ch); - // EVENT_FALC_ABNORMAL - } - } - } else { - if (pfalc->loss_fa) { - pfalc->loss_fa = 0; - pfalc->farec++; - } - } - - /* Verify LMFA */ - if (pfalc->multiframe_mode && (frs0 & FRS0_LMFA)) { - /* D4 or CRC4 frame mode */ - if (!pfalc->loss_mfa) { - pfalc->loss_mfa = 1; - pfalc->lmfa++; - if (!pfalc->blue_alarm && !pfalc->red_alarm && - !pfalc->loss_fa) { - // EVENT_FALC_ABNORMAL - if (conf->media == IF_IFACE_T1) { - /* Disable this interrupt as it may otherwise - * interfere with other working boards. */ - cpc_writeb(falcbase + F_REG(IMR0, ch), - cpc_readb(falcbase + F_REG(IMR0, ch)) - | IMR0_PDEN); - } - falc_disable_comm(card, ch); - // EVENT_FALC_ABNORMAL - } - } - } else { - pfalc->loss_mfa = 0; - } - - /* Verify Remote Alarm */ - if (frs0 & FRS0_RRA) { - if (!pfalc->yellow_alarm) { - pfalc->yellow_alarm = 1; - pfalc->rai++; - if (pfalc->sync) { - // EVENT_RAI - falc_disable_comm(card, ch); - // EVENT_RAI - } - } - } else { - pfalc->yellow_alarm = 0; - } - } /* if !PC300_UNFRAMED */ - - if (pfalc->red_alarm || pfalc->loss_fa || - pfalc->loss_mfa || pfalc->blue_alarm) { - if (pfalc->sync) { - pfalc->sync = 0; - chan->d.line_off++; - cpc_writeb(falcbase + card->hw.cpld_reg2, - cpc_readb(falcbase + card->hw.cpld_reg2) & - ~(CPLD_REG2_FALC_LED2 << (2 * ch))); - } - } else { - if (!pfalc->sync) { - pfalc->sync = 1; - chan->d.line_on++; - cpc_writeb(falcbase + card->hw.cpld_reg2, - cpc_readb(falcbase + card->hw.cpld_reg2) | - (CPLD_REG2_FALC_LED2 << (2 * ch))); - } - } - - if (pfalc->sync && !pfalc->yellow_alarm) { - if (!pfalc->active) { - // EVENT_FALC_NORMAL - if (pfalc->loop_active) { - return; - } - if (conf->media == IF_IFACE_T1) { - cpc_writeb(falcbase + F_REG(IMR0, ch), - cpc_readb(falcbase + F_REG(IMR0, ch)) & ~IMR0_PDEN); - } - falc_enable_comm(card, ch); - // EVENT_FALC_NORMAL - pfalc->active = 1; - } - } else { - if (pfalc->active) { - pfalc->active = 0; - } - } -} - -static void falc_update_stats(pc300_t * card, int ch) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; - falc_t *pfalc = (falc_t *) & chan->falc; - void __iomem *falcbase = card->hw.falcbase; - u16 counter; - - counter = cpc_readb(falcbase + F_REG(FECL, ch)); - counter |= cpc_readb(falcbase + F_REG(FECH, ch)) << 8; - pfalc->fec += counter; - - counter = cpc_readb(falcbase + F_REG(CVCL, ch)); - counter |= cpc_readb(falcbase + F_REG(CVCH, ch)) << 8; - pfalc->cvc += counter; - - counter = cpc_readb(falcbase + F_REG(CECL, ch)); - counter |= cpc_readb(falcbase + F_REG(CECH, ch)) << 8; - pfalc->cec += counter; - - counter = cpc_readb(falcbase + F_REG(EBCL, ch)); - counter |= cpc_readb(falcbase + F_REG(EBCH, ch)) << 8; - pfalc->ebc += counter; - - if (cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_EPRM) { - mdelay(10); - counter = cpc_readb(falcbase + F_REG(BECL, ch)); - counter |= cpc_readb(falcbase + F_REG(BECH, ch)) << 8; - pfalc->bec += counter; - - if (((conf->media == IF_IFACE_T1) && - (cpc_readb(falcbase + F_REG(FRS1, ch)) & FRS1_LLBAD) && - (!(cpc_readb(falcbase + F_REG(FRS1, ch)) & FRS1_PDEN))) || - ((conf->media == IF_IFACE_E1) && - (cpc_readb(falcbase + F_REG(RSP, ch)) & RSP_LLBAD))) { - pfalc->prbs = 2; - } else { - pfalc->prbs = 1; - } - } -} - -/*---------------------------------------------------------------------------- - * falc_remote_loop - *---------------------------------------------------------------------------- - * Description: In the remote loopback mode the clock and data recovered - * from the line inputs RL1/2 or RDIP/RDIN are routed back - * to the line outputs XL1/2 or XDOP/XDON via the analog - * transmitter. As in normal mode they are processed by - * the synchronizer and then sent to the system interface. - *---------------------------------------------------------------------------- - */ -static void falc_remote_loop(pc300_t * card, int ch, int loop_on) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; - falc_t *pfalc = (falc_t *) & chan->falc; - void __iomem *falcbase = card->hw.falcbase; - - if (loop_on) { - // EVENT_FALC_ABNORMAL - if (conf->media == IF_IFACE_T1) { - /* Disable this interrupt as it may otherwise interfere with - * other working boards. */ - cpc_writeb(falcbase + F_REG(IMR0, ch), - cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN); - } - falc_disable_comm(card, ch); - // EVENT_FALC_ABNORMAL - cpc_writeb(falcbase + F_REG(LIM1, ch), - cpc_readb(falcbase + F_REG(LIM1, ch)) | LIM1_RL); - pfalc->loop_active = 1; - } else { - cpc_writeb(falcbase + F_REG(LIM1, ch), - cpc_readb(falcbase + F_REG(LIM1, ch)) & ~LIM1_RL); - pfalc->sync = 0; - cpc_writeb(falcbase + card->hw.cpld_reg2, - cpc_readb(falcbase + card->hw.cpld_reg2) & - ~(CPLD_REG2_FALC_LED2 << (2 * ch))); - pfalc->active = 0; - falc_issue_cmd(card, ch, CMDR_XRES); - pfalc->loop_active = 0; - } -} - -/*---------------------------------------------------------------------------- - * falc_local_loop - *---------------------------------------------------------------------------- - * Description: The local loopback mode disconnects the receive lines - * RL1/RL2 resp. RDIP/RDIN from the receiver. Instead of the - * signals coming from the line the data provided by system - * interface are routed through the analog receiver back to - * the system interface. The unipolar bit stream will be - * undisturbed transmitted on the line. Receiver and transmitter - * coding must be identical. - *---------------------------------------------------------------------------- - */ -static void falc_local_loop(pc300_t * card, int ch, int loop_on) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - falc_t *pfalc = (falc_t *) & chan->falc; - void __iomem *falcbase = card->hw.falcbase; - - if (loop_on) { - cpc_writeb(falcbase + F_REG(LIM0, ch), - cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_LL); - pfalc->loop_active = 1; - } else { - cpc_writeb(falcbase + F_REG(LIM0, ch), - cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_LL); - pfalc->loop_active = 0; - } -} - -/*---------------------------------------------------------------------------- - * falc_payload_loop - *---------------------------------------------------------------------------- - * Description: This routine allows to enable/disable payload loopback. - * When the payload loop is activated, the received 192 bits - * of payload data will be looped back to the transmit - * direction. The framing bits, CRC6 and DL bits are not - * looped. They are originated by the FALC-LH transmitter. - *---------------------------------------------------------------------------- - */ -static void falc_payload_loop(pc300_t * card, int ch, int loop_on) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; - falc_t *pfalc = (falc_t *) & chan->falc; - void __iomem *falcbase = card->hw.falcbase; - - if (loop_on) { - // EVENT_FALC_ABNORMAL - if (conf->media == IF_IFACE_T1) { - /* Disable this interrupt as it may otherwise interfere with - * other working boards. */ - cpc_writeb(falcbase + F_REG(IMR0, ch), - cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN); - } - falc_disable_comm(card, ch); - // EVENT_FALC_ABNORMAL - cpc_writeb(falcbase + F_REG(FMR2, ch), - cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_PLB); - if (conf->media == IF_IFACE_T1) { - cpc_writeb(falcbase + F_REG(FMR4, ch), - cpc_readb(falcbase + F_REG(FMR4, ch)) | FMR4_TM); - } else { - cpc_writeb(falcbase + F_REG(FMR5, ch), - cpc_readb(falcbase + F_REG(FMR5, ch)) | XSP_TT0); - } - falc_open_all_timeslots(card, ch); - pfalc->loop_active = 2; - } else { - cpc_writeb(falcbase + F_REG(FMR2, ch), - cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_PLB); - if (conf->media == IF_IFACE_T1) { - cpc_writeb(falcbase + F_REG(FMR4, ch), - cpc_readb(falcbase + F_REG(FMR4, ch)) & ~FMR4_TM); - } else { - cpc_writeb(falcbase + F_REG(FMR5, ch), - cpc_readb(falcbase + F_REG(FMR5, ch)) & ~XSP_TT0); - } - pfalc->sync = 0; - cpc_writeb(falcbase + card->hw.cpld_reg2, - cpc_readb(falcbase + card->hw.cpld_reg2) & - ~(CPLD_REG2_FALC_LED2 << (2 * ch))); - pfalc->active = 0; - falc_issue_cmd(card, ch, CMDR_XRES); - pfalc->loop_active = 0; - } -} - -/*---------------------------------------------------------------------------- - * turn_off_xlu - *---------------------------------------------------------------------------- - * Description: Turns XLU bit off in the proper register - *---------------------------------------------------------------------------- - */ -static void turn_off_xlu(pc300_t * card, int ch) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; - void __iomem *falcbase = card->hw.falcbase; - - if (conf->media == IF_IFACE_T1) { - cpc_writeb(falcbase + F_REG(FMR5, ch), - cpc_readb(falcbase + F_REG(FMR5, ch)) & ~FMR5_XLU); - } else { - cpc_writeb(falcbase + F_REG(FMR3, ch), - cpc_readb(falcbase + F_REG(FMR3, ch)) & ~FMR3_XLU); - } -} - -/*---------------------------------------------------------------------------- - * turn_off_xld - *---------------------------------------------------------------------------- - * Description: Turns XLD bit off in the proper register - *---------------------------------------------------------------------------- - */ -static void turn_off_xld(pc300_t * card, int ch) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; - void __iomem *falcbase = card->hw.falcbase; - - if (conf->media == IF_IFACE_T1) { - cpc_writeb(falcbase + F_REG(FMR5, ch), - cpc_readb(falcbase + F_REG(FMR5, ch)) & ~FMR5_XLD); - } else { - cpc_writeb(falcbase + F_REG(FMR3, ch), - cpc_readb(falcbase + F_REG(FMR3, ch)) & ~FMR3_XLD); - } -} - -/*---------------------------------------------------------------------------- - * falc_generate_loop_up_code - *---------------------------------------------------------------------------- - * Description: This routine writes the proper FALC chip register in order - * to generate a LOOP activation code over a T1/E1 line. - *---------------------------------------------------------------------------- - */ -static void falc_generate_loop_up_code(pc300_t * card, int ch) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; - falc_t *pfalc = (falc_t *) & chan->falc; - void __iomem *falcbase = card->hw.falcbase; - - if (conf->media == IF_IFACE_T1) { - cpc_writeb(falcbase + F_REG(FMR5, ch), - cpc_readb(falcbase + F_REG(FMR5, ch)) | FMR5_XLU); - } else { - cpc_writeb(falcbase + F_REG(FMR3, ch), - cpc_readb(falcbase + F_REG(FMR3, ch)) | FMR3_XLU); - } - // EVENT_FALC_ABNORMAL - if (conf->media == IF_IFACE_T1) { - /* Disable this interrupt as it may otherwise interfere with - * other working boards. */ - cpc_writeb(falcbase + F_REG(IMR0, ch), - cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN); - } - falc_disable_comm(card, ch); - // EVENT_FALC_ABNORMAL - pfalc->loop_gen = 1; -} - -/*---------------------------------------------------------------------------- - * falc_generate_loop_down_code - *---------------------------------------------------------------------------- - * Description: This routine writes the proper FALC chip register in order - * to generate a LOOP deactivation code over a T1/E1 line. - *---------------------------------------------------------------------------- - */ -static void falc_generate_loop_down_code(pc300_t * card, int ch) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; - falc_t *pfalc = (falc_t *) & chan->falc; - void __iomem *falcbase = card->hw.falcbase; - - if (conf->media == IF_IFACE_T1) { - cpc_writeb(falcbase + F_REG(FMR5, ch), - cpc_readb(falcbase + F_REG(FMR5, ch)) | FMR5_XLD); - } else { - cpc_writeb(falcbase + F_REG(FMR3, ch), - cpc_readb(falcbase + F_REG(FMR3, ch)) | FMR3_XLD); - } - pfalc->sync = 0; - cpc_writeb(falcbase + card->hw.cpld_reg2, - cpc_readb(falcbase + card->hw.cpld_reg2) & - ~(CPLD_REG2_FALC_LED2 << (2 * ch))); - pfalc->active = 0; -//? falc_issue_cmd(card, ch, CMDR_XRES); - pfalc->loop_gen = 0; -} - -/*---------------------------------------------------------------------------- - * falc_pattern_test - *---------------------------------------------------------------------------- - * Description: This routine generates a pattern code and checks - * it on the reception side. - *---------------------------------------------------------------------------- - */ -static void falc_pattern_test(pc300_t * card, int ch, unsigned int activate) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; - falc_t *pfalc = (falc_t *) & chan->falc; - void __iomem *falcbase = card->hw.falcbase; - - if (activate) { - pfalc->prbs = 1; - pfalc->bec = 0; - if (conf->media == IF_IFACE_T1) { - /* Disable local loop activation/deactivation detect */ - cpc_writeb(falcbase + F_REG(IMR3, ch), - cpc_readb(falcbase + F_REG(IMR3, ch)) | IMR3_LLBSC); - } else { - /* Disable local loop activation/deactivation detect */ - cpc_writeb(falcbase + F_REG(IMR1, ch), - cpc_readb(falcbase + F_REG(IMR1, ch)) | IMR1_LLBSC); - } - /* Activates generation and monitoring of PRBS - * (Pseudo Random Bit Sequence) */ - cpc_writeb(falcbase + F_REG(LCR1, ch), - cpc_readb(falcbase + F_REG(LCR1, ch)) | LCR1_EPRM | LCR1_XPRBS); - } else { - pfalc->prbs = 0; - /* Deactivates generation and monitoring of PRBS - * (Pseudo Random Bit Sequence) */ - cpc_writeb(falcbase + F_REG(LCR1, ch), - cpc_readb(falcbase+F_REG(LCR1,ch)) & ~(LCR1_EPRM | LCR1_XPRBS)); - if (conf->media == IF_IFACE_T1) { - /* Enable local loop activation/deactivation detect */ - cpc_writeb(falcbase + F_REG(IMR3, ch), - cpc_readb(falcbase + F_REG(IMR3, ch)) & ~IMR3_LLBSC); - } else { - /* Enable local loop activation/deactivation detect */ - cpc_writeb(falcbase + F_REG(IMR1, ch), - cpc_readb(falcbase + F_REG(IMR1, ch)) & ~IMR1_LLBSC); - } - } -} - -/*---------------------------------------------------------------------------- - * falc_pattern_test_error - *---------------------------------------------------------------------------- - * Description: This routine returns the bit error counter value - *---------------------------------------------------------------------------- - */ -static u16 falc_pattern_test_error(pc300_t * card, int ch) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - falc_t *pfalc = (falc_t *) & chan->falc; - - return pfalc->bec; -} - -/**********************************/ -/*** Net Interface Routines ***/ -/**********************************/ - -static void -cpc_trace(struct net_device *dev, struct sk_buff *skb_main, char rx_tx) -{ - struct sk_buff *skb; - - if ((skb = dev_alloc_skb(10 + skb_main->len)) == NULL) { - printk("%s: out of memory\n", dev->name); - return; - } - skb_put(skb, 10 + skb_main->len); - - skb->dev = dev; - skb->protocol = htons(ETH_P_CUST); - skb_reset_mac_header(skb); - skb->pkt_type = PACKET_HOST; - skb->len = 10 + skb_main->len; - - skb_copy_to_linear_data(skb, dev->name, 5); - skb->data[5] = '['; - skb->data[6] = rx_tx; - skb->data[7] = ']'; - skb->data[8] = ':'; - skb->data[9] = ' '; - skb_copy_from_linear_data(skb_main, &skb->data[10], skb_main->len); - - netif_rx(skb); -} - -static void cpc_tx_timeout(struct net_device *dev) -{ - pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv; - pc300ch_t *chan = (pc300ch_t *) d->chan; - pc300_t *card = (pc300_t *) chan->card; - int ch = chan->channel; - unsigned long flags; - u8 ilar; - - dev->stats.tx_errors++; - dev->stats.tx_aborted_errors++; - CPC_LOCK(card, flags); - if ((ilar = cpc_readb(card->hw.scabase + ILAR)) != 0) { - printk("%s: ILAR=0x%x\n", dev->name, ilar); - cpc_writeb(card->hw.scabase + ILAR, ilar); - cpc_writeb(card->hw.scabase + DMER, 0x80); - } - if (card->hw.type == PC300_TE) { - cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, - cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) & - ~(CPLD_REG2_FALC_LED1 << (2 * ch))); - } - dev->trans_start = jiffies; /* prevent tx timeout */ - CPC_UNLOCK(card, flags); - netif_wake_queue(dev); -} - -static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev) -{ - pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv; - pc300ch_t *chan = (pc300ch_t *) d->chan; - pc300_t *card = (pc300_t *) chan->card; - int ch = chan->channel; - unsigned long flags; -#ifdef PC300_DEBUG_TX - int i; -#endif - - if (!netif_carrier_ok(dev)) { - /* DCD must be OFF: drop packet */ - dev_kfree_skb(skb); - dev->stats.tx_errors++; - dev->stats.tx_carrier_errors++; - return 0; - } else if (cpc_readb(card->hw.scabase + M_REG(ST3, ch)) & ST3_DCD) { - printk("%s: DCD is OFF. Going administrative down.\n", dev->name); - dev->stats.tx_errors++; - dev->stats.tx_carrier_errors++; - dev_kfree_skb(skb); - netif_carrier_off(dev); - CPC_LOCK(card, flags); - cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_BUF_CLR); - if (card->hw.type == PC300_TE) { - cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, - cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) & - ~(CPLD_REG2_FALC_LED1 << (2 * ch))); - } - CPC_UNLOCK(card, flags); - netif_wake_queue(dev); - return 0; - } - - /* Write buffer to DMA buffers */ - if (dma_buf_write(card, ch, (u8 *)skb->data, skb->len) != 0) { -// printk("%s: write error. Dropping TX packet.\n", dev->name); - netif_stop_queue(dev); - dev_kfree_skb(skb); - dev->stats.tx_errors++; - dev->stats.tx_dropped++; - return 0; - } -#ifdef PC300_DEBUG_TX - printk("%s T:", dev->name); - for (i = 0; i < skb->len; i++) - printk(" %02x", *(skb->data + i)); - printk("\n"); -#endif - - if (d->trace_on) { - cpc_trace(dev, skb, 'T'); - } - - /* Start transmission */ - CPC_LOCK(card, flags); - /* verify if it has more than one free descriptor */ - if (card->chan[ch].nfree_tx_bd <= 1) { - /* don't have so stop the queue */ - netif_stop_queue(dev); - } - cpc_writel(card->hw.scabase + DTX_REG(EDAL, ch), - TX_BD_ADDR(ch, chan->tx_next_bd)); - cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_ENA); - cpc_writeb(card->hw.scabase + DSR_TX(ch), DSR_DE); - if (card->hw.type == PC300_TE) { - cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, - cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) | - (CPLD_REG2_FALC_LED1 << (2 * ch))); - } - CPC_UNLOCK(card, flags); - dev_kfree_skb(skb); - - return 0; -} - -static void cpc_net_rx(struct net_device *dev) -{ - pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv; - pc300ch_t *chan = (pc300ch_t *) d->chan; - pc300_t *card = (pc300_t *) chan->card; - int ch = chan->channel; -#ifdef PC300_DEBUG_RX - int i; -#endif - int rxb; - struct sk_buff *skb; - - while (1) { - if ((rxb = dma_get_rx_frame_size(card, ch)) == -1) - return; - - if (!netif_carrier_ok(dev)) { - /* DCD must be OFF: drop packet */ - printk("%s : DCD is OFF - drop %d rx bytes\n", dev->name, rxb); - skb = NULL; - } else { - if (rxb > (dev->mtu + 40)) { /* add headers */ - printk("%s : MTU exceeded %d\n", dev->name, rxb); - skb = NULL; - } else { - skb = dev_alloc_skb(rxb); - if (skb == NULL) { - printk("%s: Memory squeeze!!\n", dev->name); - return; - } - skb->dev = dev; - } - } - - if (((rxb = dma_buf_read(card, ch, skb)) <= 0) || (skb == NULL)) { -#ifdef PC300_DEBUG_RX - printk("%s: rxb = %x\n", dev->name, rxb); -#endif - if ((skb == NULL) && (rxb > 0)) { - /* rxb > dev->mtu */ - dev->stats.rx_errors++; - dev->stats.rx_length_errors++; - continue; - } - - if (rxb < 0) { /* Invalid frame */ - rxb = -rxb; - if (rxb & DST_OVR) { - dev->stats.rx_errors++; - dev->stats.rx_fifo_errors++; - } - if (rxb & DST_CRC) { - dev->stats.rx_errors++; - dev->stats.rx_crc_errors++; - } - if (rxb & (DST_RBIT | DST_SHRT | DST_ABT)) { - dev->stats.rx_errors++; - dev->stats.rx_frame_errors++; - } - } - if (skb) { - dev_kfree_skb_irq(skb); - } - continue; - } - - dev->stats.rx_bytes += rxb; - -#ifdef PC300_DEBUG_RX - printk("%s R:", dev->name); - for (i = 0; i < skb->len; i++) - printk(" %02x", *(skb->data + i)); - printk("\n"); -#endif - if (d->trace_on) { - cpc_trace(dev, skb, 'R'); - } - dev->stats.rx_packets++; - skb->protocol = hdlc_type_trans(skb, dev); - netif_rx(skb); - } -} - -/************************************/ -/*** PC300 Interrupt Routines ***/ -/************************************/ -static void sca_tx_intr(pc300dev_t *dev) -{ - pc300ch_t *chan = (pc300ch_t *)dev->chan; - pc300_t *card = (pc300_t *)chan->card; - int ch = chan->channel; - volatile pcsca_bd_t __iomem * ptdescr; - - /* Clean up descriptors from previous transmission */ - ptdescr = (card->hw.rambase + - TX_BD_ADDR(ch,chan->tx_first_bd)); - while ((cpc_readl(card->hw.scabase + DTX_REG(CDAL,ch)) != - TX_BD_ADDR(ch,chan->tx_first_bd)) && - (cpc_readb(&ptdescr->status) & DST_OSB)) { - dev->dev->stats.tx_packets++; - dev->dev->stats.tx_bytes += cpc_readw(&ptdescr->len); - cpc_writeb(&ptdescr->status, DST_OSB); - cpc_writew(&ptdescr->len, 0); - chan->nfree_tx_bd++; - chan->tx_first_bd = (chan->tx_first_bd + 1) & (N_DMA_TX_BUF - 1); - ptdescr = (card->hw.rambase + TX_BD_ADDR(ch,chan->tx_first_bd)); - } - -#ifdef CONFIG_PC300_MLPPP - if (chan->conf.proto == PC300_PROTO_MLPPP) { - cpc_tty_trigger_poll(dev); - } else { -#endif - /* Tell the upper layer we are ready to transmit more packets */ - netif_wake_queue(dev->dev); -#ifdef CONFIG_PC300_MLPPP - } -#endif -} - -static void sca_intr(pc300_t * card) -{ - void __iomem *scabase = card->hw.scabase; - volatile u32 status; - int ch; - int intr_count = 0; - unsigned char dsr_rx; - - while ((status = cpc_readl(scabase + ISR0)) != 0) { - for (ch = 0; ch < card->hw.nchan; ch++) { - pc300ch_t *chan = &card->chan[ch]; - pc300dev_t *d = &chan->d; - struct net_device *dev = d->dev; - - spin_lock(&card->card_lock); - - /**** Reception ****/ - if (status & IR0_DRX((IR0_DMIA | IR0_DMIB), ch)) { - u8 drx_stat = cpc_readb(scabase + DSR_RX(ch)); - - /* Clear RX interrupts */ - cpc_writeb(scabase + DSR_RX(ch), drx_stat | DSR_DWE); - -#ifdef PC300_DEBUG_INTR - printk ("sca_intr: RX intr chan[%d] (st=0x%08lx, dsr=0x%02x)\n", - ch, status, drx_stat); -#endif - if (status & IR0_DRX(IR0_DMIA, ch)) { - if (drx_stat & DSR_BOF) { -#ifdef CONFIG_PC300_MLPPP - if (chan->conf.proto == PC300_PROTO_MLPPP) { - /* verify if driver is TTY */ - if ((cpc_readb(scabase + DSR_RX(ch)) & DSR_DE)) { - rx_dma_stop(card, ch); - } - cpc_tty_receive(d); - rx_dma_start(card, ch); - } else -#endif - { - if ((cpc_readb(scabase + DSR_RX(ch)) & DSR_DE)) { - rx_dma_stop(card, ch); - } - cpc_net_rx(dev); - /* Discard invalid frames */ - dev->stats.rx_errors++; - dev->stats.rx_over_errors++; - chan->rx_first_bd = 0; - chan->rx_last_bd = N_DMA_RX_BUF - 1; - rx_dma_start(card, ch); - } - } - } - if (status & IR0_DRX(IR0_DMIB, ch)) { - if (drx_stat & DSR_EOM) { - if (card->hw.type == PC300_TE) { - cpc_writeb(card->hw.falcbase + - card->hw.cpld_reg2, - cpc_readb (card->hw.falcbase + - card->hw.cpld_reg2) | - (CPLD_REG2_FALC_LED1 << (2 * ch))); - } -#ifdef CONFIG_PC300_MLPPP - if (chan->conf.proto == PC300_PROTO_MLPPP) { - /* verify if driver is TTY */ - cpc_tty_receive(d); - } else { - cpc_net_rx(dev); - } -#else - cpc_net_rx(dev); -#endif - if (card->hw.type == PC300_TE) { - cpc_writeb(card->hw.falcbase + - card->hw.cpld_reg2, - cpc_readb (card->hw.falcbase + - card->hw.cpld_reg2) & - ~ (CPLD_REG2_FALC_LED1 << (2 * ch))); - } - } - } - if (!(dsr_rx = cpc_readb(scabase + DSR_RX(ch)) & DSR_DE)) { -#ifdef PC300_DEBUG_INTR - printk("%s: RX intr chan[%d] (st=0x%08lx, dsr=0x%02x, dsr2=0x%02x)\n", - dev->name, ch, status, drx_stat, dsr_rx); -#endif - cpc_writeb(scabase + DSR_RX(ch), (dsr_rx | DSR_DE) & 0xfe); - } - } - - /**** Transmission ****/ - if (status & IR0_DTX((IR0_EFT | IR0_DMIA | IR0_DMIB), ch)) { - u8 dtx_stat = cpc_readb(scabase + DSR_TX(ch)); - - /* Clear TX interrupts */ - cpc_writeb(scabase + DSR_TX(ch), dtx_stat | DSR_DWE); - -#ifdef PC300_DEBUG_INTR - printk ("sca_intr: TX intr chan[%d] (st=0x%08lx, dsr=0x%02x)\n", - ch, status, dtx_stat); -#endif - if (status & IR0_DTX(IR0_EFT, ch)) { - if (dtx_stat & DSR_UDRF) { - if (cpc_readb (scabase + M_REG(TBN, ch)) != 0) { - cpc_writeb(scabase + M_REG(CMD,ch), CMD_TX_BUF_CLR); - } - if (card->hw.type == PC300_TE) { - cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, - cpc_readb (card->hw.falcbase + - card->hw.cpld_reg2) & - ~ (CPLD_REG2_FALC_LED1 << (2 * ch))); - } - dev->stats.tx_errors++; - dev->stats.tx_fifo_errors++; - sca_tx_intr(d); - } - } - if (status & IR0_DTX(IR0_DMIA, ch)) { - if (dtx_stat & DSR_BOF) { - } - } - if (status & IR0_DTX(IR0_DMIB, ch)) { - if (dtx_stat & DSR_EOM) { - if (card->hw.type == PC300_TE) { - cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, - cpc_readb (card->hw.falcbase + - card->hw.cpld_reg2) & - ~ (CPLD_REG2_FALC_LED1 << (2 * ch))); - } - sca_tx_intr(d); - } - } - } - - /**** MSCI ****/ - if (status & IR0_M(IR0_RXINTA, ch)) { - u8 st1 = cpc_readb(scabase + M_REG(ST1, ch)); - - /* Clear MSCI interrupts */ - cpc_writeb(scabase + M_REG(ST1, ch), st1); - -#ifdef PC300_DEBUG_INTR - printk("sca_intr: MSCI intr chan[%d] (st=0x%08lx, st1=0x%02x)\n", - ch, status, st1); -#endif - if (st1 & ST1_CDCD) { /* DCD changed */ - if (cpc_readb(scabase + M_REG(ST3, ch)) & ST3_DCD) { - printk ("%s: DCD is OFF. Going administrative down.\n", - dev->name); -#ifdef CONFIG_PC300_MLPPP - if (chan->conf.proto != PC300_PROTO_MLPPP) { - netif_carrier_off(dev); - } -#else - netif_carrier_off(dev); - -#endif - card->chan[ch].d.line_off++; - } else { /* DCD = 1 */ - printk ("%s: DCD is ON. Going administrative up.\n", - dev->name); -#ifdef CONFIG_PC300_MLPPP - if (chan->conf.proto != PC300_PROTO_MLPPP) - /* verify if driver is not TTY */ -#endif - netif_carrier_on(dev); - card->chan[ch].d.line_on++; - } - } - } - spin_unlock(&card->card_lock); - } - if (++intr_count == 10) - /* Too much work at this board. Force exit */ - break; - } -} - -static void falc_t1_loop_detection(pc300_t *card, int ch, u8 frs1) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - falc_t *pfalc = (falc_t *) & chan->falc; - void __iomem *falcbase = card->hw.falcbase; - - if (((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_XPRBS) == 0) && - !pfalc->loop_gen) { - if (frs1 & FRS1_LLBDD) { - // A Line Loop Back Deactivation signal detected - if (pfalc->loop_active) { - falc_remote_loop(card, ch, 0); - } - } else { - if ((frs1 & FRS1_LLBAD) && - ((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_EPRM) == 0)) { - // A Line Loop Back Activation signal detected - if (!pfalc->loop_active) { - falc_remote_loop(card, ch, 1); - } - } - } - } -} - -static void falc_e1_loop_detection(pc300_t *card, int ch, u8 rsp) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - falc_t *pfalc = (falc_t *) & chan->falc; - void __iomem *falcbase = card->hw.falcbase; - - if (((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_XPRBS) == 0) && - !pfalc->loop_gen) { - if (rsp & RSP_LLBDD) { - // A Line Loop Back Deactivation signal detected - if (pfalc->loop_active) { - falc_remote_loop(card, ch, 0); - } - } else { - if ((rsp & RSP_LLBAD) && - ((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_EPRM) == 0)) { - // A Line Loop Back Activation signal detected - if (!pfalc->loop_active) { - falc_remote_loop(card, ch, 1); - } - } - } - } -} - -static void falc_t1_intr(pc300_t * card, int ch) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - falc_t *pfalc = (falc_t *) & chan->falc; - void __iomem *falcbase = card->hw.falcbase; - u8 isr0, isr3, gis; - u8 dummy; - - while ((gis = cpc_readb(falcbase + F_REG(GIS, ch))) != 0) { - if (gis & GIS_ISR0) { - isr0 = cpc_readb(falcbase + F_REG(FISR0, ch)); - if (isr0 & FISR0_PDEN) { - /* Read the bit to clear the situation */ - if (cpc_readb(falcbase + F_REG(FRS1, ch)) & - FRS1_PDEN) { - pfalc->pden++; - } - } - } - - if (gis & GIS_ISR1) { - dummy = cpc_readb(falcbase + F_REG(FISR1, ch)); - } - - if (gis & GIS_ISR2) { - dummy = cpc_readb(falcbase + F_REG(FISR2, ch)); - } - - if (gis & GIS_ISR3) { - isr3 = cpc_readb(falcbase + F_REG(FISR3, ch)); - if (isr3 & FISR3_SEC) { - pfalc->sec++; - falc_update_stats(card, ch); - falc_check_status(card, ch, - cpc_readb(falcbase + F_REG(FRS0, ch))); - } - if (isr3 & FISR3_ES) { - pfalc->es++; - } - if (isr3 & FISR3_LLBSC) { - falc_t1_loop_detection(card, ch, - cpc_readb(falcbase + F_REG(FRS1, ch))); - } - } - } -} - -static void falc_e1_intr(pc300_t * card, int ch) -{ - pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; - falc_t *pfalc = (falc_t *) & chan->falc; - void __iomem *falcbase = card->hw.falcbase; - u8 isr1, isr2, isr3, gis, rsp; - u8 dummy; - - while ((gis = cpc_readb(falcbase + F_REG(GIS, ch))) != 0) { - rsp = cpc_readb(falcbase + F_REG(RSP, ch)); - - if (gis & GIS_ISR0) { - dummy = cpc_readb(falcbase + F_REG(FISR0, ch)); - } - if (gis & GIS_ISR1) { - isr1 = cpc_readb(falcbase + F_REG(FISR1, ch)); - if (isr1 & FISR1_XMB) { - if ((pfalc->xmb_cause & 2) && - pfalc->multiframe_mode) { - if (cpc_readb (falcbase + F_REG(FRS0, ch)) & - (FRS0_LOS | FRS0_AIS | FRS0_LFA)) { - cpc_writeb(falcbase + F_REG(XSP, ch), - cpc_readb(falcbase + F_REG(XSP, ch)) - & ~XSP_AXS); - } else { - cpc_writeb(falcbase + F_REG(XSP, ch), - cpc_readb(falcbase + F_REG(XSP, ch)) - | XSP_AXS); - } - } - pfalc->xmb_cause = 0; - cpc_writeb(falcbase + F_REG(IMR1, ch), - cpc_readb(falcbase + F_REG(IMR1, ch)) | IMR1_XMB); - } - if (isr1 & FISR1_LLBSC) { - falc_e1_loop_detection(card, ch, rsp); - } - } - if (gis & GIS_ISR2) { - isr2 = cpc_readb(falcbase + F_REG(FISR2, ch)); - if (isr2 & FISR2_T400MS) { - cpc_writeb(falcbase + F_REG(XSW, ch), - cpc_readb(falcbase + F_REG(XSW, ch)) | XSW_XRA); - } - if (isr2 & FISR2_MFAR) { - cpc_writeb(falcbase + F_REG(XSW, ch), - cpc_readb(falcbase + F_REG(XSW, ch)) & ~XSW_XRA); - } - if (isr2 & (FISR2_FAR | FISR2_LFA | FISR2_AIS | FISR2_LOS)) { - pfalc->xmb_cause |= 2; - cpc_writeb(falcbase + F_REG(IMR1, ch), - cpc_readb(falcbase + F_REG(IMR1, ch)) & ~IMR1_XMB); - } - } - if (gis & GIS_ISR3) { - isr3 = cpc_readb(falcbase + F_REG(FISR3, ch)); - if (isr3 & FISR3_SEC) { - pfalc->sec++; - falc_update_stats(card, ch); - falc_check_status(card, ch, - cpc_readb(falcbase + F_REG(FRS0, ch))); - } - if (isr3 & FISR3_ES) { - pfalc->es++; - } - } - } -} - -static void falc_intr(pc300_t * card) -{ - int ch; - - for (ch = 0; ch < card->hw.nchan; ch++) { - pc300ch_t *chan = &card->chan[ch]; - pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; - - if (conf->media == IF_IFACE_T1) { - falc_t1_intr(card, ch); - } else { - falc_e1_intr(card, ch); - } - } -} - -static irqreturn_t cpc_intr(int irq, void *dev_id) -{ - pc300_t *card = dev_id; - volatile u8 plx_status; - - if (!card) { -#ifdef PC300_DEBUG_INTR - printk("cpc_intr: spurious intr %d\n", irq); -#endif - return IRQ_NONE; /* spurious intr */ - } - - if (!card->hw.rambase) { -#ifdef PC300_DEBUG_INTR - printk("cpc_intr: spurious intr2 %d\n", irq); -#endif - return IRQ_NONE; /* spurious intr */ - } - - switch (card->hw.type) { - case PC300_RSV: - case PC300_X21: - sca_intr(card); - break; - - case PC300_TE: - while ( (plx_status = (cpc_readb(card->hw.plxbase + card->hw.intctl_reg) & - (PLX_9050_LINT1_STATUS | PLX_9050_LINT2_STATUS))) != 0) { - if (plx_status & PLX_9050_LINT1_STATUS) { /* SCA Interrupt */ - sca_intr(card); - } - if (plx_status & PLX_9050_LINT2_STATUS) { /* FALC Interrupt */ - falc_intr(card); - } - } - break; - } - return IRQ_HANDLED; -} - -static void cpc_sca_status(pc300_t * card, int ch) -{ - u8 ilar; - void __iomem *scabase = card->hw.scabase; - unsigned long flags; - - tx_dma_buf_check(card, ch); - rx_dma_buf_check(card, ch); - ilar = cpc_readb(scabase + ILAR); - printk ("ILAR=0x%02x, WCRL=0x%02x, PCR=0x%02x, BTCR=0x%02x, BOLR=0x%02x\n", - ilar, cpc_readb(scabase + WCRL), cpc_readb(scabase + PCR), - cpc_readb(scabase + BTCR), cpc_readb(scabase + BOLR)); - printk("TX_CDA=0x%08x, TX_EDA=0x%08x\n", - cpc_readl(scabase + DTX_REG(CDAL, ch)), - cpc_readl(scabase + DTX_REG(EDAL, ch))); - printk("RX_CDA=0x%08x, RX_EDA=0x%08x, BFL=0x%04x\n", - cpc_readl(scabase + DRX_REG(CDAL, ch)), - cpc_readl(scabase + DRX_REG(EDAL, ch)), - cpc_readw(scabase + DRX_REG(BFLL, ch))); - printk("DMER=0x%02x, DSR_TX=0x%02x, DSR_RX=0x%02x\n", - cpc_readb(scabase + DMER), cpc_readb(scabase + DSR_TX(ch)), - cpc_readb(scabase + DSR_RX(ch))); - printk("DMR_TX=0x%02x, DMR_RX=0x%02x, DIR_TX=0x%02x, DIR_RX=0x%02x\n", - cpc_readb(scabase + DMR_TX(ch)), cpc_readb(scabase + DMR_RX(ch)), - cpc_readb(scabase + DIR_TX(ch)), - cpc_readb(scabase + DIR_RX(ch))); - printk("DCR_TX=0x%02x, DCR_RX=0x%02x, FCT_TX=0x%02x, FCT_RX=0x%02x\n", - cpc_readb(scabase + DCR_TX(ch)), cpc_readb(scabase + DCR_RX(ch)), - cpc_readb(scabase + FCT_TX(ch)), - cpc_readb(scabase + FCT_RX(ch))); - printk("MD0=0x%02x, MD1=0x%02x, MD2=0x%02x, MD3=0x%02x, IDL=0x%02x\n", - cpc_readb(scabase + M_REG(MD0, ch)), - cpc_readb(scabase + M_REG(MD1, ch)), - cpc_readb(scabase + M_REG(MD2, ch)), - cpc_readb(scabase + M_REG(MD3, ch)), - cpc_readb(scabase + M_REG(IDL, ch))); - printk("CMD=0x%02x, SA0=0x%02x, SA1=0x%02x, TFN=0x%02x, CTL=0x%02x\n", - cpc_readb(scabase + M_REG(CMD, ch)), - cpc_readb(scabase + M_REG(SA0, ch)), - cpc_readb(scabase + M_REG(SA1, ch)), - cpc_readb(scabase + M_REG(TFN, ch)), - cpc_readb(scabase + M_REG(CTL, ch))); - printk("ST0=0x%02x, ST1=0x%02x, ST2=0x%02x, ST3=0x%02x, ST4=0x%02x\n", - cpc_readb(scabase + M_REG(ST0, ch)), - cpc_readb(scabase + M_REG(ST1, ch)), - cpc_readb(scabase + M_REG(ST2, ch)), - cpc_readb(scabase + M_REG(ST3, ch)), - cpc_readb(scabase + M_REG(ST4, ch))); - printk ("CST0=0x%02x, CST1=0x%02x, CST2=0x%02x, CST3=0x%02x, FST=0x%02x\n", - cpc_readb(scabase + M_REG(CST0, ch)), - cpc_readb(scabase + M_REG(CST1, ch)), - cpc_readb(scabase + M_REG(CST2, ch)), - cpc_readb(scabase + M_REG(CST3, ch)), - cpc_readb(scabase + M_REG(FST, ch))); - printk("TRC0=0x%02x, TRC1=0x%02x, RRC=0x%02x, TBN=0x%02x, RBN=0x%02x\n", - cpc_readb(scabase + M_REG(TRC0, ch)), - cpc_readb(scabase + M_REG(TRC1, ch)), - cpc_readb(scabase + M_REG(RRC, ch)), - cpc_readb(scabase + M_REG(TBN, ch)), - cpc_readb(scabase + M_REG(RBN, ch))); - printk("TFS=0x%02x, TNR0=0x%02x, TNR1=0x%02x, RNR=0x%02x\n", - cpc_readb(scabase + M_REG(TFS, ch)), - cpc_readb(scabase + M_REG(TNR0, ch)), - cpc_readb(scabase + M_REG(TNR1, ch)), - cpc_readb(scabase + M_REG(RNR, ch))); - printk("TCR=0x%02x, RCR=0x%02x, TNR1=0x%02x, RNR=0x%02x\n", - cpc_readb(scabase + M_REG(TCR, ch)), - cpc_readb(scabase + M_REG(RCR, ch)), - cpc_readb(scabase + M_REG(TNR1, ch)), - cpc_readb(scabase + M_REG(RNR, ch))); - printk("TXS=0x%02x, RXS=0x%02x, EXS=0x%02x, TMCT=0x%02x, TMCR=0x%02x\n", - cpc_readb(scabase + M_REG(TXS, ch)), - cpc_readb(scabase + M_REG(RXS, ch)), - cpc_readb(scabase + M_REG(EXS, ch)), - cpc_readb(scabase + M_REG(TMCT, ch)), - cpc_readb(scabase + M_REG(TMCR, ch))); - printk("IE0=0x%02x, IE1=0x%02x, IE2=0x%02x, IE4=0x%02x, FIE=0x%02x\n", - cpc_readb(scabase + M_REG(IE0, ch)), - cpc_readb(scabase + M_REG(IE1, ch)), - cpc_readb(scabase + M_REG(IE2, ch)), - cpc_readb(scabase + M_REG(IE4, ch)), - cpc_readb(scabase + M_REG(FIE, ch))); - printk("IER0=0x%08x\n", cpc_readl(scabase + IER0)); - - if (ilar != 0) { - CPC_LOCK(card, flags); - cpc_writeb(scabase + ILAR, ilar); - cpc_writeb(scabase + DMER, 0x80); - CPC_UNLOCK(card, flags); - } -} - -static void cpc_falc_status(pc300_t * card, int ch) -{ - pc300ch_t *chan = &card->chan[ch]; - falc_t *pfalc = (falc_t *) & chan->falc; - unsigned long flags; - - CPC_LOCK(card, flags); - printk("CH%d: %s %s %d channels\n", - ch, (pfalc->sync ? "SYNC" : ""), (pfalc->active ? "ACTIVE" : ""), - pfalc->num_channels); - - printk(" pden=%d, los=%d, losr=%d, lfa=%d, farec=%d\n", - pfalc->pden, pfalc->los, pfalc->losr, pfalc->lfa, pfalc->farec); - printk(" lmfa=%d, ais=%d, sec=%d, es=%d, rai=%d\n", - pfalc->lmfa, pfalc->ais, pfalc->sec, pfalc->es, pfalc->rai); - printk(" bec=%d, fec=%d, cvc=%d, cec=%d, ebc=%d\n", - pfalc->bec, pfalc->fec, pfalc->cvc, pfalc->cec, pfalc->ebc); - - printk("\n"); - printk(" STATUS: %s %s %s %s %s %s\n", - (pfalc->red_alarm ? "RED" : ""), - (pfalc->blue_alarm ? "BLU" : ""), - (pfalc->yellow_alarm ? "YEL" : ""), - (pfalc->loss_fa ? "LFA" : ""), - (pfalc->loss_mfa ? "LMF" : ""), (pfalc->prbs ? "PRB" : "")); - CPC_UNLOCK(card, flags); -} - -static int cpc_change_mtu(struct net_device *dev, int new_mtu) -{ - if ((new_mtu < 128) || (new_mtu > PC300_DEF_MTU)) - return -EINVAL; - dev->mtu = new_mtu; - return 0; -} - -static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ - pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv; - pc300ch_t *chan = (pc300ch_t *) d->chan; - pc300_t *card = (pc300_t *) chan->card; - pc300conf_t conf_aux; - pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; - int ch = chan->channel; - void __user *arg = ifr->ifr_data; - struct if_settings *settings = &ifr->ifr_settings; - void __iomem *scabase = card->hw.scabase; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - switch (cmd) { - case SIOCGPC300CONF: -#ifdef CONFIG_PC300_MLPPP - if (conf->proto != PC300_PROTO_MLPPP) { - conf->proto = /* FIXME hdlc->proto.id */ 0; - } -#else - conf->proto = /* FIXME hdlc->proto.id */ 0; -#endif - memcpy(&conf_aux.conf, conf, sizeof(pc300chconf_t)); - memcpy(&conf_aux.hw, &card->hw, sizeof(pc300hw_t)); - if (!arg || - copy_to_user(arg, &conf_aux, sizeof(pc300conf_t))) - return -EINVAL; - return 0; - case SIOCSPC300CONF: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (!arg || - copy_from_user(&conf_aux.conf, arg, sizeof(pc300chconf_t))) - return -EINVAL; - if (card->hw.cpld_id < 0x02 && - conf_aux.conf.fr_mode == PC300_FR_UNFRAMED) { - /* CPLD_ID < 0x02 doesn't support Unframed E1 */ - return -EINVAL; - } -#ifdef CONFIG_PC300_MLPPP - if (conf_aux.conf.proto == PC300_PROTO_MLPPP) { - if (conf->proto != PC300_PROTO_MLPPP) { - memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t)); - cpc_tty_init(d); /* init TTY driver */ - } - } else { - if (conf_aux.conf.proto == 0xffff) { - if (conf->proto == PC300_PROTO_MLPPP){ - /* ifdown interface */ - cpc_close(dev); - } - } else { - memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t)); - /* FIXME hdlc->proto.id = conf->proto; */ - } - } -#else - memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t)); - /* FIXME hdlc->proto.id = conf->proto; */ -#endif - return 0; - case SIOCGPC300STATUS: - cpc_sca_status(card, ch); - return 0; - case SIOCGPC300FALCSTATUS: - cpc_falc_status(card, ch); - return 0; - - case SIOCGPC300UTILSTATS: - { - if (!arg) { /* clear statistics */ - memset(&dev->stats, 0, sizeof(dev->stats)); - if (card->hw.type == PC300_TE) { - memset(&chan->falc, 0, sizeof(falc_t)); - } - } else { - pc300stats_t pc300stats; - - memset(&pc300stats, 0, sizeof(pc300stats_t)); - pc300stats.hw_type = card->hw.type; - pc300stats.line_on = card->chan[ch].d.line_on; - pc300stats.line_off = card->chan[ch].d.line_off; - memcpy(&pc300stats.gen_stats, &dev->stats, - sizeof(dev->stats)); - if (card->hw.type == PC300_TE) - memcpy(&pc300stats.te_stats,&chan->falc,sizeof(falc_t)); - if (copy_to_user(arg, &pc300stats, sizeof(pc300stats_t))) - return -EFAULT; - } - return 0; - } - - case SIOCGPC300UTILSTATUS: - { - struct pc300status pc300status; - - pc300status.hw_type = card->hw.type; - if (card->hw.type == PC300_TE) { - pc300status.te_status.sync = chan->falc.sync; - pc300status.te_status.red_alarm = chan->falc.red_alarm; - pc300status.te_status.blue_alarm = chan->falc.blue_alarm; - pc300status.te_status.loss_fa = chan->falc.loss_fa; - pc300status.te_status.yellow_alarm =chan->falc.yellow_alarm; - pc300status.te_status.loss_mfa = chan->falc.loss_mfa; - pc300status.te_status.prbs = chan->falc.prbs; - } else { - pc300status.gen_status.dcd = - !(cpc_readb (scabase + M_REG(ST3, ch)) & ST3_DCD); - pc300status.gen_status.cts = - !(cpc_readb (scabase + M_REG(ST3, ch)) & ST3_CTS); - pc300status.gen_status.rts = - !(cpc_readb (scabase + M_REG(CTL, ch)) & CTL_RTS); - pc300status.gen_status.dtr = - !(cpc_readb (scabase + M_REG(CTL, ch)) & CTL_DTR); - /* There is no DSR in HD64572 */ - } - if (!arg || - copy_to_user(arg, &pc300status, sizeof(pc300status_t))) - return -EINVAL; - return 0; - } - - case SIOCSPC300TRACE: - /* Sets/resets a trace_flag for the respective device */ - if (!arg || copy_from_user(&d->trace_on, arg,sizeof(unsigned char))) - return -EINVAL; - return 0; - - case SIOCSPC300LOOPBACK: - { - struct pc300loopback pc300loop; - - /* TE boards only */ - if (card->hw.type != PC300_TE) - return -EINVAL; - - if (!arg || - copy_from_user(&pc300loop, arg, sizeof(pc300loopback_t))) - return -EINVAL; - switch (pc300loop.loop_type) { - case PC300LOCLOOP: /* Turn the local loop on/off */ - falc_local_loop(card, ch, pc300loop.loop_on); - return 0; - - case PC300REMLOOP: /* Turn the remote loop on/off */ - falc_remote_loop(card, ch, pc300loop.loop_on); - return 0; - - case PC300PAYLOADLOOP: /* Turn the payload loop on/off */ - falc_payload_loop(card, ch, pc300loop.loop_on); - return 0; - - case PC300GENLOOPUP: /* Generate loop UP */ - if (pc300loop.loop_on) { - falc_generate_loop_up_code (card, ch); - } else { - turn_off_xlu(card, ch); - } - return 0; - - case PC300GENLOOPDOWN: /* Generate loop DOWN */ - if (pc300loop.loop_on) { - falc_generate_loop_down_code (card, ch); - } else { - turn_off_xld(card, ch); - } - return 0; - - default: - return -EINVAL; - } - } - - case SIOCSPC300PATTERNTEST: - /* Turn the pattern test on/off and show the errors counter */ - { - struct pc300patterntst pc300patrntst; - - /* TE boards only */ - if (card->hw.type != PC300_TE) - return -EINVAL; - - if (card->hw.cpld_id < 0x02) { - /* CPLD_ID < 0x02 doesn't support pattern test */ - return -EINVAL; - } - - if (!arg || - copy_from_user(&pc300patrntst,arg,sizeof(pc300patterntst_t))) - return -EINVAL; - if (pc300patrntst.patrntst_on == 2) { - if (chan->falc.prbs == 0) { - falc_pattern_test(card, ch, 1); - } - pc300patrntst.num_errors = - falc_pattern_test_error(card, ch); - if (copy_to_user(arg, &pc300patrntst, - sizeof(pc300patterntst_t))) - return -EINVAL; - } else { - falc_pattern_test(card, ch, pc300patrntst.patrntst_on); - } - return 0; - } - - case SIOCWANDEV: - switch (ifr->ifr_settings.type) { - case IF_GET_IFACE: - { - const size_t size = sizeof(sync_serial_settings); - ifr->ifr_settings.type = conf->media; - if (ifr->ifr_settings.size < size) { - /* data size wanted */ - ifr->ifr_settings.size = size; - return -ENOBUFS; - } - - if (copy_to_user(settings->ifs_ifsu.sync, - &conf->phys_settings, size)) { - return -EFAULT; - } - return 0; - } - - case IF_IFACE_V35: - case IF_IFACE_V24: - case IF_IFACE_X21: - { - const size_t size = sizeof(sync_serial_settings); - - if (!capable(CAP_NET_ADMIN)) { - return -EPERM; - } - /* incorrect data len? */ - if (ifr->ifr_settings.size != size) { - return -ENOBUFS; - } - - if (copy_from_user(&conf->phys_settings, - settings->ifs_ifsu.sync, size)) { - return -EFAULT; - } - - if (conf->phys_settings.loopback) { - cpc_writeb(card->hw.scabase + M_REG(MD2, ch), - cpc_readb(card->hw.scabase + M_REG(MD2, ch)) | - MD2_LOOP_MIR); - } - conf->media = ifr->ifr_settings.type; - return 0; - } - - case IF_IFACE_T1: - case IF_IFACE_E1: - { - const size_t te_size = sizeof(te1_settings); - const size_t size = sizeof(sync_serial_settings); - - if (!capable(CAP_NET_ADMIN)) { - return -EPERM; - } - - /* incorrect data len? */ - if (ifr->ifr_settings.size != te_size) { - return -ENOBUFS; - } - - if (copy_from_user(&conf->phys_settings, - settings->ifs_ifsu.te1, size)) { - return -EFAULT; - }/* Ignoring HDLC slot_map for a while */ - - if (conf->phys_settings.loopback) { - cpc_writeb(card->hw.scabase + M_REG(MD2, ch), - cpc_readb(card->hw.scabase + M_REG(MD2, ch)) | - MD2_LOOP_MIR); - } - conf->media = ifr->ifr_settings.type; - return 0; - } - default: - return hdlc_ioctl(dev, ifr, cmd); - } - - default: - return hdlc_ioctl(dev, ifr, cmd); - } -} - -static int clock_rate_calc(u32 rate, u32 clock, int *br_io) -{ - int br, tc; - int br_pwr, error; - - *br_io = 0; - - if (rate == 0) - return 0; - - for (br = 0, br_pwr = 1; br <= 9; br++, br_pwr <<= 1) { - if ((tc = clock / br_pwr / rate) <= 0xff) { - *br_io = br; - break; - } - } - - if (tc <= 0xff) { - error = ((rate - (clock / br_pwr / rate)) / rate) * 1000; - /* Errors bigger than +/- 1% won't be tolerated */ - if (error < -10 || error > 10) - return -1; - else - return tc; - } else { - return -1; - } -} - -static int ch_config(pc300dev_t * d) -{ - pc300ch_t *chan = (pc300ch_t *) d->chan; - pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; - pc300_t *card = (pc300_t *) chan->card; - void __iomem *scabase = card->hw.scabase; - void __iomem *plxbase = card->hw.plxbase; - int ch = chan->channel; - u32 clkrate = chan->conf.phys_settings.clock_rate; - u32 clktype = chan->conf.phys_settings.clock_type; - u16 encoding = chan->conf.proto_settings.encoding; - u16 parity = chan->conf.proto_settings.parity; - u8 md0, md2; - - /* Reset the channel */ - cpc_writeb(scabase + M_REG(CMD, ch), CMD_CH_RST); - - /* Configure the SCA registers */ - switch (parity) { - case PARITY_NONE: - md0 = MD0_BIT_SYNC; - break; - case PARITY_CRC16_PR0: - md0 = MD0_CRC16_0|MD0_CRCC0|MD0_BIT_SYNC; - break; - case PARITY_CRC16_PR1: - md0 = MD0_CRC16_1|MD0_CRCC0|MD0_BIT_SYNC; - break; - case PARITY_CRC32_PR1_CCITT: - md0 = MD0_CRC32|MD0_CRCC0|MD0_BIT_SYNC; - break; - case PARITY_CRC16_PR1_CCITT: - default: - md0 = MD0_CRC_CCITT|MD0_CRCC0|MD0_BIT_SYNC; - break; - } - switch (encoding) { - case ENCODING_NRZI: - md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_NRZI; - break; - case ENCODING_FM_MARK: /* FM1 */ - md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_FM|MD2_FM1; - break; - case ENCODING_FM_SPACE: /* FM0 */ - md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_FM|MD2_FM0; - break; - case ENCODING_MANCHESTER: /* It's not working... */ - md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_FM|MD2_MANCH; - break; - case ENCODING_NRZ: - default: - md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_NRZ; - break; - } - cpc_writeb(scabase + M_REG(MD0, ch), md0); - cpc_writeb(scabase + M_REG(MD1, ch), 0); - cpc_writeb(scabase + M_REG(MD2, ch), md2); - cpc_writeb(scabase + M_REG(IDL, ch), 0x7e); - cpc_writeb(scabase + M_REG(CTL, ch), CTL_URSKP | CTL_IDLC); - - /* Configure HW media */ - switch (card->hw.type) { - case PC300_RSV: - if (conf->media == IF_IFACE_V35) { - cpc_writel((plxbase + card->hw.gpioc_reg), - cpc_readl(plxbase + card->hw.gpioc_reg) | PC300_CHMEDIA_MASK(ch)); - } else { - cpc_writel((plxbase + card->hw.gpioc_reg), - cpc_readl(plxbase + card->hw.gpioc_reg) & ~PC300_CHMEDIA_MASK(ch)); - } - break; - - case PC300_X21: - break; - - case PC300_TE: - te_config(card, ch); - break; - } - - switch (card->hw.type) { - case PC300_RSV: - case PC300_X21: - if (clktype == CLOCK_INT || clktype == CLOCK_TXINT) { - int tmc, br; - - /* Calculate the clkrate parameters */ - tmc = clock_rate_calc(clkrate, card->hw.clock, &br); - if (tmc < 0) - return -EIO; - cpc_writeb(scabase + M_REG(TMCT, ch), tmc); - cpc_writeb(scabase + M_REG(TXS, ch), - (TXS_DTRXC | TXS_IBRG | br)); - if (clktype == CLOCK_INT) { - cpc_writeb(scabase + M_REG(TMCR, ch), tmc); - cpc_writeb(scabase + M_REG(RXS, ch), - (RXS_IBRG | br)); - } else { - cpc_writeb(scabase + M_REG(TMCR, ch), 1); - cpc_writeb(scabase + M_REG(RXS, ch), 0); - } - if (card->hw.type == PC300_X21) { - cpc_writeb(scabase + M_REG(GPO, ch), 1); - cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1 | EXS_RES1); - } else { - cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1); - } - } else { - cpc_writeb(scabase + M_REG(TMCT, ch), 1); - if (clktype == CLOCK_EXT) { - cpc_writeb(scabase + M_REG(TXS, ch), - TXS_DTRXC); - } else { - cpc_writeb(scabase + M_REG(TXS, ch), - TXS_DTRXC|TXS_RCLK); - } - cpc_writeb(scabase + M_REG(TMCR, ch), 1); - cpc_writeb(scabase + M_REG(RXS, ch), 0); - if (card->hw.type == PC300_X21) { - cpc_writeb(scabase + M_REG(GPO, ch), 0); - cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1 | EXS_RES1); - } else { - cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1); - } - } - break; - - case PC300_TE: - /* SCA always receives clock from the FALC chip */ - cpc_writeb(scabase + M_REG(TMCT, ch), 1); - cpc_writeb(scabase + M_REG(TXS, ch), 0); - cpc_writeb(scabase + M_REG(TMCR, ch), 1); - cpc_writeb(scabase + M_REG(RXS, ch), 0); - cpc_writeb(scabase + M_REG(EXS, ch), 0); - break; - } - - /* Enable Interrupts */ - cpc_writel(scabase + IER0, - cpc_readl(scabase + IER0) | - IR0_M(IR0_RXINTA, ch) | - IR0_DRX(IR0_EFT | IR0_DMIA | IR0_DMIB, ch) | - IR0_DTX(IR0_EFT | IR0_DMIA | IR0_DMIB, ch)); - cpc_writeb(scabase + M_REG(IE0, ch), - cpc_readl(scabase + M_REG(IE0, ch)) | IE0_RXINTA); - cpc_writeb(scabase + M_REG(IE1, ch), - cpc_readl(scabase + M_REG(IE1, ch)) | IE1_CDCD); - - return 0; -} - -static int rx_config(pc300dev_t * d) -{ - pc300ch_t *chan = (pc300ch_t *) d->chan; - pc300_t *card = (pc300_t *) chan->card; - void __iomem *scabase = card->hw.scabase; - int ch = chan->channel; - - cpc_writeb(scabase + DSR_RX(ch), 0); - - /* General RX settings */ - cpc_writeb(scabase + M_REG(RRC, ch), 0); - cpc_writeb(scabase + M_REG(RNR, ch), 16); - - /* Enable reception */ - cpc_writeb(scabase + M_REG(CMD, ch), CMD_RX_CRC_INIT); - cpc_writeb(scabase + M_REG(CMD, ch), CMD_RX_ENA); - - /* Initialize DMA stuff */ - chan->rx_first_bd = 0; - chan->rx_last_bd = N_DMA_RX_BUF - 1; - rx_dma_buf_init(card, ch); - cpc_writeb(scabase + DCR_RX(ch), DCR_FCT_CLR); - cpc_writeb(scabase + DMR_RX(ch), (DMR_TMOD | DMR_NF)); - cpc_writeb(scabase + DIR_RX(ch), (DIR_EOM | DIR_BOF)); - - /* Start DMA */ - rx_dma_start(card, ch); - - return 0; -} - -static int tx_config(pc300dev_t * d) -{ - pc300ch_t *chan = (pc300ch_t *) d->chan; - pc300_t *card = (pc300_t *) chan->card; - void __iomem *scabase = card->hw.scabase; - int ch = chan->channel; - - cpc_writeb(scabase + DSR_TX(ch), 0); - - /* General TX settings */ - cpc_writeb(scabase + M_REG(TRC0, ch), 0); - cpc_writeb(scabase + M_REG(TFS, ch), 32); - cpc_writeb(scabase + M_REG(TNR0, ch), 20); - cpc_writeb(scabase + M_REG(TNR1, ch), 48); - cpc_writeb(scabase + M_REG(TCR, ch), 8); - - /* Enable transmission */ - cpc_writeb(scabase + M_REG(CMD, ch), CMD_TX_CRC_INIT); - - /* Initialize DMA stuff */ - chan->tx_first_bd = 0; - chan->tx_next_bd = 0; - tx_dma_buf_init(card, ch); - cpc_writeb(scabase + DCR_TX(ch), DCR_FCT_CLR); - cpc_writeb(scabase + DMR_TX(ch), (DMR_TMOD | DMR_NF)); - cpc_writeb(scabase + DIR_TX(ch), (DIR_EOM | DIR_BOF | DIR_UDRF)); - cpc_writel(scabase + DTX_REG(CDAL, ch), TX_BD_ADDR(ch, chan->tx_first_bd)); - cpc_writel(scabase + DTX_REG(EDAL, ch), TX_BD_ADDR(ch, chan->tx_next_bd)); - - return 0; -} - -static int cpc_attach(struct net_device *dev, unsigned short encoding, - unsigned short parity) -{ - pc300dev_t *d = (pc300dev_t *)dev_to_hdlc(dev)->priv; - pc300ch_t *chan = (pc300ch_t *)d->chan; - pc300_t *card = (pc300_t *)chan->card; - pc300chconf_t *conf = (pc300chconf_t *)&chan->conf; - - if (card->hw.type == PC300_TE) { - if (encoding != ENCODING_NRZ && encoding != ENCODING_NRZI) { - return -EINVAL; - } - } else { - if (encoding != ENCODING_NRZ && encoding != ENCODING_NRZI && - encoding != ENCODING_FM_MARK && encoding != ENCODING_FM_SPACE) { - /* Driver doesn't support ENCODING_MANCHESTER yet */ - return -EINVAL; - } - } - - if (parity != PARITY_NONE && parity != PARITY_CRC16_PR0 && - parity != PARITY_CRC16_PR1 && parity != PARITY_CRC32_PR1_CCITT && - parity != PARITY_CRC16_PR1_CCITT) { - return -EINVAL; - } - - conf->proto_settings.encoding = encoding; - conf->proto_settings.parity = parity; - return 0; -} - -static int cpc_opench(pc300dev_t * d) -{ - pc300ch_t *chan = (pc300ch_t *) d->chan; - pc300_t *card = (pc300_t *) chan->card; - int ch = chan->channel, rc; - void __iomem *scabase = card->hw.scabase; - - rc = ch_config(d); - if (rc) - return rc; - - rx_config(d); - - tx_config(d); - - /* Assert RTS and DTR */ - cpc_writeb(scabase + M_REG(CTL, ch), - cpc_readb(scabase + M_REG(CTL, ch)) & ~(CTL_RTS | CTL_DTR)); - - return 0; -} - -static void cpc_closech(pc300dev_t * d) -{ - pc300ch_t *chan = (pc300ch_t *) d->chan; - pc300_t *card = (pc300_t *) chan->card; - falc_t *pfalc = (falc_t *) & chan->falc; - int ch = chan->channel; - - cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_CH_RST); - rx_dma_stop(card, ch); - tx_dma_stop(card, ch); - - if (card->hw.type == PC300_TE) { - memset(pfalc, 0, sizeof(falc_t)); - cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, - cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) & - ~((CPLD_REG2_FALC_TX_CLK | CPLD_REG2_FALC_RX_CLK | - CPLD_REG2_FALC_LED2) << (2 * ch))); - /* Reset the FALC chip */ - cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, - cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) | - (CPLD_REG1_FALC_RESET << (2 * ch))); - udelay(10000); - cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, - cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) & - ~(CPLD_REG1_FALC_RESET << (2 * ch))); - } -} - -int cpc_open(struct net_device *dev) -{ - pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv; - struct ifreq ifr; - int result; - -#ifdef PC300_DEBUG_OTHER - printk("pc300: cpc_open"); -#endif - - result = hdlc_open(dev); - - if (result) - return result; - - sprintf(ifr.ifr_name, "%s", dev->name); - result = cpc_opench(d); - if (result) - goto err_out; - - netif_start_queue(dev); - return 0; - -err_out: - hdlc_close(dev); - return result; -} - -static int cpc_close(struct net_device *dev) -{ - pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv; - pc300ch_t *chan = (pc300ch_t *) d->chan; - pc300_t *card = (pc300_t *) chan->card; - unsigned long flags; - -#ifdef PC300_DEBUG_OTHER - printk("pc300: cpc_close"); -#endif - - netif_stop_queue(dev); - - CPC_LOCK(card, flags); - cpc_closech(d); - CPC_UNLOCK(card, flags); - - hdlc_close(dev); - -#ifdef CONFIG_PC300_MLPPP - if (chan->conf.proto == PC300_PROTO_MLPPP) { - cpc_tty_unregister_service(d); - chan->conf.proto = 0xffff; - } -#endif - - return 0; -} - -static u32 detect_ram(pc300_t * card) -{ - u32 i; - u8 data; - void __iomem *rambase = card->hw.rambase; - - card->hw.ramsize = PC300_RAMSIZE; - /* Let's find out how much RAM is present on this board */ - for (i = 0; i < card->hw.ramsize; i++) { - data = (u8)(i & 0xff); - cpc_writeb(rambase + i, data); - if (cpc_readb(rambase + i) != data) { - break; - } - } - return i; -} - -static void plx_init(pc300_t * card) -{ - struct RUNTIME_9050 __iomem *plx_ctl = card->hw.plxbase; - - /* Reset PLX */ - cpc_writel(&plx_ctl->init_ctrl, - cpc_readl(&plx_ctl->init_ctrl) | 0x40000000); - udelay(10000L); - cpc_writel(&plx_ctl->init_ctrl, - cpc_readl(&plx_ctl->init_ctrl) & ~0x40000000); - - /* Reload Config. Registers from EEPROM */ - cpc_writel(&plx_ctl->init_ctrl, - cpc_readl(&plx_ctl->init_ctrl) | 0x20000000); - udelay(10000L); - cpc_writel(&plx_ctl->init_ctrl, - cpc_readl(&plx_ctl->init_ctrl) & ~0x20000000); - -} - -static void show_version(void) -{ - char *rcsvers, *rcsdate, *tmp; - - rcsvers = strchr(rcsid, ' '); - rcsvers++; - tmp = strchr(rcsvers, ' '); - *tmp++ = '\0'; - rcsdate = strchr(tmp, ' '); - rcsdate++; - tmp = strrchr(rcsdate, ' '); - *tmp = '\0'; - pr_info("Cyclades-PC300 driver %s %s\n", rcsvers, rcsdate); -} /* show_version */ - -static const struct net_device_ops cpc_netdev_ops = { - .ndo_open = cpc_open, - .ndo_stop = cpc_close, - .ndo_tx_timeout = cpc_tx_timeout, - .ndo_set_mac_address = NULL, - .ndo_change_mtu = cpc_change_mtu, - .ndo_do_ioctl = cpc_ioctl, - .ndo_validate_addr = eth_validate_addr, -}; - -static void cpc_init_card(pc300_t * card) -{ - int i, devcount = 0; - static int board_nbr = 1; - - /* Enable interrupts on the PCI bridge */ - plx_init(card); - cpc_writew(card->hw.plxbase + card->hw.intctl_reg, - cpc_readw(card->hw.plxbase + card->hw.intctl_reg) | 0x0040); - -#ifdef USE_PCI_CLOCK - /* Set board clock to PCI clock */ - cpc_writel(card->hw.plxbase + card->hw.gpioc_reg, - cpc_readl(card->hw.plxbase + card->hw.gpioc_reg) | 0x00000004UL); - card->hw.clock = PC300_PCI_CLOCK; -#else - /* Set board clock to internal oscillator clock */ - cpc_writel(card->hw.plxbase + card->hw.gpioc_reg, - cpc_readl(card->hw.plxbase + card->hw.gpioc_reg) & ~0x00000004UL); - card->hw.clock = PC300_OSC_CLOCK; -#endif - - /* Detect actual on-board RAM size */ - card->hw.ramsize = detect_ram(card); - - /* Set Global SCA-II registers */ - cpc_writeb(card->hw.scabase + PCR, PCR_PR2); - cpc_writeb(card->hw.scabase + BTCR, 0x10); - cpc_writeb(card->hw.scabase + WCRL, 0); - cpc_writeb(card->hw.scabase + DMER, 0x80); - - if (card->hw.type == PC300_TE) { - u8 reg1; - - /* Check CPLD version */ - reg1 = cpc_readb(card->hw.falcbase + CPLD_REG1); - cpc_writeb(card->hw.falcbase + CPLD_REG1, (reg1 + 0x5a)); - if (cpc_readb(card->hw.falcbase + CPLD_REG1) == reg1) { - /* New CPLD */ - card->hw.cpld_id = cpc_readb(card->hw.falcbase + CPLD_ID_REG); - card->hw.cpld_reg1 = CPLD_V2_REG1; - card->hw.cpld_reg2 = CPLD_V2_REG2; - } else { - /* old CPLD */ - card->hw.cpld_id = 0; - card->hw.cpld_reg1 = CPLD_REG1; - card->hw.cpld_reg2 = CPLD_REG2; - cpc_writeb(card->hw.falcbase + CPLD_REG1, reg1); - } - - /* Enable the board's global clock */ - cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, - cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) | - CPLD_REG1_GLOBAL_CLK); - - } - - for (i = 0; i < card->hw.nchan; i++) { - pc300ch_t *chan = &card->chan[i]; - pc300dev_t *d = &chan->d; - hdlc_device *hdlc; - struct net_device *dev; - - chan->card = card; - chan->channel = i; - chan->conf.phys_settings.clock_rate = 0; - chan->conf.phys_settings.clock_type = CLOCK_EXT; - chan->conf.proto_settings.encoding = ENCODING_NRZ; - chan->conf.proto_settings.parity = PARITY_CRC16_PR1_CCITT; - switch (card->hw.type) { - case PC300_TE: - chan->conf.media = IF_IFACE_T1; - chan->conf.lcode = PC300_LC_B8ZS; - chan->conf.fr_mode = PC300_FR_ESF; - chan->conf.lbo = PC300_LBO_0_DB; - chan->conf.rx_sens = PC300_RX_SENS_SH; - chan->conf.tslot_bitmap = 0xffffffffUL; - break; - - case PC300_X21: - chan->conf.media = IF_IFACE_X21; - break; - - case PC300_RSV: - default: - chan->conf.media = IF_IFACE_V35; - break; - } - chan->conf.proto = IF_PROTO_PPP; - chan->tx_first_bd = 0; - chan->tx_next_bd = 0; - chan->rx_first_bd = 0; - chan->rx_last_bd = N_DMA_RX_BUF - 1; - chan->nfree_tx_bd = N_DMA_TX_BUF; - - d->chan = chan; - d->trace_on = 0; - d->line_on = 0; - d->line_off = 0; - - dev = alloc_hdlcdev(d); - if (dev == NULL) - continue; - - hdlc = dev_to_hdlc(dev); - hdlc->xmit = cpc_queue_xmit; - hdlc->attach = cpc_attach; - d->dev = dev; - dev->mem_start = card->hw.ramphys; - dev->mem_end = card->hw.ramphys + card->hw.ramsize - 1; - dev->irq = card->hw.irq; - dev->tx_queue_len = PC300_TX_QUEUE_LEN; - dev->mtu = PC300_DEF_MTU; - - dev->netdev_ops = &cpc_netdev_ops; - dev->watchdog_timeo = PC300_TX_TIMEOUT; - - if (register_hdlc_device(dev) == 0) { - printk("%s: Cyclades-PC300/", dev->name); - switch (card->hw.type) { - case PC300_TE: - if (card->hw.bus == PC300_PMC) { - printk("TE-M"); - } else { - printk("TE "); - } - break; - - case PC300_X21: - printk("X21 "); - break; - - case PC300_RSV: - default: - printk("RSV "); - break; - } - printk (" #%d, %dKB of RAM at 0x%08x, IRQ%d, channel %d.\n", - board_nbr, card->hw.ramsize / 1024, - card->hw.ramphys, card->hw.irq, i + 1); - devcount++; - } else { - printk ("Dev%d on card(0x%08x): unable to allocate i/f name.\n", - i + 1, card->hw.ramphys); - free_netdev(dev); - continue; - } - } - spin_lock_init(&card->card_lock); - - board_nbr++; -} - -static int __devinit -cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - int err, eeprom_outdated = 0; - u16 device_id; - pc300_t *card; - - if ((err = pci_enable_device(pdev)) < 0) - return err; - - card = kzalloc(sizeof(pc300_t), GFP_KERNEL); - if (card == NULL) { - printk("PC300 found at RAM 0x%016llx, " - "but could not allocate card structure.\n", - (unsigned long long)pci_resource_start(pdev, 3)); - err = -ENOMEM; - goto err_disable_dev; - } - - err = -ENODEV; - - /* read PCI configuration area */ - device_id = ent->device; - card->hw.irq = pdev->irq; - card->hw.iophys = pci_resource_start(pdev, 1); - card->hw.iosize = pci_resource_len(pdev, 1); - card->hw.scaphys = pci_resource_start(pdev, 2); - card->hw.scasize = pci_resource_len(pdev, 2); - card->hw.ramphys = pci_resource_start(pdev, 3); - card->hw.alloc_ramsize = pci_resource_len(pdev, 3); - card->hw.falcphys = pci_resource_start(pdev, 4); - card->hw.falcsize = pci_resource_len(pdev, 4); - card->hw.plxphys = pci_resource_start(pdev, 5); - card->hw.plxsize = pci_resource_len(pdev, 5); - - switch (device_id) { - case PCI_DEVICE_ID_PC300_RX_1: - case PCI_DEVICE_ID_PC300_TE_1: - case PCI_DEVICE_ID_PC300_TE_M_1: - card->hw.nchan = 1; - break; - - case PCI_DEVICE_ID_PC300_RX_2: - case PCI_DEVICE_ID_PC300_TE_2: - case PCI_DEVICE_ID_PC300_TE_M_2: - default: - card->hw.nchan = PC300_MAXCHAN; - break; - } -#ifdef PC300_DEBUG_PCI - printk("cpc (bus=0x0%x,pci_id=0x%x,", pdev->bus->number, pdev->devfn); - printk("rev_id=%d) IRQ%d\n", pdev->revision, card->hw.irq); - printk("cpc:found ramaddr=0x%08lx plxaddr=0x%08lx " - "ctladdr=0x%08lx falcaddr=0x%08lx\n", - card->hw.ramphys, card->hw.plxphys, card->hw.scaphys, - card->hw.falcphys); -#endif - /* Although we don't use this I/O region, we should - * request it from the kernel anyway, to avoid problems - * with other drivers accessing it. */ - if (!request_region(card->hw.iophys, card->hw.iosize, "PLX Registers")) { - /* In case we can't allocate it, warn user */ - printk("WARNING: couldn't allocate I/O region for PC300 board " - "at 0x%08x!\n", card->hw.ramphys); - } - - if (card->hw.plxphys) { - pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, card->hw.plxphys); - } else { - eeprom_outdated = 1; - card->hw.plxphys = pci_resource_start(pdev, 0); - card->hw.plxsize = pci_resource_len(pdev, 0); - } - - if (!request_mem_region(card->hw.plxphys, card->hw.plxsize, - "PLX Registers")) { - printk("PC300 found at RAM 0x%08x, " - "but could not allocate PLX mem region.\n", - card->hw.ramphys); - goto err_release_io; - } - if (!request_mem_region(card->hw.ramphys, card->hw.alloc_ramsize, - "On-board RAM")) { - printk("PC300 found at RAM 0x%08x, " - "but could not allocate RAM mem region.\n", - card->hw.ramphys); - goto err_release_plx; - } - if (!request_mem_region(card->hw.scaphys, card->hw.scasize, - "SCA-II Registers")) { - printk("PC300 found at RAM 0x%08x, " - "but could not allocate SCA mem region.\n", - card->hw.ramphys); - goto err_release_ram; - } - - card->hw.plxbase = ioremap(card->hw.plxphys, card->hw.plxsize); - card->hw.rambase = ioremap(card->hw.ramphys, card->hw.alloc_ramsize); - card->hw.scabase = ioremap(card->hw.scaphys, card->hw.scasize); - switch (device_id) { - case PCI_DEVICE_ID_PC300_TE_1: - case PCI_DEVICE_ID_PC300_TE_2: - case PCI_DEVICE_ID_PC300_TE_M_1: - case PCI_DEVICE_ID_PC300_TE_M_2: - request_mem_region(card->hw.falcphys, card->hw.falcsize, - "FALC Registers"); - card->hw.falcbase = ioremap(card->hw.falcphys, card->hw.falcsize); - break; - - case PCI_DEVICE_ID_PC300_RX_1: - case PCI_DEVICE_ID_PC300_RX_2: - default: - card->hw.falcbase = NULL; - break; - } - -#ifdef PC300_DEBUG_PCI - printk("cpc: relocate ramaddr=0x%08lx plxaddr=0x%08lx " - "ctladdr=0x%08lx falcaddr=0x%08lx\n", - card->hw.rambase, card->hw.plxbase, card->hw.scabase, - card->hw.falcbase); -#endif - - /* Set PCI drv pointer to the card structure */ - pci_set_drvdata(pdev, card); - - /* Set board type */ - switch (device_id) { - case PCI_DEVICE_ID_PC300_TE_1: - case PCI_DEVICE_ID_PC300_TE_2: - case PCI_DEVICE_ID_PC300_TE_M_1: - case PCI_DEVICE_ID_PC300_TE_M_2: - card->hw.type = PC300_TE; - - if ((device_id == PCI_DEVICE_ID_PC300_TE_M_1) || - (device_id == PCI_DEVICE_ID_PC300_TE_M_2)) { - card->hw.bus = PC300_PMC; - /* Set PLX register offsets */ - card->hw.gpioc_reg = 0x54; - card->hw.intctl_reg = 0x4c; - } else { - card->hw.bus = PC300_PCI; - /* Set PLX register offsets */ - card->hw.gpioc_reg = 0x50; - card->hw.intctl_reg = 0x4c; - } - break; - - case PCI_DEVICE_ID_PC300_RX_1: - case PCI_DEVICE_ID_PC300_RX_2: - default: - card->hw.bus = PC300_PCI; - /* Set PLX register offsets */ - card->hw.gpioc_reg = 0x50; - card->hw.intctl_reg = 0x4c; - - if ((cpc_readl(card->hw.plxbase + card->hw.gpioc_reg) & PC300_CTYPE_MASK)) { - card->hw.type = PC300_X21; - } else { - card->hw.type = PC300_RSV; - } - break; - } - - /* Allocate IRQ */ - if (request_irq(card->hw.irq, cpc_intr, IRQF_SHARED, "Cyclades-PC300", card)) { - printk ("PC300 found at RAM 0x%08x, but could not allocate IRQ%d.\n", - card->hw.ramphys, card->hw.irq); - goto err_io_unmap; - } - - cpc_init_card(card); - - if (eeprom_outdated) - printk("WARNING: PC300 with outdated EEPROM.\n"); - return 0; - -err_io_unmap: - iounmap(card->hw.plxbase); - iounmap(card->hw.scabase); - iounmap(card->hw.rambase); - if (card->hw.type == PC300_TE) { - iounmap(card->hw.falcbase); - release_mem_region(card->hw.falcphys, card->hw.falcsize); - } - release_mem_region(card->hw.scaphys, card->hw.scasize); -err_release_ram: - release_mem_region(card->hw.ramphys, card->hw.alloc_ramsize); -err_release_plx: - release_mem_region(card->hw.plxphys, card->hw.plxsize); -err_release_io: - release_region(card->hw.iophys, card->hw.iosize); - kfree(card); -err_disable_dev: - pci_disable_device(pdev); - return err; -} - -static void __devexit cpc_remove_one(struct pci_dev *pdev) -{ - pc300_t *card = pci_get_drvdata(pdev); - - if (card->hw.rambase) { - int i; - - /* Disable interrupts on the PCI bridge */ - cpc_writew(card->hw.plxbase + card->hw.intctl_reg, - cpc_readw(card->hw.plxbase + card->hw.intctl_reg) & ~(0x0040)); - - for (i = 0; i < card->hw.nchan; i++) { - unregister_hdlc_device(card->chan[i].d.dev); - } - iounmap(card->hw.plxbase); - iounmap(card->hw.scabase); - iounmap(card->hw.rambase); - release_mem_region(card->hw.plxphys, card->hw.plxsize); - release_mem_region(card->hw.ramphys, card->hw.alloc_ramsize); - release_mem_region(card->hw.scaphys, card->hw.scasize); - release_region(card->hw.iophys, card->hw.iosize); - if (card->hw.type == PC300_TE) { - iounmap(card->hw.falcbase); - release_mem_region(card->hw.falcphys, card->hw.falcsize); - } - for (i = 0; i < card->hw.nchan; i++) - if (card->chan[i].d.dev) - free_netdev(card->chan[i].d.dev); - if (card->hw.irq) - free_irq(card->hw.irq, card); - kfree(card); - pci_disable_device(pdev); - } -} - -static struct pci_driver cpc_driver = { - .name = "pc300", - .id_table = cpc_pci_dev_id, - .probe = cpc_init_one, - .remove = __devexit_p(cpc_remove_one), -}; - -static int __init cpc_init(void) -{ - show_version(); - return pci_register_driver(&cpc_driver); -} - -static void __exit cpc_cleanup_module(void) -{ - pci_unregister_driver(&cpc_driver); -} - -module_init(cpc_init); -module_exit(cpc_cleanup_module); - -MODULE_DESCRIPTION("Cyclades-PC300 cards driver"); -MODULE_AUTHOR( "Author: Ivan Passos \r\n" - "Maintainer: PC300 Maintainer - * - * Copyright: (c) 1999-2002 Cyclades Corp. - * - * 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. - * - * $Log: pc300_tty.c,v $ - * Revision 3.7 2002/03/07 14:17:09 henrique - * License data fixed - * - * Revision 3.6 2001/12/10 12:29:42 regina - * Fix the MLPPP bug - * - * Revision 3.5 2001/10/31 11:20:05 regina - * automatic pppd starts - * - * Revision 3.4 2001/08/06 12:01:51 regina - * problem in DSR_DE bit - * - * Revision 3.3 2001/07/26 22:58:41 regina - * update EDA value - * - * Revision 3.2 2001/07/12 13:11:20 regina - * bug fix - DCD-OFF in pc300 tty driver - * - * DMA transmission bug fix - * - * Revision 3.1 2001/06/22 13:13:02 regina - * MLPPP implementation - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -/* TTY includes */ -#include -#include -#include - -#include -#include - -#include "pc300.h" - -/* defines and macros */ -/* TTY Global definitions */ -#define CPC_TTY_NPORTS 8 /* maximum number of the sync tty connections */ -#define CPC_TTY_MAJOR CYCLADES_MAJOR -#define CPC_TTY_MINOR_START 240 /* minor of the first PC300 interface */ - -#define CPC_TTY_MAX_MTU 2000 - -/* tty interface state */ -#define CPC_TTY_ST_IDLE 0 -#define CPC_TTY_ST_INIT 1 /* configured with MLPPP and up */ -#define CPC_TTY_ST_OPEN 2 /* opened by application */ - -#define CPC_TTY_LOCK(card,flags)\ - do {\ - spin_lock_irqsave(&card->card_lock, flags); \ - } while (0) - -#define CPC_TTY_UNLOCK(card,flags) \ - do {\ - spin_unlock_irqrestore(&card->card_lock, flags); \ - } while (0) - -//#define CPC_TTY_DBG(format,a...) printk(format,##a) -#define CPC_TTY_DBG(format,a...) - -/* data structures */ -typedef struct _st_cpc_rx_buf { - struct _st_cpc_rx_buf *next; - int size; - unsigned char data[1]; -} st_cpc_rx_buf; - -struct st_cpc_rx_list { - st_cpc_rx_buf *first; - st_cpc_rx_buf *last; -}; - -typedef struct _st_cpc_tty_area { - int state; /* state of the TTY interface */ - int num_open; - unsigned int tty_minor; /* minor this interface */ - volatile struct st_cpc_rx_list buf_rx; /* ptr. to reception buffer */ - unsigned char* buf_tx; /* ptr. to transmission buffer */ - pc300dev_t* pc300dev; /* ptr. to info struct in PC300 driver */ - unsigned char name[20]; /* interf. name + "-tty" */ - struct tty_struct *tty; - struct work_struct tty_tx_work; /* tx work - tx interrupt */ - struct work_struct tty_rx_work; /* rx work - rx interrupt */ - } st_cpc_tty_area; - -/* TTY data structures */ -static struct tty_driver serial_drv; - -/* local variables */ -static st_cpc_tty_area cpc_tty_area[CPC_TTY_NPORTS]; - -static int cpc_tty_cnt = 0; /* number of intrfaces configured with MLPPP */ -static int cpc_tty_unreg_flag = 0; - -/* TTY functions prototype */ -static int cpc_tty_open(struct tty_struct *tty, struct file *flip); -static void cpc_tty_close(struct tty_struct *tty, struct file *flip); -static int cpc_tty_write(struct tty_struct *tty, const unsigned char *buf, int count); -static int cpc_tty_write_room(struct tty_struct *tty); -static int cpc_tty_chars_in_buffer(struct tty_struct *tty); -static void cpc_tty_flush_buffer(struct tty_struct *tty); -static void cpc_tty_hangup(struct tty_struct *tty); -static void cpc_tty_rx_work(struct work_struct *work); -static void cpc_tty_tx_work(struct work_struct *work); -static int cpc_tty_send_to_card(pc300dev_t *dev,void *buf, int len); -static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx); -static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char); -static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char); - -static int pc300_tiocmset(struct tty_struct *, unsigned int, unsigned int); -static int pc300_tiocmget(struct tty_struct *); - -/* functions called by PC300 driver */ -void cpc_tty_init(pc300dev_t *dev); -void cpc_tty_unregister_service(pc300dev_t *pc300dev); -void cpc_tty_receive(pc300dev_t *pc300dev); -void cpc_tty_trigger_poll(pc300dev_t *pc300dev); - -/* - * PC300 TTY clear "signal" - */ -static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char signal) -{ - pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; - pc300_t *card = (pc300_t *) pc300chan->card; - int ch = pc300chan->channel; - unsigned long flags; - - CPC_TTY_DBG("%s-tty: Clear signal %x\n", - pc300dev->dev->name, signal); - CPC_TTY_LOCK(card, flags); - cpc_writeb(card->hw.scabase + M_REG(CTL,ch), - cpc_readb(card->hw.scabase+M_REG(CTL,ch))& signal); - CPC_TTY_UNLOCK(card,flags); -} - -/* - * PC300 TTY set "signal" to ON - */ -static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char signal) -{ - pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; - pc300_t *card = (pc300_t *) pc300chan->card; - int ch = pc300chan->channel; - unsigned long flags; - - CPC_TTY_DBG("%s-tty: Set signal %x\n", - pc300dev->dev->name, signal); - CPC_TTY_LOCK(card, flags); - cpc_writeb(card->hw.scabase + M_REG(CTL,ch), - cpc_readb(card->hw.scabase+M_REG(CTL,ch))& ~signal); - CPC_TTY_UNLOCK(card,flags); -} - - -static const struct tty_operations pc300_ops = { - .open = cpc_tty_open, - .close = cpc_tty_close, - .write = cpc_tty_write, - .write_room = cpc_tty_write_room, - .chars_in_buffer = cpc_tty_chars_in_buffer, - .tiocmset = pc300_tiocmset, - .tiocmget = pc300_tiocmget, - .flush_buffer = cpc_tty_flush_buffer, - .hangup = cpc_tty_hangup, -}; - - -/* - * PC300 TTY initialization routine - * - * This routine is called by the PC300 driver during board configuration - * (ioctl=SIOCSP300CONF). At this point the adapter is completely - * initialized. - * o verify kernel version (only 2.4.x) - * o register TTY driver - * o init cpc_tty_area struct - */ -void cpc_tty_init(pc300dev_t *pc300dev) -{ - unsigned long port; - int aux; - st_cpc_tty_area * cpc_tty; - - /* hdlcX - X=interface number */ - port = pc300dev->dev->name[4] - '0'; - if (port >= CPC_TTY_NPORTS) { - printk("%s-tty: invalid interface selected (0-%i): %li", - pc300dev->dev->name, - CPC_TTY_NPORTS-1,port); - return; - } - - if (cpc_tty_cnt == 0) { /* first TTY connection -> register driver */ - CPC_TTY_DBG("%s-tty: driver init, major:%i, minor range:%i=%i\n", - pc300dev->dev->name, - CPC_TTY_MAJOR, CPC_TTY_MINOR_START, - CPC_TTY_MINOR_START+CPC_TTY_NPORTS); - /* initialize tty driver struct */ - memset(&serial_drv,0,sizeof(struct tty_driver)); - serial_drv.magic = TTY_DRIVER_MAGIC; - serial_drv.owner = THIS_MODULE; - serial_drv.driver_name = "pc300_tty"; - serial_drv.name = "ttyCP"; - serial_drv.major = CPC_TTY_MAJOR; - serial_drv.minor_start = CPC_TTY_MINOR_START; - serial_drv.num = CPC_TTY_NPORTS; - serial_drv.type = TTY_DRIVER_TYPE_SERIAL; - serial_drv.subtype = SERIAL_TYPE_NORMAL; - - serial_drv.init_termios = tty_std_termios; - serial_drv.init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; - serial_drv.flags = TTY_DRIVER_REAL_RAW; - - /* interface routines from the upper tty layer to the tty driver */ - tty_set_operations(&serial_drv, &pc300_ops); - - /* register the TTY driver */ - if (tty_register_driver(&serial_drv)) { - printk("%s-tty: Failed to register serial driver! ", - pc300dev->dev->name); - return; - } - - memset((void *)cpc_tty_area, 0, - sizeof(st_cpc_tty_area) * CPC_TTY_NPORTS); - } - - cpc_tty = &cpc_tty_area[port]; - - if (cpc_tty->state != CPC_TTY_ST_IDLE) { - CPC_TTY_DBG("%s-tty: TTY port %i, already in use.\n", - pc300dev->dev->name, port); - return; - } - - cpc_tty_cnt++; - cpc_tty->state = CPC_TTY_ST_INIT; - cpc_tty->num_open= 0; - cpc_tty->tty_minor = port + CPC_TTY_MINOR_START; - cpc_tty->pc300dev = pc300dev; - - INIT_WORK(&cpc_tty->tty_tx_work, cpc_tty_tx_work); - INIT_WORK(&cpc_tty->tty_rx_work, cpc_tty_rx_work); - - cpc_tty->buf_rx.first = cpc_tty->buf_rx.last = NULL; - - pc300dev->cpc_tty = (void *)cpc_tty; - - aux = strlen(pc300dev->dev->name); - memcpy(cpc_tty->name, pc300dev->dev->name, aux); - memcpy(&cpc_tty->name[aux], "-tty", 5); - - cpc_open(pc300dev->dev); - cpc_tty_signal_off(pc300dev, CTL_DTR); - - CPC_TTY_DBG("%s: Initializing TTY Sync Driver, tty major#%d minor#%i\n", - cpc_tty->name,CPC_TTY_MAJOR,cpc_tty->tty_minor); - return; -} - -/* - * PC300 TTY OPEN routine - * - * This routine is called by the tty driver to open the interface - * o verify minor - * o allocate buffer to Rx and Tx - */ -static int cpc_tty_open(struct tty_struct *tty, struct file *flip) -{ - int port ; - st_cpc_tty_area *cpc_tty; - - if (!tty) { - return -ENODEV; - } - - port = tty->index; - - if ((port < 0) || (port >= CPC_TTY_NPORTS)){ - CPC_TTY_DBG("pc300_tty: open invalid port %d\n", port); - return -ENODEV; - } - - cpc_tty = &cpc_tty_area[port]; - - if (cpc_tty->state == CPC_TTY_ST_IDLE){ - CPC_TTY_DBG("%s: open - invalid interface, port=%d\n", - cpc_tty->name, tty->index); - return -ENODEV; - } - - if (cpc_tty->num_open == 0) { /* first open of this tty */ - if (!cpc_tty_area[port].buf_tx){ - cpc_tty_area[port].buf_tx = kmalloc(CPC_TTY_MAX_MTU,GFP_KERNEL); - if (!cpc_tty_area[port].buf_tx) { - CPC_TTY_DBG("%s: error in memory allocation\n",cpc_tty->name); - return -ENOMEM; - } - } - - if (cpc_tty_area[port].buf_rx.first) { - unsigned char * aux; - while (cpc_tty_area[port].buf_rx.first) { - aux = (unsigned char *)cpc_tty_area[port].buf_rx.first; - cpc_tty_area[port].buf_rx.first = cpc_tty_area[port].buf_rx.first->next; - kfree(aux); - } - cpc_tty_area[port].buf_rx.first = NULL; - cpc_tty_area[port].buf_rx.last = NULL; - } - - cpc_tty_area[port].state = CPC_TTY_ST_OPEN; - cpc_tty_area[port].tty = tty; - tty->driver_data = &cpc_tty_area[port]; - - cpc_tty_signal_on(cpc_tty->pc300dev, CTL_DTR); - } - - cpc_tty->num_open++; - - CPC_TTY_DBG("%s: opening TTY driver\n", cpc_tty->name); - - /* avisar driver PC300 */ - return 0; -} - -/* - * PC300 TTY CLOSE routine - * - * This routine is called by the tty driver to close the interface - * o call close channel in PC300 driver (cpc_closech) - * o free Rx and Tx buffers - */ - -static void cpc_tty_close(struct tty_struct *tty, struct file *flip) -{ - st_cpc_tty_area *cpc_tty; - unsigned long flags; - int res; - - if (!tty || !tty->driver_data ) { - CPC_TTY_DBG("hdlx-tty: no TTY in close\n"); - return; - } - - cpc_tty = (st_cpc_tty_area *) tty->driver_data; - - if ((cpc_tty->tty != tty)|| (cpc_tty->state != CPC_TTY_ST_OPEN)) { - CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name); - return; - } - - if (!cpc_tty->num_open) { - CPC_TTY_DBG("%s: TTY is closed\n",cpc_tty->name); - return; - } - - if (--cpc_tty->num_open > 0) { - CPC_TTY_DBG("%s: TTY closed\n",cpc_tty->name); - return; - } - - cpc_tty_signal_off(cpc_tty->pc300dev, CTL_DTR); - - CPC_TTY_LOCK(cpc_tty->pc300dev->chan->card, flags); /* lock irq */ - cpc_tty->tty = NULL; - cpc_tty->state = CPC_TTY_ST_INIT; - CPC_TTY_UNLOCK(cpc_tty->pc300dev->chan->card, flags); /* unlock irq */ - - if (cpc_tty->buf_rx.first) { - unsigned char * aux; - while (cpc_tty->buf_rx.first) { - aux = (unsigned char *)cpc_tty->buf_rx.first; - cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next; - kfree(aux); - } - cpc_tty->buf_rx.first = NULL; - cpc_tty->buf_rx.last = NULL; - } - - kfree(cpc_tty->buf_tx); - cpc_tty->buf_tx = NULL; - - CPC_TTY_DBG("%s: TTY closed\n",cpc_tty->name); - - if (!serial_drv.refcount && cpc_tty_unreg_flag) { - cpc_tty_unreg_flag = 0; - CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name); - if ((res=tty_unregister_driver(&serial_drv))) { - CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n", - cpc_tty->name,res); - } - } - return; -} - -/* - * PC300 TTY WRITE routine - * - * This routine is called by the tty driver to write a series of characters - * to the tty device. The characters may come from user or kernel space. - * o verify the DCD signal - * o send characters to board and start the transmission - */ -static int cpc_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) -{ - st_cpc_tty_area *cpc_tty; - pc300ch_t *pc300chan; - pc300_t *card; - int ch; - unsigned long flags; - struct net_device_stats *stats; - - if (!tty || !tty->driver_data ) { - CPC_TTY_DBG("hdlcX-tty: no TTY in write\n"); - return -ENODEV; - } - - cpc_tty = (st_cpc_tty_area *) tty->driver_data; - - if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { - CPC_TTY_DBG("%s: TTY is not opened\n", cpc_tty->name); - return -ENODEV; - } - - if (count > CPC_TTY_MAX_MTU) { - CPC_TTY_DBG("%s: count is invalid\n",cpc_tty->name); - return -EINVAL; /* frame too big */ - } - - CPC_TTY_DBG("%s: cpc_tty_write data len=%i\n",cpc_tty->name,count); - - pc300chan = (pc300ch_t *)((pc300dev_t*)cpc_tty->pc300dev)->chan; - stats = &cpc_tty->pc300dev->dev->stats; - card = (pc300_t *) pc300chan->card; - ch = pc300chan->channel; - - /* verify DCD signal*/ - if (cpc_readb(card->hw.scabase + M_REG(ST3,ch)) & ST3_DCD) { - /* DCD is OFF */ - CPC_TTY_DBG("%s : DCD is OFF\n", cpc_tty->name); - stats->tx_errors++; - stats->tx_carrier_errors++; - CPC_TTY_LOCK(card, flags); - cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_BUF_CLR); - - if (card->hw.type == PC300_TE) { - cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, - cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) & - ~(CPLD_REG2_FALC_LED1 << (2 *ch))); - } - - CPC_TTY_UNLOCK(card, flags); - - return -EINVAL; - } - - if (cpc_tty_send_to_card(cpc_tty->pc300dev, (void*)buf, count)) { - /* failed to send */ - CPC_TTY_DBG("%s: trasmition error\n", cpc_tty->name); - return 0; - } - return count; -} - -/* - * PC300 TTY Write Room routine - * - * This routine returns the numbers of characteres the tty driver will accept - * for queuing to be written. - * o return MTU - */ -static int cpc_tty_write_room(struct tty_struct *tty) -{ - st_cpc_tty_area *cpc_tty; - - if (!tty || !tty->driver_data ) { - CPC_TTY_DBG("hdlcX-tty: no TTY to write room\n"); - return -ENODEV; - } - - cpc_tty = (st_cpc_tty_area *) tty->driver_data; - - if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { - CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name); - return -ENODEV; - } - - CPC_TTY_DBG("%s: write room\n",cpc_tty->name); - - return CPC_TTY_MAX_MTU; -} - -/* - * PC300 TTY chars in buffer routine - * - * This routine returns the chars number in the transmission buffer - * o returns 0 - */ -static int cpc_tty_chars_in_buffer(struct tty_struct *tty) -{ - st_cpc_tty_area *cpc_tty; - - if (!tty || !tty->driver_data ) { - CPC_TTY_DBG("hdlcX-tty: no TTY to chars in buffer\n"); - return -ENODEV; - } - - cpc_tty = (st_cpc_tty_area *) tty->driver_data; - - if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { - CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name); - return -ENODEV; - } - - return 0; -} - -static int pc300_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - st_cpc_tty_area *cpc_tty; - - CPC_TTY_DBG("%s: set:%x clear:%x\n", __func__, set, clear); - - if (!tty || !tty->driver_data ) { - CPC_TTY_DBG("hdlcX-tty: no TTY to chars in buffer\n"); - return -ENODEV; - } - - cpc_tty = (st_cpc_tty_area *) tty->driver_data; - - if (set & TIOCM_RTS) - cpc_tty_signal_on(cpc_tty->pc300dev, CTL_RTS); - if (set & TIOCM_DTR) - cpc_tty_signal_on(cpc_tty->pc300dev, CTL_DTR); - - if (clear & TIOCM_RTS) - cpc_tty_signal_off(cpc_tty->pc300dev, CTL_RTS); - if (clear & TIOCM_DTR) - cpc_tty_signal_off(cpc_tty->pc300dev, CTL_DTR); - - return 0; -} - -static int pc300_tiocmget(struct tty_struct *tty) -{ - unsigned int result; - unsigned char status; - unsigned long flags; - st_cpc_tty_area *cpc_tty = (st_cpc_tty_area *) tty->driver_data; - pc300dev_t *pc300dev = cpc_tty->pc300dev; - pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; - pc300_t *card = (pc300_t *) pc300chan->card; - int ch = pc300chan->channel; - - cpc_tty = (st_cpc_tty_area *) tty->driver_data; - - CPC_TTY_DBG("%s-tty: tiocmget\n", - ((struct net_device*)(pc300dev->hdlc))->name); - - CPC_TTY_LOCK(card, flags); - status = cpc_readb(card->hw.scabase+M_REG(CTL,ch)); - CPC_TTY_UNLOCK(card,flags); - - result = ((status & CTL_DTR) ? TIOCM_DTR : 0) | - ((status & CTL_RTS) ? TIOCM_RTS : 0); - - return result; -} - -/* - * PC300 TTY Flush Buffer routine - * - * This routine resets the transmission buffer - */ -static void cpc_tty_flush_buffer(struct tty_struct *tty) -{ - st_cpc_tty_area *cpc_tty; - - if (!tty || !tty->driver_data ) { - CPC_TTY_DBG("hdlcX-tty: no TTY to flush buffer\n"); - return; - } - - cpc_tty = (st_cpc_tty_area *) tty->driver_data; - - if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { - CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name); - return; - } - - CPC_TTY_DBG("%s: call wake_up_interruptible\n",cpc_tty->name); - - tty_wakeup(tty); - return; -} - -/* - * PC300 TTY Hangup routine - * - * This routine is called by the tty driver to hangup the interface - * o clear DTR signal - */ - -static void cpc_tty_hangup(struct tty_struct *tty) -{ - st_cpc_tty_area *cpc_tty; - int res; - - if (!tty || !tty->driver_data ) { - CPC_TTY_DBG("hdlcX-tty: no TTY to hangup\n"); - return ; - } - - cpc_tty = (st_cpc_tty_area *) tty->driver_data; - - if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { - CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name); - return ; - } - if (!serial_drv.refcount && cpc_tty_unreg_flag) { - cpc_tty_unreg_flag = 0; - CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name); - if ((res=tty_unregister_driver(&serial_drv))) { - CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n", - cpc_tty->name,res); - } - } - cpc_tty_signal_off(cpc_tty->pc300dev, CTL_DTR); -} - -/* - * PC300 TTY RX work routine - * This routine treats RX work - * o verify read buffer - * o call the line disc. read - * o free memory - */ -static void cpc_tty_rx_work(struct work_struct *work) -{ - st_cpc_tty_area *cpc_tty; - unsigned long port; - int i, j; - volatile st_cpc_rx_buf *buf; - char flags=0,flg_rx=1; - struct tty_ldisc *ld; - - if (cpc_tty_cnt == 0) return; - - for (i=0; (i < 4) && flg_rx ; i++) { - flg_rx = 0; - - cpc_tty = container_of(work, st_cpc_tty_area, tty_rx_work); - port = cpc_tty - cpc_tty_area; - - for (j=0; j < CPC_TTY_NPORTS; j++) { - cpc_tty = &cpc_tty_area[port]; - - if ((buf=cpc_tty->buf_rx.first) != NULL) { - if (cpc_tty->tty) { - ld = tty_ldisc_ref(cpc_tty->tty); - if (ld) { - if (ld->ops->receive_buf) { - CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name); - ld->ops->receive_buf(cpc_tty->tty, (char *)(buf->data), &flags, buf->size); - } - tty_ldisc_deref(ld); - } - } - cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next; - kfree((void *)buf); - buf = cpc_tty->buf_rx.first; - flg_rx = 1; - } - if (++port == CPC_TTY_NPORTS) port = 0; - } - } -} - -/* - * PC300 TTY RX work routine - * - * This routine treats RX interrupt. - * o read all frames in card - * o verify the frame size - * o read the frame in rx buffer - */ -static void cpc_tty_rx_disc_frame(pc300ch_t *pc300chan) -{ - volatile pcsca_bd_t __iomem * ptdescr; - volatile unsigned char status; - pc300_t *card = (pc300_t *)pc300chan->card; - int ch = pc300chan->channel; - - /* dma buf read */ - ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + - RX_BD_ADDR(ch, pc300chan->rx_first_bd)); - while (pc300chan->rx_first_bd != pc300chan->rx_last_bd) { - status = cpc_readb(&ptdescr->status); - cpc_writeb(&ptdescr->status, 0); - cpc_writeb(&ptdescr->len, 0); - pc300chan->rx_first_bd = (pc300chan->rx_first_bd + 1) & - (N_DMA_RX_BUF - 1); - if (status & DST_EOM) { - break; /* end of message */ - } - ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + cpc_readl(&ptdescr->next)); - } -} - -void cpc_tty_receive(pc300dev_t *pc300dev) -{ - st_cpc_tty_area *cpc_tty; - pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; - pc300_t *card = (pc300_t *)pc300chan->card; - int ch = pc300chan->channel; - volatile pcsca_bd_t __iomem * ptdescr; - struct net_device_stats *stats = &pc300dev->dev->stats; - int rx_len, rx_aux; - volatile unsigned char status; - unsigned short first_bd = pc300chan->rx_first_bd; - st_cpc_rx_buf *new = NULL; - unsigned char dsr_rx; - - if (pc300dev->cpc_tty == NULL) { - return; - } - - dsr_rx = cpc_readb(card->hw.scabase + DSR_RX(ch)); - - cpc_tty = pc300dev->cpc_tty; - - while (1) { - rx_len = 0; - ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + RX_BD_ADDR(ch, first_bd)); - while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) { - rx_len += cpc_readw(&ptdescr->len); - first_bd = (first_bd + 1) & (N_DMA_RX_BUF - 1); - if (status & DST_EOM) { - break; - } - ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase+cpc_readl(&ptdescr->next)); - } - - if (!rx_len) { - if (dsr_rx & DSR_BOF) { - /* update EDA */ - cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), - RX_BD_ADDR(ch, pc300chan->rx_last_bd)); - } - kfree(new); - return; - } - - if (rx_len > CPC_TTY_MAX_MTU) { - /* Free RX descriptors */ - CPC_TTY_DBG("%s: frame size is invalid.\n",cpc_tty->name); - stats->rx_errors++; - stats->rx_frame_errors++; - cpc_tty_rx_disc_frame(pc300chan); - continue; - } - - new = kmalloc(rx_len + sizeof(st_cpc_rx_buf), GFP_ATOMIC); - if (!new) { - cpc_tty_rx_disc_frame(pc300chan); - continue; - } - - /* dma buf read */ - ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + - RX_BD_ADDR(ch, pc300chan->rx_first_bd)); - - rx_len = 0; /* counter frame size */ - - while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) { - rx_aux = cpc_readw(&ptdescr->len); - if ((status & (DST_OVR | DST_CRC | DST_RBIT | DST_SHRT | DST_ABT)) - || (rx_aux > BD_DEF_LEN)) { - CPC_TTY_DBG("%s: reception error\n", cpc_tty->name); - stats->rx_errors++; - if (status & DST_OVR) { - stats->rx_fifo_errors++; - } - if (status & DST_CRC) { - stats->rx_crc_errors++; - } - if ((status & (DST_RBIT | DST_SHRT | DST_ABT)) || - (rx_aux > BD_DEF_LEN)) { - stats->rx_frame_errors++; - } - /* discard remainig descriptors used by the bad frame */ - CPC_TTY_DBG("%s: reception error - discard descriptors", - cpc_tty->name); - cpc_tty_rx_disc_frame(pc300chan); - rx_len = 0; - kfree(new); - new = NULL; - break; /* read next frame - while(1) */ - } - - if (cpc_tty->state != CPC_TTY_ST_OPEN) { - /* Free RX descriptors */ - cpc_tty_rx_disc_frame(pc300chan); - stats->rx_dropped++; - rx_len = 0; - kfree(new); - new = NULL; - break; /* read next frame - while(1) */ - } - - /* read the segment of the frame */ - if (rx_aux != 0) { - memcpy_fromio((new->data + rx_len), - (void __iomem *)(card->hw.rambase + - cpc_readl(&ptdescr->ptbuf)), rx_aux); - rx_len += rx_aux; - } - cpc_writeb(&ptdescr->status,0); - cpc_writeb(&ptdescr->len, 0); - pc300chan->rx_first_bd = (pc300chan->rx_first_bd + 1) & - (N_DMA_RX_BUF -1); - if (status & DST_EOM)break; - - ptdescr = (pcsca_bd_t __iomem *) (card->hw.rambase + - cpc_readl(&ptdescr->next)); - } - /* update pointer */ - pc300chan->rx_last_bd = (pc300chan->rx_first_bd - 1) & - (N_DMA_RX_BUF - 1) ; - if (!(dsr_rx & DSR_BOF)) { - /* update EDA */ - cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), - RX_BD_ADDR(ch, pc300chan->rx_last_bd)); - } - if (rx_len != 0) { - stats->rx_bytes += rx_len; - - if (pc300dev->trace_on) { - cpc_tty_trace(pc300dev, new->data,rx_len, 'R'); - } - new->size = rx_len; - new->next = NULL; - if (cpc_tty->buf_rx.first == NULL) { - cpc_tty->buf_rx.first = new; - cpc_tty->buf_rx.last = new; - } else { - cpc_tty->buf_rx.last->next = new; - cpc_tty->buf_rx.last = new; - } - schedule_work(&(cpc_tty->tty_rx_work)); - stats->rx_packets++; - } - } -} - -/* - * PC300 TTY TX work routine - * - * This routine treats TX interrupt. - * o if need call line discipline wakeup - * o call wake_up_interruptible - */ -static void cpc_tty_tx_work(struct work_struct *work) -{ - st_cpc_tty_area *cpc_tty = - container_of(work, st_cpc_tty_area, tty_tx_work); - struct tty_struct *tty; - - CPC_TTY_DBG("%s: cpc_tty_tx_work init\n",cpc_tty->name); - - if ((tty = cpc_tty->tty) == NULL) { - CPC_TTY_DBG("%s: the interface is not opened\n",cpc_tty->name); - return; - } - tty_wakeup(tty); -} - -/* - * PC300 TTY send to card routine - * - * This routine send data to card. - * o clear descriptors - * o write data to DMA buffers - * o start the transmission - */ -static int cpc_tty_send_to_card(pc300dev_t *dev,void* buf, int len) -{ - pc300ch_t *chan = (pc300ch_t *)dev->chan; - pc300_t *card = (pc300_t *)chan->card; - int ch = chan->channel; - struct net_device_stats *stats = &dev->dev->stats; - unsigned long flags; - volatile pcsca_bd_t __iomem *ptdescr; - int i, nchar; - int tosend = len; - int nbuf = ((len - 1)/BD_DEF_LEN) + 1; - unsigned char *pdata=buf; - - CPC_TTY_DBG("%s:cpc_tty_send_to_cars len=%i", - (st_cpc_tty_area *)dev->cpc_tty->name,len); - - if (nbuf >= card->chan[ch].nfree_tx_bd) { - return 1; - } - - /* write buffer to DMA buffers */ - CPC_TTY_DBG("%s: call dma_buf_write\n", - (st_cpc_tty_area *)dev->cpc_tty->name); - for (i = 0 ; i < nbuf ; i++) { - ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + - TX_BD_ADDR(ch, card->chan[ch].tx_next_bd)); - nchar = (BD_DEF_LEN > tosend) ? tosend : BD_DEF_LEN; - if (cpc_readb(&ptdescr->status) & DST_OSB) { - memcpy_toio((void __iomem *)(card->hw.rambase + - cpc_readl(&ptdescr->ptbuf)), - &pdata[len - tosend], - nchar); - card->chan[ch].nfree_tx_bd--; - if ((i + 1) == nbuf) { - /* This must be the last BD to be used */ - cpc_writeb(&ptdescr->status, DST_EOM); - } else { - cpc_writeb(&ptdescr->status, 0); - } - cpc_writew(&ptdescr->len, nchar); - } else { - CPC_TTY_DBG("%s: error in dma_buf_write\n", - (st_cpc_tty_area *)dev->cpc_tty->name); - stats->tx_dropped++; - return 1; - } - tosend -= nchar; - card->chan[ch].tx_next_bd = - (card->chan[ch].tx_next_bd + 1) & (N_DMA_TX_BUF - 1); - } - - if (dev->trace_on) { - cpc_tty_trace(dev, buf, len,'T'); - } - - /* start transmission */ - CPC_TTY_DBG("%s: start transmission\n", - (st_cpc_tty_area *)dev->cpc_tty->name); - - CPC_TTY_LOCK(card, flags); - cpc_writeb(card->hw.scabase + DTX_REG(EDAL, ch), - TX_BD_ADDR(ch, chan->tx_next_bd)); - cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_ENA); - cpc_writeb(card->hw.scabase + DSR_TX(ch), DSR_DE); - - if (card->hw.type == PC300_TE) { - cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, - cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) | - (CPLD_REG2_FALC_LED1 << (2 * ch))); - } - CPC_TTY_UNLOCK(card, flags); - return 0; -} - -/* - * PC300 TTY trace routine - * - * This routine send trace of connection to application. - * o clear descriptors - * o write data to DMA buffers - * o start the transmission - */ - -static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx) -{ - struct sk_buff *skb; - - if ((skb = dev_alloc_skb(10 + len)) == NULL) { - /* out of memory */ - CPC_TTY_DBG("%s: tty_trace - out of memory\n", dev->dev->name); - return; - } - - skb_put (skb, 10 + len); - skb->dev = dev->dev; - skb->protocol = htons(ETH_P_CUST); - skb_reset_mac_header(skb); - skb->pkt_type = PACKET_HOST; - skb->len = 10 + len; - - skb_copy_to_linear_data(skb, dev->dev->name, 5); - skb->data[5] = '['; - skb->data[6] = rxtx; - skb->data[7] = ']'; - skb->data[8] = ':'; - skb->data[9] = ' '; - skb_copy_to_linear_data_offset(skb, 10, buf, len); - netif_rx(skb); -} - -/* - * PC300 TTY unregister service routine - * - * This routine unregister one interface. - */ -void cpc_tty_unregister_service(pc300dev_t *pc300dev) -{ - st_cpc_tty_area *cpc_tty; - ulong flags; - int res; - - if ((cpc_tty= (st_cpc_tty_area *) pc300dev->cpc_tty) == NULL) { - CPC_TTY_DBG("%s: interface is not TTY\n", pc300dev->dev->name); - return; - } - CPC_TTY_DBG("%s: cpc_tty_unregister_service", cpc_tty->name); - - if (cpc_tty->pc300dev != pc300dev) { - CPC_TTY_DBG("%s: invalid tty ptr=%s\n", - pc300dev->dev->name, cpc_tty->name); - return; - } - - if (--cpc_tty_cnt == 0) { - if (serial_drv.refcount) { - CPC_TTY_DBG("%s: unregister is not possible, refcount=%d", - cpc_tty->name, serial_drv.refcount); - cpc_tty_cnt++; - cpc_tty_unreg_flag = 1; - return; - } else { - CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name); - if ((res=tty_unregister_driver(&serial_drv))) { - CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n", - cpc_tty->name,res); - } - } - } - CPC_TTY_LOCK(pc300dev->chan->card,flags); - cpc_tty->tty = NULL; - CPC_TTY_UNLOCK(pc300dev->chan->card, flags); - cpc_tty->tty_minor = 0; - cpc_tty->state = CPC_TTY_ST_IDLE; -} - -/* - * PC300 TTY trigger poll routine - * This routine is called by pc300driver to treats Tx interrupt. - */ -void cpc_tty_trigger_poll(pc300dev_t *pc300dev) -{ - st_cpc_tty_area *cpc_tty = (st_cpc_tty_area *)pc300dev->cpc_tty; - if (!cpc_tty) { - return; - } - schedule_work(&(cpc_tty->tty_tx_work)); -} diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 4c99b4c..8d406b5 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -120,6 +120,8 @@ source "drivers/staging/nvec/Kconfig" source "drivers/staging/media/Kconfig" +source "drivers/staging/net/Kconfig" + source "drivers/staging/omapdrm/Kconfig" source "drivers/staging/android/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 74662ce..0381958 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_STAGING) += staging.o obj-y += media/ +obj-y += net/ obj-$(CONFIG_ET131X) += et131x/ obj-$(CONFIG_SLICOSS) += slicoss/ obj-$(CONFIG_USBIP_CORE) += usbip/ diff --git a/drivers/staging/net/Kconfig b/drivers/staging/net/Kconfig new file mode 100644 index 0000000..a64e56b --- /dev/null +++ b/drivers/staging/net/Kconfig @@ -0,0 +1,38 @@ +if NETDEVICES + +if WAN + +config PC300 + tristate "Cyclades-PC300 support (RS-232/V.35, X.21, T1/E1 boards)" + depends on HDLC && PCI && BROKEN + ---help--- + This driver is broken because of struct tty_driver change. + + Driver for the Cyclades-PC300 synchronous communication boards. + + These boards provide synchronous serial interfaces to your + Linux box (interfaces currently available are RS-232/V.35, X.21 and + T1/E1). If you wish to support Multilink PPP, please select the + option later and read the file README.mlppp provided by PC300 + package. + + To compile this as a module, choose M here: the module + will be called pc300. + + If unsure, say N. + +config PC300_MLPPP + bool "Cyclades-PC300 MLPPP support" + depends on PC300 && PPP_MULTILINK && PPP_SYNC_TTY && HDLC_PPP + help + Multilink PPP over the PC300 synchronous communication boards. + +comment "Cyclades-PC300 MLPPP support is disabled." + depends on HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP) + +comment "Refer to the file README.mlppp, provided by PC300 package." + depends on HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP) + +endif # WAN + +endif # NETDEVICES diff --git a/drivers/staging/net/Makefile b/drivers/staging/net/Makefile new file mode 100644 index 0000000..0799c43 --- /dev/null +++ b/drivers/staging/net/Makefile @@ -0,0 +1,5 @@ +pc300-y := pc300_drv.o +pc300-$(CONFIG_PC300_MLPPP) += pc300_tty.o +pc300-objs := $(pc300-y) + +obj-$(CONFIG_PC300) += pc300.o diff --git a/drivers/staging/net/TODO b/drivers/staging/net/TODO new file mode 100644 index 0000000..e3446f2 --- /dev/null +++ b/drivers/staging/net/TODO @@ -0,0 +1,5 @@ +PC300 +The driver is very broken and cannot work with the current TTY layer. It is +inevitable to convert it to the new TTY API. + +If no one steps in to adopt the driver, it will be removed in the 3.7 release. diff --git a/drivers/staging/net/pc300-falc-lh.h b/drivers/staging/net/pc300-falc-lh.h new file mode 100644 index 0000000..01ed23c --- /dev/null +++ b/drivers/staging/net/pc300-falc-lh.h @@ -0,0 +1,1238 @@ +/* + * falc.h Description of the Siemens FALC T1/E1 framer. + * + * Author: Ivan Passos + * + * Copyright: (c) 2000-2001 Cyclades Corp. + * + * 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. + * + * $Log: falc-lh.h,v $ + * Revision 3.1 2001/06/15 12:41:10 regina + * upping major version number + * + * Revision 1.1.1.1 2001/06/13 20:24:47 daniela + * PC300 initial CVS version (3.4.0-pre1) + * + * Revision 1.1 2000/05/15 ivan + * Included DJA bits for the LIM2 register. + * + * Revision 1.0 2000/02/22 ivan + * Initial version. + * + */ + +#ifndef _FALC_LH_H +#define _FALC_LH_H + +#define NUM_OF_T1_CHANNELS 24 +#define NUM_OF_E1_CHANNELS 32 + +/*>>>>>>>>>>>>>>>>> FALC Register Bits (Transmit Mode) <<<<<<<<<<<<<<<<<<< */ + +/* CMDR (Command Register) + ---------------- E1 & T1 ------------------------------ */ +#define CMDR_RMC 0x80 +#define CMDR_RRES 0x40 +#define CMDR_XREP 0x20 +#define CMDR_XRES 0x10 +#define CMDR_XHF 0x08 +#define CMDR_XTF 0x04 +#define CMDR_XME 0x02 +#define CMDR_SRES 0x01 + +/* MODE (Mode Register) + ----------------- E1 & T1 ----------------------------- */ +#define MODE_MDS2 0x80 +#define MODE_MDS1 0x40 +#define MODE_MDS0 0x20 +#define MODE_BRAC 0x10 +#define MODE_HRAC 0x08 + +/* IPC (Interrupt Port Configuration) + ----------------- E1 & T1 ----------------------------- */ +#define IPC_VIS 0x80 +#define IPC_SCI 0x04 +#define IPC_IC1 0x02 +#define IPC_IC0 0x01 + +/* CCR1 (Common Configuration Register 1) + ----------------- E1 & T1 ----------------------------- */ +#define CCR1_SFLG 0x80 +#define CCR1_XTS16RA 0x40 +#define CCR1_BRM 0x40 +#define CCR1_CASSYM 0x20 +#define CCR1_EDLX 0x20 +#define CCR1_EITS 0x10 +#define CCR1_ITF 0x08 +#define CCR1_RFT1 0x02 +#define CCR1_RFT0 0x01 + +/* CCR3 (Common Configuration Register 3) + ---------------- E1 & T1 ------------------------------ */ + +#define CCR3_PRE1 0x80 +#define CCR3_PRE0 0x40 +#define CCR3_EPT 0x20 +#define CCR3_RADD 0x10 +#define CCR3_RCRC 0x04 +#define CCR3_XCRC 0x02 + + +/* RTR1-4 (Receive Timeslot Register 1-4) + ---------------- E1 & T1 ------------------------------ */ + +#define RTR1_TS0 0x80 +#define RTR1_TS1 0x40 +#define RTR1_TS2 0x20 +#define RTR1_TS3 0x10 +#define RTR1_TS4 0x08 +#define RTR1_TS5 0x04 +#define RTR1_TS6 0x02 +#define RTR1_TS7 0x01 + +#define RTR2_TS8 0x80 +#define RTR2_TS9 0x40 +#define RTR2_TS10 0x20 +#define RTR2_TS11 0x10 +#define RTR2_TS12 0x08 +#define RTR2_TS13 0x04 +#define RTR2_TS14 0x02 +#define RTR2_TS15 0x01 + +#define RTR3_TS16 0x80 +#define RTR3_TS17 0x40 +#define RTR3_TS18 0x20 +#define RTR3_TS19 0x10 +#define RTR3_TS20 0x08 +#define RTR3_TS21 0x04 +#define RTR3_TS22 0x02 +#define RTR3_TS23 0x01 + +#define RTR4_TS24 0x80 +#define RTR4_TS25 0x40 +#define RTR4_TS26 0x20 +#define RTR4_TS27 0x10 +#define RTR4_TS28 0x08 +#define RTR4_TS29 0x04 +#define RTR4_TS30 0x02 +#define RTR4_TS31 0x01 + + +/* TTR1-4 (Transmit Timeslot Register 1-4) + ---------------- E1 & T1 ------------------------------ */ + +#define TTR1_TS0 0x80 +#define TTR1_TS1 0x40 +#define TTR1_TS2 0x20 +#define TTR1_TS3 0x10 +#define TTR1_TS4 0x08 +#define TTR1_TS5 0x04 +#define TTR1_TS6 0x02 +#define TTR1_TS7 0x01 + +#define TTR2_TS8 0x80 +#define TTR2_TS9 0x40 +#define TTR2_TS10 0x20 +#define TTR2_TS11 0x10 +#define TTR2_TS12 0x08 +#define TTR2_TS13 0x04 +#define TTR2_TS14 0x02 +#define TTR2_TS15 0x01 + +#define TTR3_TS16 0x80 +#define TTR3_TS17 0x40 +#define TTR3_TS18 0x20 +#define TTR3_TS19 0x10 +#define TTR3_TS20 0x08 +#define TTR3_TS21 0x04 +#define TTR3_TS22 0x02 +#define TTR3_TS23 0x01 + +#define TTR4_TS24 0x80 +#define TTR4_TS25 0x40 +#define TTR4_TS26 0x20 +#define TTR4_TS27 0x10 +#define TTR4_TS28 0x08 +#define TTR4_TS29 0x04 +#define TTR4_TS30 0x02 +#define TTR4_TS31 0x01 + + + +/* IMR0-4 (Interrupt Mask Register 0-4) + + ----------------- E1 & T1 ----------------------------- */ + +#define IMR0_RME 0x80 +#define IMR0_RFS 0x40 +#define IMR0_T8MS 0x20 +#define IMR0_ISF 0x20 +#define IMR0_RMB 0x10 +#define IMR0_CASC 0x08 +#define IMR0_RSC 0x08 +#define IMR0_CRC6 0x04 +#define IMR0_CRC4 0x04 +#define IMR0_PDEN 0x02 +#define IMR0_RPF 0x01 + +#define IMR1_CASE 0x80 +#define IMR1_RDO 0x40 +#define IMR1_ALLS 0x20 +#define IMR1_XDU 0x10 +#define IMR1_XMB 0x08 +#define IMR1_XLSC 0x02 +#define IMR1_XPR 0x01 +#define IMR1_LLBSC 0x80 + +#define IMR2_FAR 0x80 +#define IMR2_LFA 0x40 +#define IMR2_MFAR 0x20 +#define IMR2_T400MS 0x10 +#define IMR2_LMFA 0x10 +#define IMR2_AIS 0x08 +#define IMR2_LOS 0x04 +#define IMR2_RAR 0x02 +#define IMR2_RA 0x01 + +#define IMR3_ES 0x80 +#define IMR3_SEC 0x40 +#define IMR3_LMFA16 0x20 +#define IMR3_AIS16 0x10 +#define IMR3_RA16 0x08 +#define IMR3_API 0x04 +#define IMR3_XSLP 0x20 +#define IMR3_XSLN 0x10 +#define IMR3_LLBSC 0x08 +#define IMR3_XRS 0x04 +#define IMR3_SLN 0x02 +#define IMR3_SLP 0x01 + +#define IMR4_LFA 0x80 +#define IMR4_FER 0x40 +#define IMR4_CER 0x20 +#define IMR4_AIS 0x10 +#define IMR4_LOS 0x08 +#define IMR4_CVE 0x04 +#define IMR4_SLIP 0x02 +#define IMR4_EBE 0x01 + +/* FMR0-5 for E1 and T1 (Framer Mode Register ) */ + +#define FMR0_XC1 0x80 +#define FMR0_XC0 0x40 +#define FMR0_RC1 0x20 +#define FMR0_RC0 0x10 +#define FMR0_EXTD 0x08 +#define FMR0_ALM 0x04 +#define E1_FMR0_FRS 0x02 +#define T1_FMR0_FRS 0x08 +#define FMR0_SRAF 0x04 +#define FMR0_EXLS 0x02 +#define FMR0_SIM 0x01 + +#define FMR1_MFCS 0x80 +#define FMR1_AFR 0x40 +#define FMR1_ENSA 0x20 +#define FMR1_CTM 0x80 +#define FMR1_SIGM 0x40 +#define FMR1_EDL 0x20 +#define FMR1_PMOD 0x10 +#define FMR1_XFS 0x08 +#define FMR1_CRC 0x08 +#define FMR1_ECM 0x04 +#define FMR1_IMOD 0x02 +#define FMR1_XAIS 0x01 + +#define FMR2_RFS1 0x80 +#define FMR2_RFS0 0x40 +#define FMR2_MCSP 0x40 +#define FMR2_RTM 0x20 +#define FMR2_SSP 0x20 +#define FMR2_DAIS 0x10 +#define FMR2_SAIS 0x08 +#define FMR2_PLB 0x04 +#define FMR2_AXRA 0x02 +#define FMR2_ALMF 0x01 +#define FMR2_EXZE 0x01 + +#define LOOP_RTM 0x40 +#define LOOP_SFM 0x40 +#define LOOP_ECLB 0x20 +#define LOOP_CLA 0x1f + +/*--------------------- E1 ----------------------------*/ +#define FMR3_XLD 0x20 +#define FMR3_XLU 0x10 + +/*--------------------- T1 ----------------------------*/ +#define FMR4_AIS3 0x80 +#define FMR4_TM 0x40 +#define FMR4_XRA 0x20 +#define FMR4_SSC1 0x10 +#define FMR4_SSC0 0x08 +#define FMR4_AUTO 0x04 +#define FMR4_FM1 0x02 +#define FMR4_FM0 0x01 + +#define FMR5_SRS 0x80 +#define FMR5_EIBR 0x40 +#define FMR5_XLD 0x20 +#define FMR5_XLU 0x10 + + +/* LOOP (Channel Loop Back) + + ------------------ E1 & T1 ---------------------------- */ + +#define LOOP_SFM 0x40 +#define LOOP_ECLB 0x20 +#define LOOP_CLA4 0x10 +#define LOOP_CLA3 0x08 +#define LOOP_CLA2 0x04 +#define LOOP_CLA1 0x02 +#define LOOP_CLA0 0x01 + + + +/* XSW (Transmit Service Word Pulseframe) + + ------------------- E1 --------------------------- */ + +#define XSW_XSIS 0x80 +#define XSW_XTM 0x40 +#define XSW_XRA 0x20 +#define XSW_XY0 0x10 +#define XSW_XY1 0x08 +#define XSW_XY2 0x04 +#define XSW_XY3 0x02 +#define XSW_XY4 0x01 + + +/* XSP (Transmit Spare Bits) + + ------------------- E1 --------------------------- */ + +#define XSP_XAP 0x80 +#define XSP_CASEN 0x40 +#define XSP_TT0 0x20 +#define XSP_EBP 0x10 +#define XSP_AXS 0x08 +#define XSP_XSIF 0x04 +#define XSP_XS13 0x02 +#define XSP_XS15 0x01 + + +/* XC0/1 (Transmit Control 0/1) + ------------------ E1 & T1 ---------------------------- */ + +#define XC0_SA8E 0x80 +#define XC0_SA7E 0x40 +#define XC0_SA6E 0x20 +#define XC0_SA5E 0x10 +#define XC0_SA4E 0x08 +#define XC0_BRM 0x80 +#define XC0_MFBS 0x40 +#define XC0_SFRZ 0x10 +#define XC0_XCO2 0x04 +#define XC0_XCO1 0x02 +#define XC0_XCO0 0x01 + +#define XC1_XTO5 0x20 +#define XC1_XTO4 0x10 +#define XC1_XTO3 0x08 +#define XC1_XTO2 0x04 +#define XC1_XTO1 0x02 +#define XC1_XTO0 0x01 + + +/* RC0/1 (Receive Control 0/1) + ------------------ E1 & T1 ---------------------------- */ + +#define RC0_SICS 0x40 +#define RC0_CRCI 0x20 +#define RC0_XCRCI 0x10 +#define RC0_RDIS 0x08 +#define RC0_RCO2 0x04 +#define RC0_RCO1 0x02 +#define RC0_RCO0 0x01 + +#define RC1_SWD 0x80 +#define RC1_ASY4 0x40 +#define RC1_RRAM 0x40 +#define RC1_RTO5 0x20 +#define RC1_RTO4 0x10 +#define RC1_RTO3 0x08 +#define RC1_RTO2 0x04 +#define RC1_RTO1 0x02 +#define RC1_RTO0 0x01 + + + +/* XPM0-2 (Transmit Pulse Mask 0-2) + --------------------- E1 & T1 ------------------------- */ + +#define XPM0_XP12 0x80 +#define XPM0_XP11 0x40 +#define XPM0_XP10 0x20 +#define XPM0_XP04 0x10 +#define XPM0_XP03 0x08 +#define XPM0_XP02 0x04 +#define XPM0_XP01 0x02 +#define XPM0_XP00 0x01 + +#define XPM1_XP30 0x80 +#define XPM1_XP24 0x40 +#define XPM1_XP23 0x20 +#define XPM1_XP22 0x10 +#define XPM1_XP21 0x08 +#define XPM1_XP20 0x04 +#define XPM1_XP14 0x02 +#define XPM1_XP13 0x01 + +#define XPM2_XLHP 0x80 +#define XPM2_XLT 0x40 +#define XPM2_DAXLT 0x20 +#define XPM2_XP34 0x08 +#define XPM2_XP33 0x04 +#define XPM2_XP32 0x02 +#define XPM2_XP31 0x01 + + +/* TSWM (Transparent Service Word Mask) + ------------------ E1 ---------------------------- */ + +#define TSWM_TSIS 0x80 +#define TSWM_TSIF 0x40 +#define TSWM_TRA 0x20 +#define TSWM_TSA4 0x10 +#define TSWM_TSA5 0x08 +#define TSWM_TSA6 0x04 +#define TSWM_TSA7 0x02 +#define TSWM_TSA8 0x01 + +/* IDLE + + ------------------ E1 & T1 ----------------------- */ + +#define IDLE_IDL7 0x80 +#define IDLE_IDL6 0x40 +#define IDLE_IDL5 0x20 +#define IDLE_IDL4 0x10 +#define IDLE_IDL3 0x08 +#define IDLE_IDL2 0x04 +#define IDLE_IDL1 0x02 +#define IDLE_IDL0 0x01 + + +/* XSA4-8 + -------------------E1 ----------------------------- */ + +#define XSA4_XS47 0x80 +#define XSA4_XS46 0x40 +#define XSA4_XS45 0x20 +#define XSA4_XS44 0x10 +#define XSA4_XS43 0x08 +#define XSA4_XS42 0x04 +#define XSA4_XS41 0x02 +#define XSA4_XS40 0x01 + +#define XSA5_XS57 0x80 +#define XSA5_XS56 0x40 +#define XSA5_XS55 0x20 +#define XSA5_XS54 0x10 +#define XSA5_XS53 0x08 +#define XSA5_XS52 0x04 +#define XSA5_XS51 0x02 +#define XSA5_XS50 0x01 + +#define XSA6_XS67 0x80 +#define XSA6_XS66 0x40 +#define XSA6_XS65 0x20 +#define XSA6_XS64 0x10 +#define XSA6_XS63 0x08 +#define XSA6_XS62 0x04 +#define XSA6_XS61 0x02 +#define XSA6_XS60 0x01 + +#define XSA7_XS77 0x80 +#define XSA7_XS76 0x40 +#define XSA7_XS75 0x20 +#define XSA7_XS74 0x10 +#define XSA7_XS73 0x08 +#define XSA7_XS72 0x04 +#define XSA7_XS71 0x02 +#define XSA7_XS70 0x01 + +#define XSA8_XS87 0x80 +#define XSA8_XS86 0x40 +#define XSA8_XS85 0x20 +#define XSA8_XS84 0x10 +#define XSA8_XS83 0x08 +#define XSA8_XS82 0x04 +#define XSA8_XS81 0x02 +#define XSA8_XS80 0x01 + + +/* XDL1-3 (Transmit DL-Bit Register1-3 (read/write)) + ----------------------- T1 --------------------- */ + +#define XDL1_XDL17 0x80 +#define XDL1_XDL16 0x40 +#define XDL1_XDL15 0x20 +#define XDL1_XDL14 0x10 +#define XDL1_XDL13 0x08 +#define XDL1_XDL12 0x04 +#define XDL1_XDL11 0x02 +#define XDL1_XDL10 0x01 + +#define XDL2_XDL27 0x80 +#define XDL2_XDL26 0x40 +#define XDL2_XDL25 0x20 +#define XDL2_XDL24 0x10 +#define XDL2_XDL23 0x08 +#define XDL2_XDL22 0x04 +#define XDL2_XDL21 0x02 +#define XDL2_XDL20 0x01 + +#define XDL3_XDL37 0x80 +#define XDL3_XDL36 0x40 +#define XDL3_XDL35 0x20 +#define XDL3_XDL34 0x10 +#define XDL3_XDL33 0x08 +#define XDL3_XDL32 0x04 +#define XDL3_XDL31 0x02 +#define XDL3_XDL30 0x01 + + +/* ICB1-4 (Idle Channel Register 1-4) + ------------------ E1 ---------------------------- */ + +#define E1_ICB1_IC0 0x80 +#define E1_ICB1_IC1 0x40 +#define E1_ICB1_IC2 0x20 +#define E1_ICB1_IC3 0x10 +#define E1_ICB1_IC4 0x08 +#define E1_ICB1_IC5 0x04 +#define E1_ICB1_IC6 0x02 +#define E1_ICB1_IC7 0x01 + +#define E1_ICB2_IC8 0x80 +#define E1_ICB2_IC9 0x40 +#define E1_ICB2_IC10 0x20 +#define E1_ICB2_IC11 0x10 +#define E1_ICB2_IC12 0x08 +#define E1_ICB2_IC13 0x04 +#define E1_ICB2_IC14 0x02 +#define E1_ICB2_IC15 0x01 + +#define E1_ICB3_IC16 0x80 +#define E1_ICB3_IC17 0x40 +#define E1_ICB3_IC18 0x20 +#define E1_ICB3_IC19 0x10 +#define E1_ICB3_IC20 0x08 +#define E1_ICB3_IC21 0x04 +#define E1_ICB3_IC22 0x02 +#define E1_ICB3_IC23 0x01 + +#define E1_ICB4_IC24 0x80 +#define E1_ICB4_IC25 0x40 +#define E1_ICB4_IC26 0x20 +#define E1_ICB4_IC27 0x10 +#define E1_ICB4_IC28 0x08 +#define E1_ICB4_IC29 0x04 +#define E1_ICB4_IC30 0x02 +#define E1_ICB4_IC31 0x01 + +/* ICB1-4 (Idle Channel Register 1-4) + ------------------ T1 ---------------------------- */ + +#define T1_ICB1_IC1 0x80 +#define T1_ICB1_IC2 0x40 +#define T1_ICB1_IC3 0x20 +#define T1_ICB1_IC4 0x10 +#define T1_ICB1_IC5 0x08 +#define T1_ICB1_IC6 0x04 +#define T1_ICB1_IC7 0x02 +#define T1_ICB1_IC8 0x01 + +#define T1_ICB2_IC9 0x80 +#define T1_ICB2_IC10 0x40 +#define T1_ICB2_IC11 0x20 +#define T1_ICB2_IC12 0x10 +#define T1_ICB2_IC13 0x08 +#define T1_ICB2_IC14 0x04 +#define T1_ICB2_IC15 0x02 +#define T1_ICB2_IC16 0x01 + +#define T1_ICB3_IC17 0x80 +#define T1_ICB3_IC18 0x40 +#define T1_ICB3_IC19 0x20 +#define T1_ICB3_IC20 0x10 +#define T1_ICB3_IC21 0x08 +#define T1_ICB3_IC22 0x04 +#define T1_ICB3_IC23 0x02 +#define T1_ICB3_IC24 0x01 + +/* FMR3 (Framer Mode Register 3) + --------------------E1------------------------ */ + +#define FMR3_CMI 0x08 +#define FMR3_SYNSA 0x04 +#define FMR3_CFRZ 0x02 +#define FMR3_EXTIW 0x01 + + + +/* CCB1-3 (Clear Channel Register) + ------------------- T1 ----------------------- */ + +#define CCB1_CH1 0x80 +#define CCB1_CH2 0x40 +#define CCB1_CH3 0x20 +#define CCB1_CH4 0x10 +#define CCB1_CH5 0x08 +#define CCB1_CH6 0x04 +#define CCB1_CH7 0x02 +#define CCB1_CH8 0x01 + +#define CCB2_CH9 0x80 +#define CCB2_CH10 0x40 +#define CCB2_CH11 0x20 +#define CCB2_CH12 0x10 +#define CCB2_CH13 0x08 +#define CCB2_CH14 0x04 +#define CCB2_CH15 0x02 +#define CCB2_CH16 0x01 + +#define CCB3_CH17 0x80 +#define CCB3_CH18 0x40 +#define CCB3_CH19 0x20 +#define CCB3_CH20 0x10 +#define CCB3_CH21 0x08 +#define CCB3_CH22 0x04 +#define CCB3_CH23 0x02 +#define CCB3_CH24 0x01 + + +/* LIM0/1 (Line Interface Mode 0/1) + ------------------- E1 & T1 --------------------------- */ + +#define LIM0_XFB 0x80 +#define LIM0_XDOS 0x40 +#define LIM0_SCL1 0x20 +#define LIM0_SCL0 0x10 +#define LIM0_EQON 0x08 +#define LIM0_ELOS 0x04 +#define LIM0_LL 0x02 +#define LIM0_MAS 0x01 + +#define LIM1_EFSC 0x80 +#define LIM1_RIL2 0x40 +#define LIM1_RIL1 0x20 +#define LIM1_RIL0 0x10 +#define LIM1_DCOC 0x08 +#define LIM1_JATT 0x04 +#define LIM1_RL 0x02 +#define LIM1_DRS 0x01 + + +/* PCDR (Pulse Count Detection Register(Read/Write)) + ------------------ E1 & T1 ------------------------- */ + +#define PCDR_PCD7 0x80 +#define PCDR_PCD6 0x40 +#define PCDR_PCD5 0x20 +#define PCDR_PCD4 0x10 +#define PCDR_PCD3 0x08 +#define PCDR_PCD2 0x04 +#define PCDR_PCD1 0x02 +#define PCDR_PCD0 0x01 + +#define PCRR_PCR7 0x80 +#define PCRR_PCR6 0x40 +#define PCRR_PCR5 0x20 +#define PCRR_PCR4 0x10 +#define PCRR_PCR3 0x08 +#define PCRR_PCR2 0x04 +#define PCRR_PCR1 0x02 +#define PCRR_PCR0 0x01 + + +/* LIM2 (Line Interface Mode 2) + + ------------------ E1 & T1 ---------------------------- */ + +#define LIM2_DJA2 0x20 +#define LIM2_DJA1 0x10 +#define LIM2_LOS2 0x02 +#define LIM2_LOS1 0x01 + +/* LCR1 (Loop Code Register 1) */ + +#define LCR1_EPRM 0x80 +#define LCR1_XPRBS 0x40 + +/* SIC1 (System Interface Control 1) */ +#define SIC1_SRSC 0x80 +#define SIC1_RBS1 0x20 +#define SIC1_RBS0 0x10 +#define SIC1_SXSC 0x08 +#define SIC1_XBS1 0x02 +#define SIC1_XBS0 0x01 + +/* DEC (Disable Error Counter) + ------------------ E1 & T1 ---------------------------- */ + +#define DEC_DCEC3 0x20 +#define DEC_DBEC 0x10 +#define DEC_DCEC1 0x08 +#define DEC_DCEC 0x08 +#define DEC_DEBC 0x04 +#define DEC_DCVC 0x02 +#define DEC_DFEC 0x01 + + +/* FALC Register Bits (Receive Mode) + ---------------------------------------------------------------------------- */ + + +/* FRS0/1 (Framer Receive Status Register 0/1) + ----------------- E1 & T1 ---------------------------------- */ + +#define FRS0_LOS 0x80 +#define FRS0_AIS 0x40 +#define FRS0_LFA 0x20 +#define FRS0_RRA 0x10 +#define FRS0_API 0x08 +#define FRS0_NMF 0x04 +#define FRS0_LMFA 0x02 +#define FRS0_FSRF 0x01 + +#define FRS1_TS16RA 0x40 +#define FRS1_TS16LOS 0x20 +#define FRS1_TS16AIS 0x10 +#define FRS1_TS16LFA 0x08 +#define FRS1_EXZD 0x80 +#define FRS1_LLBDD 0x10 +#define FRS1_LLBAD 0x08 +#define FRS1_XLS 0x02 +#define FRS1_XLO 0x01 +#define FRS1_PDEN 0x40 + +/* FRS2/3 (Framer Receive Status Register 2/3) + ----------------- T1 ---------------------------------- */ + +#define FRS2_ESC2 0x80 +#define FRS2_ESC1 0x40 +#define FRS2_ESC0 0x20 + +#define FRS3_FEH5 0x20 +#define FRS3_FEH4 0x10 +#define FRS3_FEH3 0x08 +#define FRS3_FEH2 0x04 +#define FRS3_FEH1 0x02 +#define FRS3_FEH0 0x01 + + +/* RSW (Receive Service Word Pulseframe) + ----------------- E1 ------------------------------ */ + +#define RSW_RSI 0x80 +#define RSW_RRA 0x20 +#define RSW_RYO 0x10 +#define RSW_RY1 0x08 +#define RSW_RY2 0x04 +#define RSW_RY3 0x02 +#define RSW_RY4 0x01 + + +/* RSP (Receive Spare Bits / Additional Status) + ---------------- E1 ------------------------------- */ + +#define RSP_SI1 0x80 +#define RSP_SI2 0x40 +#define RSP_LLBDD 0x10 +#define RSP_LLBAD 0x08 +#define RSP_RSIF 0x04 +#define RSP_RS13 0x02 +#define RSP_RS15 0x01 + + +/* FECL (Framing Error Counter) + ---------------- E1 & T1 -------------------------- */ + +#define FECL_FE7 0x80 +#define FECL_FE6 0x40 +#define FECL_FE5 0x20 +#define FECL_FE4 0x10 +#define FECL_FE3 0x08 +#define FECL_FE2 0x04 +#define FECL_FE1 0x02 +#define FECL_FE0 0x01 + +#define FECH_FE15 0x80 +#define FECH_FE14 0x40 +#define FECH_FE13 0x20 +#define FECH_FE12 0x10 +#define FECH_FE11 0x08 +#define FECH_FE10 0x04 +#define FECH_FE9 0x02 +#define FECH_FE8 0x01 + + +/* CVCl (Code Violation Counter) + ----------------- E1 ------------------------- */ + +#define CVCL_CV7 0x80 +#define CVCL_CV6 0x40 +#define CVCL_CV5 0x20 +#define CVCL_CV4 0x10 +#define CVCL_CV3 0x08 +#define CVCL_CV2 0x04 +#define CVCL_CV1 0x02 +#define CVCL_CV0 0x01 + +#define CVCH_CV15 0x80 +#define CVCH_CV14 0x40 +#define CVCH_CV13 0x20 +#define CVCH_CV12 0x10 +#define CVCH_CV11 0x08 +#define CVCH_CV10 0x04 +#define CVCH_CV9 0x02 +#define CVCH_CV8 0x01 + + +/* CEC1-3L (CRC Error Counter) + ------------------ E1 ----------------------------- */ + +#define CEC1L_CR7 0x80 +#define CEC1L_CR6 0x40 +#define CEC1L_CR5 0x20 +#define CEC1L_CR4 0x10 +#define CEC1L_CR3 0x08 +#define CEC1L_CR2 0x04 +#define CEC1L_CR1 0x02 +#define CEC1L_CR0 0x01 + +#define CEC1H_CR15 0x80 +#define CEC1H_CR14 0x40 +#define CEC1H_CR13 0x20 +#define CEC1H_CR12 0x10 +#define CEC1H_CR11 0x08 +#define CEC1H_CR10 0x04 +#define CEC1H_CR9 0x02 +#define CEC1H_CR8 0x01 + +#define CEC2L_CR7 0x80 +#define CEC2L_CR6 0x40 +#define CEC2L_CR5 0x20 +#define CEC2L_CR4 0x10 +#define CEC2L_CR3 0x08 +#define CEC2L_CR2 0x04 +#define CEC2L_CR1 0x02 +#define CEC2L_CR0 0x01 + +#define CEC2H_CR15 0x80 +#define CEC2H_CR14 0x40 +#define CEC2H_CR13 0x20 +#define CEC2H_CR12 0x10 +#define CEC2H_CR11 0x08 +#define CEC2H_CR10 0x04 +#define CEC2H_CR9 0x02 +#define CEC2H_CR8 0x01 + +#define CEC3L_CR7 0x80 +#define CEC3L_CR6 0x40 +#define CEC3L_CR5 0x20 +#define CEC3L_CR4 0x10 +#define CEC3L_CR3 0x08 +#define CEC3L_CR2 0x04 +#define CEC3L_CR1 0x02 +#define CEC3L_CR0 0x01 + +#define CEC3H_CR15 0x80 +#define CEC3H_CR14 0x40 +#define CEC3H_CR13 0x20 +#define CEC3H_CR12 0x10 +#define CEC3H_CR11 0x08 +#define CEC3H_CR10 0x04 +#define CEC3H_CR9 0x02 +#define CEC3H_CR8 0x01 + + +/* CECL (CRC Error Counter) + + ------------------ T1 ----------------------------- */ + +#define CECL_CR7 0x80 +#define CECL_CR6 0x40 +#define CECL_CR5 0x20 +#define CECL_CR4 0x10 +#define CECL_CR3 0x08 +#define CECL_CR2 0x04 +#define CECL_CR1 0x02 +#define CECL_CR0 0x01 + +#define CECH_CR15 0x80 +#define CECH_CR14 0x40 +#define CECH_CR13 0x20 +#define CECH_CR12 0x10 +#define CECH_CR11 0x08 +#define CECH_CR10 0x04 +#define CECH_CR9 0x02 +#define CECH_CR8 0x01 + +/* EBCL (E Bit Error Counter) + ------------------- E1 & T1 ------------------------- */ + +#define EBCL_EB7 0x80 +#define EBCL_EB6 0x40 +#define EBCL_EB5 0x20 +#define EBCL_EB4 0x10 +#define EBCL_EB3 0x08 +#define EBCL_EB2 0x04 +#define EBCL_EB1 0x02 +#define EBCL_EB0 0x01 + +#define EBCH_EB15 0x80 +#define EBCH_EB14 0x40 +#define EBCH_EB13 0x20 +#define EBCH_EB12 0x10 +#define EBCH_EB11 0x08 +#define EBCH_EB10 0x04 +#define EBCH_EB9 0x02 +#define EBCH_EB8 0x01 + + +/* RSA4-8 (Receive Sa4-8-Bit Register) + -------------------- E1 --------------------------- */ + +#define RSA4_RS47 0x80 +#define RSA4_RS46 0x40 +#define RSA4_RS45 0x20 +#define RSA4_RS44 0x10 +#define RSA4_RS43 0x08 +#define RSA4_RS42 0x04 +#define RSA4_RS41 0x02 +#define RSA4_RS40 0x01 + +#define RSA5_RS57 0x80 +#define RSA5_RS56 0x40 +#define RSA5_RS55 0x20 +#define RSA5_RS54 0x10 +#define RSA5_RS53 0x08 +#define RSA5_RS52 0x04 +#define RSA5_RS51 0x02 +#define RSA5_RS50 0x01 + +#define RSA6_RS67 0x80 +#define RSA6_RS66 0x40 +#define RSA6_RS65 0x20 +#define RSA6_RS64 0x10 +#define RSA6_RS63 0x08 +#define RSA6_RS62 0x04 +#define RSA6_RS61 0x02 +#define RSA6_RS60 0x01 + +#define RSA7_RS77 0x80 +#define RSA7_RS76 0x40 +#define RSA7_RS75 0x20 +#define RSA7_RS74 0x10 +#define RSA7_RS73 0x08 +#define RSA7_RS72 0x04 +#define RSA7_RS71 0x02 +#define RSA7_RS70 0x01 + +#define RSA8_RS87 0x80 +#define RSA8_RS86 0x40 +#define RSA8_RS85 0x20 +#define RSA8_RS84 0x10 +#define RSA8_RS83 0x08 +#define RSA8_RS82 0x04 +#define RSA8_RS81 0x02 +#define RSA8_RS80 0x01 + +/* RSA6S (Receive Sa6 Bit Status Register) + ------------------------ T1 ------------------------- */ + +#define RSA6S_SX 0x20 +#define RSA6S_SF 0x10 +#define RSA6S_SE 0x08 +#define RSA6S_SC 0x04 +#define RSA6S_SA 0x02 +#define RSA6S_S8 0x01 + + +/* RDL1-3 Receive DL-Bit Register1-3) + ------------------------ T1 ------------------------- */ + +#define RDL1_RDL17 0x80 +#define RDL1_RDL16 0x40 +#define RDL1_RDL15 0x20 +#define RDL1_RDL14 0x10 +#define RDL1_RDL13 0x08 +#define RDL1_RDL12 0x04 +#define RDL1_RDL11 0x02 +#define RDL1_RDL10 0x01 + +#define RDL2_RDL27 0x80 +#define RDL2_RDL26 0x40 +#define RDL2_RDL25 0x20 +#define RDL2_RDL24 0x10 +#define RDL2_RDL23 0x08 +#define RDL2_RDL22 0x04 +#define RDL2_RDL21 0x02 +#define RDL2_RDL20 0x01 + +#define RDL3_RDL37 0x80 +#define RDL3_RDL36 0x40 +#define RDL3_RDL35 0x20 +#define RDL3_RDL34 0x10 +#define RDL3_RDL33 0x08 +#define RDL3_RDL32 0x04 +#define RDL3_RDL31 0x02 +#define RDL3_RDL30 0x01 + + +/* SIS (Signaling Status Register) + + -------------------- E1 & T1 -------------------------- */ + +#define SIS_XDOV 0x80 +#define SIS_XFW 0x40 +#define SIS_XREP 0x20 +#define SIS_RLI 0x08 +#define SIS_CEC 0x04 +#define SIS_BOM 0x01 + + +/* RSIS (Receive Signaling Status Register) + + -------------------- E1 & T1 --------------------------- */ + +#define RSIS_VFR 0x80 +#define RSIS_RDO 0x40 +#define RSIS_CRC16 0x20 +#define RSIS_RAB 0x10 +#define RSIS_HA1 0x08 +#define RSIS_HA0 0x04 +#define RSIS_HFR 0x02 +#define RSIS_LA 0x01 + + +/* RBCL/H (Receive Byte Count Low/High) + + ------------------- E1 & T1 ----------------------- */ + +#define RBCL_RBC7 0x80 +#define RBCL_RBC6 0x40 +#define RBCL_RBC5 0x20 +#define RBCL_RBC4 0x10 +#define RBCL_RBC3 0x08 +#define RBCL_RBC2 0x04 +#define RBCL_RBC1 0x02 +#define RBCL_RBC0 0x01 + +#define RBCH_OV 0x10 +#define RBCH_RBC11 0x08 +#define RBCH_RBC10 0x04 +#define RBCH_RBC9 0x02 +#define RBCH_RBC8 0x01 + + +/* ISR1-3 (Interrupt Status Register 1-3) + + ------------------ E1 & T1 ------------------------------ */ + +#define FISR0_RME 0x80 +#define FISR0_RFS 0x40 +#define FISR0_T8MS 0x20 +#define FISR0_ISF 0x20 +#define FISR0_RMB 0x10 +#define FISR0_CASC 0x08 +#define FISR0_RSC 0x08 +#define FISR0_CRC6 0x04 +#define FISR0_CRC4 0x04 +#define FISR0_PDEN 0x02 +#define FISR0_RPF 0x01 + +#define FISR1_CASE 0x80 +#define FISR1_LLBSC 0x80 +#define FISR1_RDO 0x40 +#define FISR1_ALLS 0x20 +#define FISR1_XDU 0x10 +#define FISR1_XMB 0x08 +#define FISR1_XLSC 0x02 +#define FISR1_XPR 0x01 + +#define FISR2_FAR 0x80 +#define FISR2_LFA 0x40 +#define FISR2_MFAR 0x20 +#define FISR2_T400MS 0x10 +#define FISR2_LMFA 0x10 +#define FISR2_AIS 0x08 +#define FISR2_LOS 0x04 +#define FISR2_RAR 0x02 +#define FISR2_RA 0x01 + +#define FISR3_ES 0x80 +#define FISR3_SEC 0x40 +#define FISR3_LMFA16 0x20 +#define FISR3_AIS16 0x10 +#define FISR3_RA16 0x08 +#define FISR3_API 0x04 +#define FISR3_XSLP 0x20 +#define FISR3_XSLN 0x10 +#define FISR3_LLBSC 0x08 +#define FISR3_XRS 0x04 +#define FISR3_SLN 0x02 +#define FISR3_SLP 0x01 + + +/* GIS (Global Interrupt Status Register) + + --------------------- E1 & T1 --------------------- */ + +#define GIS_ISR3 0x08 +#define GIS_ISR2 0x04 +#define GIS_ISR1 0x02 +#define GIS_ISR0 0x01 + + +/* VSTR (Version Status Register) + + --------------------- E1 & T1 --------------------- */ + +#define VSTR_VN3 0x08 +#define VSTR_VN2 0x04 +#define VSTR_VN1 0x02 +#define VSTR_VN0 0x01 + + +/*>>>>>>>>>>>>>>>>>>>>> Local Control Structures <<<<<<<<<<<<<<<<<<<<<<<<< */ + +/* Write-only Registers (E1/T1 control mode write registers) */ +#define XFIFOH 0x00 /* Tx FIFO High Byte */ +#define XFIFOL 0x01 /* Tx FIFO Low Byte */ +#define CMDR 0x02 /* Command Reg */ +#define DEC 0x60 /* Disable Error Counter */ +#define TEST2 0x62 /* Manuf. Test Reg 2 */ +#define XS(nbr) (0x70 + (nbr)) /* Tx CAS Reg (0 to 15) */ + +/* Read-write Registers (E1/T1 status mode read registers) */ +#define MODE 0x03 /* Mode Reg */ +#define RAH1 0x04 /* Receive Address High 1 */ +#define RAH2 0x05 /* Receive Address High 2 */ +#define RAL1 0x06 /* Receive Address Low 1 */ +#define RAL2 0x07 /* Receive Address Low 2 */ +#define IPC 0x08 /* Interrupt Port Configuration */ +#define CCR1 0x09 /* Common Configuration Reg 1 */ +#define CCR3 0x0A /* Common Configuration Reg 3 */ +#define PRE 0x0B /* Preamble Reg */ +#define RTR1 0x0C /* Receive Timeslot Reg 1 */ +#define RTR2 0x0D /* Receive Timeslot Reg 2 */ +#define RTR3 0x0E /* Receive Timeslot Reg 3 */ +#define RTR4 0x0F /* Receive Timeslot Reg 4 */ +#define TTR1 0x10 /* Transmit Timeslot Reg 1 */ +#define TTR2 0x11 /* Transmit Timeslot Reg 2 */ +#define TTR3 0x12 /* Transmit Timeslot Reg 3 */ +#define TTR4 0x13 /* Transmit Timeslot Reg 4 */ +#define IMR0 0x14 /* Interrupt Mask Reg 0 */ +#define IMR1 0x15 /* Interrupt Mask Reg 1 */ +#define IMR2 0x16 /* Interrupt Mask Reg 2 */ +#define IMR3 0x17 /* Interrupt Mask Reg 3 */ +#define IMR4 0x18 /* Interrupt Mask Reg 4 */ +#define IMR5 0x19 /* Interrupt Mask Reg 5 */ +#define FMR0 0x1A /* Framer Mode Reigster 0 */ +#define FMR1 0x1B /* Framer Mode Reigster 1 */ +#define FMR2 0x1C /* Framer Mode Reigster 2 */ +#define LOOP 0x1D /* Channel Loop Back */ +#define XSW 0x1E /* Transmit Service Word */ +#define FMR4 0x1E /* Framer Mode Reg 4 */ +#define XSP 0x1F /* Transmit Spare Bits */ +#define FMR5 0x1F /* Framer Mode Reg 5 */ +#define XC0 0x20 /* Transmit Control 0 */ +#define XC1 0x21 /* Transmit Control 1 */ +#define RC0 0x22 /* Receive Control 0 */ +#define RC1 0x23 /* Receive Control 1 */ +#define XPM0 0x24 /* Transmit Pulse Mask 0 */ +#define XPM1 0x25 /* Transmit Pulse Mask 1 */ +#define XPM2 0x26 /* Transmit Pulse Mask 2 */ +#define TSWM 0x27 /* Transparent Service Word Mask */ +#define TEST1 0x28 /* Manuf. Test Reg 1 */ +#define IDLE 0x29 /* Idle Channel Code */ +#define XSA4 0x2A /* Transmit SA4 Bit Reg */ +#define XDL1 0x2A /* Transmit DL-Bit Reg 2 */ +#define XSA5 0x2B /* Transmit SA4 Bit Reg */ +#define XDL2 0x2B /* Transmit DL-Bit Reg 2 */ +#define XSA6 0x2C /* Transmit SA4 Bit Reg */ +#define XDL3 0x2C /* Transmit DL-Bit Reg 2 */ +#define XSA7 0x2D /* Transmit SA4 Bit Reg */ +#define CCB1 0x2D /* Clear Channel Reg 1 */ +#define XSA8 0x2E /* Transmit SA4 Bit Reg */ +#define CCB2 0x2E /* Clear Channel Reg 2 */ +#define FMR3 0x2F /* Framer Mode Reg. 3 */ +#define CCB3 0x2F /* Clear Channel Reg 3 */ +#define ICB1 0x30 /* Idle Channel Reg 1 */ +#define ICB2 0x31 /* Idle Channel Reg 2 */ +#define ICB3 0x32 /* Idle Channel Reg 3 */ +#define ICB4 0x33 /* Idle Channel Reg 4 */ +#define LIM0 0x34 /* Line Interface Mode 0 */ +#define LIM1 0x35 /* Line Interface Mode 1 */ +#define PCDR 0x36 /* Pulse Count Detection */ +#define PCRR 0x37 /* Pulse Count Recovery */ +#define LIM2 0x38 /* Line Interface Mode Reg 2 */ +#define LCR1 0x39 /* Loop Code Reg 1 */ +#define LCR2 0x3A /* Loop Code Reg 2 */ +#define LCR3 0x3B /* Loop Code Reg 3 */ +#define SIC1 0x3C /* System Interface Control 1 */ + +/* Read-only Registers (E1/T1 control mode read registers) */ +#define RFIFOH 0x00 /* Receive FIFO */ +#define RFIFOL 0x01 /* Receive FIFO */ +#define FRS0 0x4C /* Framer Receive Status 0 */ +#define FRS1 0x4D /* Framer Receive Status 1 */ +#define RSW 0x4E /* Receive Service Word */ +#define FRS2 0x4E /* Framer Receive Status 2 */ +#define RSP 0x4F /* Receive Spare Bits */ +#define FRS3 0x4F /* Framer Receive Status 3 */ +#define FECL 0x50 /* Framing Error Counter */ +#define FECH 0x51 /* Framing Error Counter */ +#define CVCL 0x52 /* Code Violation Counter */ +#define CVCH 0x53 /* Code Violation Counter */ +#define CECL 0x54 /* CRC Error Counter 1 */ +#define CECH 0x55 /* CRC Error Counter 1 */ +#define EBCL 0x56 /* E-Bit Error Counter */ +#define EBCH 0x57 /* E-Bit Error Counter */ +#define BECL 0x58 /* Bit Error Counter Low */ +#define BECH 0x59 /* Bit Error Counter Low */ +#define CEC3 0x5A /* CRC Error Counter 3 (16-bit) */ +#define RSA4 0x5C /* Receive SA4 Bit Reg */ +#define RDL1 0x5C /* Receive DL-Bit Reg 1 */ +#define RSA5 0x5D /* Receive SA5 Bit Reg */ +#define RDL2 0x5D /* Receive DL-Bit Reg 2 */ +#define RSA6 0x5E /* Receive SA6 Bit Reg */ +#define RDL3 0x5E /* Receive DL-Bit Reg 3 */ +#define RSA7 0x5F /* Receive SA7 Bit Reg */ +#define RSA8 0x60 /* Receive SA8 Bit Reg */ +#define RSA6S 0x61 /* Receive SA6 Bit Status Reg */ +#define TSR0 0x62 /* Manuf. Test Reg 0 */ +#define TSR1 0x63 /* Manuf. Test Reg 1 */ +#define SIS 0x64 /* Signaling Status Reg */ +#define RSIS 0x65 /* Receive Signaling Status Reg */ +#define RBCL 0x66 /* Receive Byte Control */ +#define RBCH 0x67 /* Receive Byte Control */ +#define FISR0 0x68 /* Interrupt Status Reg 0 */ +#define FISR1 0x69 /* Interrupt Status Reg 1 */ +#define FISR2 0x6A /* Interrupt Status Reg 2 */ +#define FISR3 0x6B /* Interrupt Status Reg 3 */ +#define GIS 0x6E /* Global Interrupt Status */ +#define VSTR 0x6F /* Version Status */ +#define RS(nbr) (0x70 + (nbr)) /* Rx CAS Reg (0 to 15) */ + +#endif /* _FALC_LH_H */ + diff --git a/drivers/staging/net/pc300.h b/drivers/staging/net/pc300.h new file mode 100644 index 0000000..2e4f84f --- /dev/null +++ b/drivers/staging/net/pc300.h @@ -0,0 +1,436 @@ +/* + * pc300.h Cyclades-PC300(tm) Kernel API Definitions. + * + * Author: Ivan Passos + * + * Copyright: (c) 1999-2002 Cyclades Corp. + * + * 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. + * + * $Log: pc300.h,v $ + * Revision 3.12 2002/03/07 14:17:09 henrique + * License data fixed + * + * Revision 3.11 2002/01/28 21:09:39 daniela + * Included ';' after pc300hw.bus. + * + * Revision 3.10 2002/01/17 17:58:52 ivan + * Support for PC300-TE/M (PMC). + * + * Revision 3.9 2001/09/28 13:30:53 daniela + * Renamed dma_start routine to rx_dma_start. + * + * Revision 3.8 2001/09/24 13:03:45 daniela + * Fixed BOF interrupt treatment. Created dma_start routine. + * + * Revision 3.7 2001/08/10 17:19:58 daniela + * Fixed IOCTLs defines. + * + * Revision 3.6 2001/07/18 19:24:42 daniela + * Included kernel version. + * + * Revision 3.5 2001/07/05 18:38:08 daniela + * DMA transmission bug fix. + * + * Revision 3.4 2001/06/26 17:10:40 daniela + * New configuration parameters (line code, CRC calculation and clock). + * + * Revision 3.3 2001/06/22 13:13:02 regina + * MLPPP implementation + * + * Revision 3.2 2001/06/18 17:56:09 daniela + * Increased DEF_MTU and TX_QUEUE_LEN. + * + * Revision 3.1 2001/06/15 12:41:10 regina + * upping major version number + * + * Revision 1.1.1.1 2001/06/13 20:25:06 daniela + * PC300 initial CVS version (3.4.0-pre1) + * + * Revision 2.3 2001/03/05 daniela + * Created struct pc300conf, to provide the hardware information to pc300util. + * Inclusion of 'alloc_ramsize' field on structure 'pc300hw'. + * + * Revision 2.2 2000/12/22 daniela + * Structures and defines to support pc300util: statistics, status, + * loopback tests, trace. + * + * Revision 2.1 2000/09/28 ivan + * Inclusion of 'iophys' and 'iosize' fields on structure 'pc300hw', to + * allow release of I/O region at module unload. + * Changed location of include files. + * + * Revision 2.0 2000/03/27 ivan + * Added support for the PC300/TE cards. + * + * Revision 1.1 2000/01/31 ivan + * Replaced 'pc300[drv|sca].h' former PC300 driver include files. + * + * Revision 1.0 1999/12/16 ivan + * First official release. + * Inclusion of 'nchan' field on structure 'pc300hw', to allow variable + * number of ports per card. + * Inclusion of 'if_ptr' field on structure 'pc300dev'. + * + * Revision 0.6 1999/11/17 ivan + * Changed X.25-specific function names to comply with adopted convention. + * + * Revision 0.5 1999/11/16 Daniela Squassoni + * X.25 support. + * + * Revision 0.4 1999/11/15 ivan + * Inclusion of 'clock' field on structure 'pc300hw'. + * + * Revision 0.3 1999/11/10 ivan + * IOCTL name changing. + * Inclusion of driver function prototypes. + * + * Revision 0.2 1999/11/03 ivan + * Inclusion of 'tx_skb' and union 'ifu' on structure 'pc300dev'. + * + * Revision 0.1 1999/01/15 ivan + * Initial version. + * + */ + +#ifndef _PC300_H +#define _PC300_H + +#include +#include "hd64572.h" +#include "pc300-falc-lh.h" + +#define PC300_PROTO_MLPPP 1 + +#define PC300_MAXCHAN 2 /* Number of channels per card */ + +#define PC300_RAMSIZE 0x40000 /* RAM window size (256Kb) */ +#define PC300_FALCSIZE 0x400 /* FALC window size (1Kb) */ + +#define PC300_OSC_CLOCK 24576000 +#define PC300_PCI_CLOCK 33000000 + +#define BD_DEF_LEN 0x0800 /* DMA buffer length (2KB) */ +#define DMA_TX_MEMSZ 0x8000 /* Total DMA Tx memory size (32KB/ch) */ +#define DMA_RX_MEMSZ 0x10000 /* Total DMA Rx memory size (64KB/ch) */ + +#define N_DMA_TX_BUF (DMA_TX_MEMSZ / BD_DEF_LEN) /* DMA Tx buffers */ +#define N_DMA_RX_BUF (DMA_RX_MEMSZ / BD_DEF_LEN) /* DMA Rx buffers */ + +/* DMA Buffer Offsets */ +#define DMA_TX_BASE ((N_DMA_TX_BUF + N_DMA_RX_BUF) * \ + PC300_MAXCHAN * sizeof(pcsca_bd_t)) +#define DMA_RX_BASE (DMA_TX_BASE + PC300_MAXCHAN*DMA_TX_MEMSZ) + +/* DMA Descriptor Offsets */ +#define DMA_TX_BD_BASE 0x0000 +#define DMA_RX_BD_BASE (DMA_TX_BD_BASE + ((PC300_MAXCHAN*DMA_TX_MEMSZ / \ + BD_DEF_LEN) * sizeof(pcsca_bd_t))) + +/* DMA Descriptor Macros */ +#define TX_BD_ADDR(chan, n) (DMA_TX_BD_BASE + \ + ((N_DMA_TX_BUF*chan) + n) * sizeof(pcsca_bd_t)) +#define RX_BD_ADDR(chan, n) (DMA_RX_BD_BASE + \ + ((N_DMA_RX_BUF*chan) + n) * sizeof(pcsca_bd_t)) + +/* Macro to access the FALC registers (TE only) */ +#define F_REG(reg, chan) (0x200*(chan) + ((reg)<<2)) + +/*************************************** + * Memory access functions/macros * + * (required to support Alpha systems) * + ***************************************/ +#define cpc_writeb(port,val) {writeb((u8)(val),(port)); mb();} +#define cpc_writew(port,val) {writew((ushort)(val),(port)); mb();} +#define cpc_writel(port,val) {writel((u32)(val),(port)); mb();} + +#define cpc_readb(port) readb(port) +#define cpc_readw(port) readw(port) +#define cpc_readl(port) readl(port) + +/****** Data Structures *****************************************************/ + +/* + * RUNTIME_9050 - PLX PCI9050-1 local configuration and shared runtime + * registers. This structure can be used to access the 9050 registers + * (memory mapped). + */ +struct RUNTIME_9050 { + u32 loc_addr_range[4]; /* 00-0Ch : Local Address Ranges */ + u32 loc_rom_range; /* 10h : Local ROM Range */ + u32 loc_addr_base[4]; /* 14-20h : Local Address Base Addrs */ + u32 loc_rom_base; /* 24h : Local ROM Base */ + u32 loc_bus_descr[4]; /* 28-34h : Local Bus Descriptors */ + u32 rom_bus_descr; /* 38h : ROM Bus Descriptor */ + u32 cs_base[4]; /* 3C-48h : Chip Select Base Addrs */ + u32 intr_ctrl_stat; /* 4Ch : Interrupt Control/Status */ + u32 init_ctrl; /* 50h : EEPROM ctrl, Init Ctrl, etc */ +}; + +#define PLX_9050_LINT1_ENABLE 0x01 +#define PLX_9050_LINT1_POL 0x02 +#define PLX_9050_LINT1_STATUS 0x04 +#define PLX_9050_LINT2_ENABLE 0x08 +#define PLX_9050_LINT2_POL 0x10 +#define PLX_9050_LINT2_STATUS 0x20 +#define PLX_9050_INTR_ENABLE 0x40 +#define PLX_9050_SW_INTR 0x80 + +/* Masks to access the init_ctrl PLX register */ +#define PC300_CLKSEL_MASK (0x00000004UL) +#define PC300_CHMEDIA_MASK(chan) (0x00000020UL<<(chan*3)) +#define PC300_CTYPE_MASK (0x00000800UL) + +/* CPLD Registers (base addr = falcbase, TE only) */ +/* CPLD v. 0 */ +#define CPLD_REG1 0x140 /* Chip resets, DCD/CTS status */ +#define CPLD_REG2 0x144 /* Clock enable , LED control */ +/* CPLD v. 2 or higher */ +#define CPLD_V2_REG1 0x100 /* Chip resets, DCD/CTS status */ +#define CPLD_V2_REG2 0x104 /* Clock enable , LED control */ +#define CPLD_ID_REG 0x108 /* CPLD version */ + +/* CPLD Register bit description: for the FALC bits, they should always be + set based on the channel (use (bit<<(2*ch)) to access the correct bit for + that channel) */ +#define CPLD_REG1_FALC_RESET 0x01 +#define CPLD_REG1_SCA_RESET 0x02 +#define CPLD_REG1_GLOBAL_CLK 0x08 +#define CPLD_REG1_FALC_DCD 0x10 +#define CPLD_REG1_FALC_CTS 0x20 + +#define CPLD_REG2_FALC_TX_CLK 0x01 +#define CPLD_REG2_FALC_RX_CLK 0x02 +#define CPLD_REG2_FALC_LED1 0x10 +#define CPLD_REG2_FALC_LED2 0x20 + +/* Structure with FALC-related fields (TE only) */ +#define PC300_FALC_MAXLOOP 0x0000ffff /* for falc_issue_cmd() */ + +typedef struct falc { + u8 sync; /* If true FALC is synchronized */ + u8 active; /* if TRUE then already active */ + u8 loop_active; /* if TRUE a line loopback UP was received */ + u8 loop_gen; /* if TRUE a line loopback UP was issued */ + + u8 num_channels; + u8 offset; /* 1 for T1, 0 for E1 */ + u8 full_bandwidth; + + u8 xmb_cause; + u8 multiframe_mode; + + /* Statistics */ + u16 pden; /* Pulse Density violation count */ + u16 los; /* Loss of Signal count */ + u16 losr; /* Loss of Signal recovery count */ + u16 lfa; /* Loss of frame alignment count */ + u16 farec; /* Frame Alignment Recovery count */ + u16 lmfa; /* Loss of multiframe alignment count */ + u16 ais; /* Remote Alarm indication Signal count */ + u16 sec; /* One-second timer */ + u16 es; /* Errored second */ + u16 rai; /* remote alarm received */ + u16 bec; + u16 fec; + u16 cvc; + u16 cec; + u16 ebc; + + /* Status */ + u8 red_alarm; + u8 blue_alarm; + u8 loss_fa; + u8 yellow_alarm; + u8 loss_mfa; + u8 prbs; +} falc_t; + +typedef struct falc_status { + u8 sync; /* If true FALC is synchronized */ + u8 red_alarm; + u8 blue_alarm; + u8 loss_fa; + u8 yellow_alarm; + u8 loss_mfa; + u8 prbs; +} falc_status_t; + +typedef struct rsv_x21_status { + u8 dcd; + u8 dsr; + u8 cts; + u8 rts; + u8 dtr; +} rsv_x21_status_t; + +typedef struct pc300stats { + int hw_type; + u32 line_on; + u32 line_off; + struct net_device_stats gen_stats; + falc_t te_stats; +} pc300stats_t; + +typedef struct pc300status { + int hw_type; + rsv_x21_status_t gen_status; + falc_status_t te_status; +} pc300status_t; + +typedef struct pc300loopback { + char loop_type; + char loop_on; +} pc300loopback_t; + +typedef struct pc300patterntst { + char patrntst_on; /* 0 - off; 1 - on; 2 - read num_errors */ + u16 num_errors; +} pc300patterntst_t; + +typedef struct pc300dev { + struct pc300ch *chan; + u8 trace_on; + u32 line_on; /* DCD(X.21, RSV) / sync(TE) change counters */ + u32 line_off; + char name[16]; + struct net_device *dev; +#ifdef CONFIG_PC300_MLPPP + void *cpc_tty; /* information to PC300 TTY driver */ +#endif +}pc300dev_t; + +typedef struct pc300hw { + int type; /* RSV, X21, etc. */ + int bus; /* Bus (PCI, PMC, etc.) */ + int nchan; /* number of channels */ + int irq; /* interrupt request level */ + u32 clock; /* Board clock */ + u8 cpld_id; /* CPLD ID (TE only) */ + u16 cpld_reg1; /* CPLD reg 1 (TE only) */ + u16 cpld_reg2; /* CPLD reg 2 (TE only) */ + u16 gpioc_reg; /* PLX GPIOC reg */ + u16 intctl_reg; /* PLX Int Ctrl/Status reg */ + u32 iophys; /* PLX registers I/O base */ + u32 iosize; /* PLX registers I/O size */ + u32 plxphys; /* PLX registers MMIO base (physical) */ + void __iomem * plxbase; /* PLX registers MMIO base (virtual) */ + u32 plxsize; /* PLX registers MMIO size */ + u32 scaphys; /* SCA registers MMIO base (physical) */ + void __iomem * scabase; /* SCA registers MMIO base (virtual) */ + u32 scasize; /* SCA registers MMIO size */ + u32 ramphys; /* On-board RAM MMIO base (physical) */ + void __iomem * rambase; /* On-board RAM MMIO base (virtual) */ + u32 alloc_ramsize; /* RAM MMIO size allocated by the PCI bridge */ + u32 ramsize; /* On-board RAM MMIO size */ + u32 falcphys; /* FALC registers MMIO base (physical) */ + void __iomem * falcbase;/* FALC registers MMIO base (virtual) */ + u32 falcsize; /* FALC registers MMIO size */ +} pc300hw_t; + +typedef struct pc300chconf { + sync_serial_settings phys_settings; /* Clock type/rate (in bps), + loopback mode */ + raw_hdlc_proto proto_settings; /* Encoding, parity (CRC) */ + u32 media; /* HW media (RS232, V.35, etc.) */ + u32 proto; /* Protocol (PPP, X.25, etc.) */ + + /* TE-specific parameters */ + u8 lcode; /* Line Code (AMI, B8ZS, etc.) */ + u8 fr_mode; /* Frame Mode (ESF, D4, etc.) */ + u8 lbo; /* Line Build Out */ + u8 rx_sens; /* Rx Sensitivity (long- or short-haul) */ + u32 tslot_bitmap; /* bit[i]=1 => timeslot _i_ is active */ +} pc300chconf_t; + +typedef struct pc300ch { + struct pc300 *card; + int channel; + pc300dev_t d; + pc300chconf_t conf; + u8 tx_first_bd; /* First TX DMA block descr. w/ data */ + u8 tx_next_bd; /* Next free TX DMA block descriptor */ + u8 rx_first_bd; /* First free RX DMA block descriptor */ + u8 rx_last_bd; /* Last free RX DMA block descriptor */ + u8 nfree_tx_bd; /* Number of free TX DMA block descriptors */ + falc_t falc; /* FALC structure (TE only) */ +} pc300ch_t; + +typedef struct pc300 { + pc300hw_t hw; /* hardware config. */ + pc300ch_t chan[PC300_MAXCHAN]; + spinlock_t card_lock; +} pc300_t; + +typedef struct pc300conf { + pc300hw_t hw; + pc300chconf_t conf; +} pc300conf_t; + +/* DEV ioctl() commands */ +#define N_SPPP_IOCTLS 2 + +enum pc300_ioctl_cmds { + SIOCCPCRESERVED = (SIOCDEVPRIVATE + N_SPPP_IOCTLS), + SIOCGPC300CONF, + SIOCSPC300CONF, + SIOCGPC300STATUS, + SIOCGPC300FALCSTATUS, + SIOCGPC300UTILSTATS, + SIOCGPC300UTILSTATUS, + SIOCSPC300TRACE, + SIOCSPC300LOOPBACK, + SIOCSPC300PATTERNTEST, +}; + +/* Loopback types - PC300/TE boards */ +enum pc300_loopback_cmds { + PC300LOCLOOP = 1, + PC300REMLOOP, + PC300PAYLOADLOOP, + PC300GENLOOPUP, + PC300GENLOOPDOWN, +}; + +/* Control Constant Definitions */ +#define PC300_RSV 0x01 +#define PC300_X21 0x02 +#define PC300_TE 0x03 + +#define PC300_PCI 0x00 +#define PC300_PMC 0x01 + +#define PC300_LC_AMI 0x01 +#define PC300_LC_B8ZS 0x02 +#define PC300_LC_NRZ 0x03 +#define PC300_LC_HDB3 0x04 + +/* Framing (T1) */ +#define PC300_FR_ESF 0x01 +#define PC300_FR_D4 0x02 +#define PC300_FR_ESF_JAPAN 0x03 + +/* Framing (E1) */ +#define PC300_FR_MF_CRC4 0x04 +#define PC300_FR_MF_NON_CRC4 0x05 +#define PC300_FR_UNFRAMED 0x06 + +#define PC300_LBO_0_DB 0x00 +#define PC300_LBO_7_5_DB 0x01 +#define PC300_LBO_15_DB 0x02 +#define PC300_LBO_22_5_DB 0x03 + +#define PC300_RX_SENS_SH 0x01 +#define PC300_RX_SENS_LH 0x02 + +#define PC300_TX_TIMEOUT (2*HZ) +#define PC300_TX_QUEUE_LEN 100 +#define PC300_DEF_MTU 1600 + +/* Function Prototypes */ +int cpc_open(struct net_device *dev); + +#endif /* _PC300_H */ diff --git a/drivers/staging/net/pc300_drv.c b/drivers/staging/net/pc300_drv.c new file mode 100644 index 0000000..cb0f8d9 --- /dev/null +++ b/drivers/staging/net/pc300_drv.c @@ -0,0 +1,3670 @@ +#define USE_PCI_CLOCK +static const char rcsid[] = +"Revision: 3.4.5 Date: 2002/03/07 "; + +/* + * pc300.c Cyclades-PC300(tm) Driver. + * + * Author: Ivan Passos + * Maintainer: PC300 Maintainer + * + * Copyright: (c) 1999-2003 Cyclades Corp. + * + * 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. + * + * Using tabstop = 4. + * + * $Log: pc300_drv.c,v $ + * Revision 3.23 2002/03/20 13:58:40 henrique + * Fixed ortographic mistakes + * + * Revision 3.22 2002/03/13 16:56:56 henrique + * Take out the debug messages + * + * Revision 3.21 2002/03/07 14:17:09 henrique + * License data fixed + * + * Revision 3.20 2002/01/17 17:58:52 ivan + * Support for PC300-TE/M (PMC). + * + * Revision 3.19 2002/01/03 17:08:47 daniela + * Enables DMA reception when the SCA-II disables it improperly. + * + * Revision 3.18 2001/12/03 18:47:50 daniela + * Esthetic changes. + * + * Revision 3.17 2001/10/19 16:50:13 henrique + * Patch to kernel 2.4.12 and new generic hdlc. + * + * Revision 3.16 2001/10/16 15:12:31 regina + * clear statistics + * + * Revision 3.11 to 3.15 2001/10/11 20:26:04 daniela + * More DMA fixes for noisy lines. + * Return the size of bad frames in dma_get_rx_frame_size, so that the Rx buffer + * descriptors can be cleaned by dma_buf_read (called in cpc_net_rx). + * Renamed dma_start routine to rx_dma_start. Improved Rx statistics. + * Fixed BOF interrupt treatment. Created dma_start routine. + * Changed min and max to cpc_min and cpc_max. + * + * Revision 3.10 2001/08/06 12:01:51 regina + * Fixed problem in DSR_DE bit. + * + * Revision 3.9 2001/07/18 19:27:26 daniela + * Added some history comments. + * + * Revision 3.8 2001/07/12 13:11:19 regina + * bug fix - DCD-OFF in pc300 tty driver + * + * Revision 3.3 to 3.7 2001/07/06 15:00:20 daniela + * Removing kernel 2.4.3 and previous support. + * DMA transmission bug fix. + * MTU check in cpc_net_rx fixed. + * Boot messages reviewed. + * New configuration parameters (line code, CRC calculation and clock). + * + * Revision 3.2 2001/06/22 13:13:02 regina + * MLPPP implementation. Changed the header of message trace to include + * the device name. New format : "hdlcX[R/T]: ". + * Default configuration changed. + * + * Revision 3.1 2001/06/15 regina + * in cpc_queue_xmit, netif_stop_queue is called if don't have free descriptor + * upping major version number + * + * Revision 1.1.1.1 2001/06/13 20:25:04 daniela + * PC300 initial CVS version (3.4.0-pre1) + * + * Revision 3.0.1.2 2001/06/08 daniela + * Did some changes in the DMA programming implementation to avoid the + * occurrence of a SCA-II bug when CDA is accessed during a DMA transfer. + * + * Revision 3.0.1.1 2001/05/02 daniela + * Added kernel 2.4.3 support. + * + * Revision 3.0.1.0 2001/03/13 daniela, henrique + * Added Frame Relay Support. + * Driver now uses HDLC generic driver to provide protocol support. + * + * Revision 3.0.0.8 2001/03/02 daniela + * Fixed ram size detection. + * Changed SIOCGPC300CONF ioctl, to give hw information to pc300util. + * + * Revision 3.0.0.7 2001/02/23 daniela + * netif_stop_queue called before the SCA-II transmition commands in + * cpc_queue_xmit, and with interrupts disabled to avoid race conditions with + * transmition interrupts. + * Fixed falc_check_status for Unframed E1. + * + * Revision 3.0.0.6 2000/12/13 daniela + * Implemented pc300util support: trace, statistics, status and loopback + * tests for the PC300 TE boards. + * + * Revision 3.0.0.5 2000/12/12 ivan + * Added support for Unframed E1. + * Implemented monitor mode. + * Fixed DCD sensitivity on the second channel. + * Driver now complies with new PCI kernel architecture. + * + * Revision 3.0.0.4 2000/09/28 ivan + * Implemented DCD sensitivity. + * Moved hardware-specific open to the end of cpc_open, to avoid race + * conditions with early reception interrupts. + * Included code for [request|release]_mem_region(). + * Changed location of pc300.h . + * Minor code revision (contrib. of Jeff Garzik). + * + * Revision 3.0.0.3 2000/07/03 ivan + * Previous bugfix for the framing errors with external clock made X21 + * boards stop working. This version fixes it. + * + * Revision 3.0.0.2 2000/06/23 ivan + * Revisited cpc_queue_xmit to prevent race conditions on Tx DMA buffer + * handling when Tx timeouts occur. + * Revisited Rx statistics. + * Fixed a bug in the SCA-II programming that would cause framing errors + * when external clock was configured. + * + * Revision 3.0.0.1 2000/05/26 ivan + * Added logic in the SCA interrupt handler so that no board can monopolize + * the driver. + * Request PLX I/O region, although driver doesn't use it, to avoid + * problems with other drivers accessing it. + * + * Revision 3.0.0.0 2000/05/15 ivan + * Did some changes in the DMA programming implementation to avoid the + * occurrence of a SCA-II bug in the second channel. + * Implemented workaround for PLX9050 bug that would cause a system lockup + * in certain systems, depending on the MMIO addresses allocated to the + * board. + * Fixed the FALC chip programming to avoid synchronization problems in the + * second channel (TE only). + * Implemented a cleaner and faster Tx DMA descriptor cleanup procedure in + * cpc_queue_xmit(). + * Changed the built-in driver implementation so that the driver can use the + * general 'hdlcN' naming convention instead of proprietary device names. + * Driver load messages are now device-centric, instead of board-centric. + * Dynamic allocation of net_device structures. + * Code is now compliant with the new module interface (module_[init|exit]). + * Make use of the PCI helper functions to access PCI resources. + * + * Revision 2.0.0.0 2000/04/15 ivan + * Added support for the PC300/TE boards (T1/FT1/E1/FE1). + * + * Revision 1.1.0.0 2000/02/28 ivan + * Major changes in the driver architecture. + * Softnet compliancy implemented. + * Driver now reports physical instead of virtual memory addresses. + * Added cpc_change_mtu function. + * + * Revision 1.0.0.0 1999/12/16 ivan + * First official release. + * Support for 1- and 2-channel boards (which use distinct PCI Device ID's). + * Support for monolythic installation (i.e., drv built into the kernel). + * X.25 additional checking when lapb_[dis]connect_request returns an error. + * SCA programming now covers X.21 as well. + * + * Revision 0.3.1.0 1999/11/18 ivan + * Made X.25 support configuration-dependent (as it depends on external + * modules to work). + * Changed X.25-specific function names to comply with adopted convention. + * Fixed typos in X.25 functions that would cause compile errors (Daniela). + * Fixed bug in ch_config that would disable interrupts on a previously + * enabled channel if the other channel on the same board was enabled later. + * + * Revision 0.3.0.0 1999/11/16 daniela + * X.25 support. + * + * Revision 0.2.3.0 1999/11/15 ivan + * Function cpc_ch_status now provides more detailed information. + * Added support for X.21 clock configuration. + * Changed TNR1 setting in order to prevent Tx FIFO overaccesses by the SCA. + * Now using PCI clock instead of internal oscillator clock for the SCA. + * + * Revision 0.2.2.0 1999/11/10 ivan + * Changed the *_dma_buf_check functions so that they would print only + * the useful info instead of the whole buffer descriptor bank. + * Fixed bug in cpc_queue_xmit that would eventually crash the system + * in case of a packet drop. + * Implemented TX underrun handling. + * Improved SCA fine tuning to boost up its performance. + * + * Revision 0.2.1.0 1999/11/03 ivan + * Added functions *dma_buf_pt_init to allow independent initialization + * of the next-descr. and DMA buffer pointers on the DMA descriptors. + * Kernel buffer release and tbusy clearing is now done in the interrupt + * handler. + * Fixed bug in cpc_open that would cause an interface reopen to fail. + * Added a protocol-specific code section in cpc_net_rx. + * Removed printk level defs (they might be added back after the beta phase). + * + * Revision 0.2.0.0 1999/10/28 ivan + * Revisited the code so that new protocols can be easily added / supported. + * + * Revision 0.1.0.1 1999/10/20 ivan + * Mostly "esthetic" changes. + * + * Revision 0.1.0.0 1999/10/11 ivan + * Initial version. + * + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "pc300.h" + +#define CPC_LOCK(card,flags) \ + do { \ + spin_lock_irqsave(&card->card_lock, flags); \ + } while (0) + +#define CPC_UNLOCK(card,flags) \ + do { \ + spin_unlock_irqrestore(&card->card_lock, flags); \ + } while (0) + +#undef PC300_DEBUG_PCI +#undef PC300_DEBUG_INTR +#undef PC300_DEBUG_TX +#undef PC300_DEBUG_RX +#undef PC300_DEBUG_OTHER + +static DEFINE_PCI_DEVICE_TABLE(cpc_pci_dev_id) = { + /* PC300/RSV or PC300/X21, 2 chan */ + {0x120e, 0x300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x300}, + /* PC300/RSV or PC300/X21, 1 chan */ + {0x120e, 0x301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x301}, + /* PC300/TE, 2 chan */ + {0x120e, 0x310, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x310}, + /* PC300/TE, 1 chan */ + {0x120e, 0x311, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x311}, + /* PC300/TE-M, 2 chan */ + {0x120e, 0x320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x320}, + /* PC300/TE-M, 1 chan */ + {0x120e, 0x321, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x321}, + /* End of table */ + {0,}, +}; +MODULE_DEVICE_TABLE(pci, cpc_pci_dev_id); + +#ifndef cpc_min +#define cpc_min(a,b) (((a)<(b))?(a):(b)) +#endif +#ifndef cpc_max +#define cpc_max(a,b) (((a)>(b))?(a):(b)) +#endif + +/* prototypes */ +static void tx_dma_buf_pt_init(pc300_t *, int); +static void tx_dma_buf_init(pc300_t *, int); +static void rx_dma_buf_pt_init(pc300_t *, int); +static void rx_dma_buf_init(pc300_t *, int); +static void tx_dma_buf_check(pc300_t *, int); +static void rx_dma_buf_check(pc300_t *, int); +static irqreturn_t cpc_intr(int, void *); +static int clock_rate_calc(u32, u32, int *); +static u32 detect_ram(pc300_t *); +static void plx_init(pc300_t *); +static void cpc_trace(struct net_device *, struct sk_buff *, char); +static int cpc_attach(struct net_device *, unsigned short, unsigned short); +static int cpc_close(struct net_device *dev); + +#ifdef CONFIG_PC300_MLPPP +void cpc_tty_init(pc300dev_t * dev); +void cpc_tty_unregister_service(pc300dev_t * pc300dev); +void cpc_tty_receive(pc300dev_t * pc300dev); +void cpc_tty_trigger_poll(pc300dev_t * pc300dev); +#endif + +/************************/ +/*** DMA Routines ***/ +/************************/ +static void tx_dma_buf_pt_init(pc300_t * card, int ch) +{ + int i; + int ch_factor = ch * N_DMA_TX_BUF; + volatile pcsca_bd_t __iomem *ptdescr = (card->hw.rambase + + DMA_TX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); + + for (i = 0; i < N_DMA_TX_BUF; i++, ptdescr++) { + cpc_writel(&ptdescr->next, (u32)(DMA_TX_BD_BASE + + (ch_factor + ((i + 1) & (N_DMA_TX_BUF - 1))) * sizeof(pcsca_bd_t))); + cpc_writel(&ptdescr->ptbuf, + (u32)(DMA_TX_BASE + (ch_factor + i) * BD_DEF_LEN)); + } +} + +static void tx_dma_buf_init(pc300_t * card, int ch) +{ + int i; + int ch_factor = ch * N_DMA_TX_BUF; + volatile pcsca_bd_t __iomem *ptdescr = (card->hw.rambase + + DMA_TX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); + + for (i = 0; i < N_DMA_TX_BUF; i++, ptdescr++) { + memset_io(ptdescr, 0, sizeof(pcsca_bd_t)); + cpc_writew(&ptdescr->len, 0); + cpc_writeb(&ptdescr->status, DST_OSB); + } + tx_dma_buf_pt_init(card, ch); +} + +static void rx_dma_buf_pt_init(pc300_t * card, int ch) +{ + int i; + int ch_factor = ch * N_DMA_RX_BUF; + volatile pcsca_bd_t __iomem *ptdescr = (card->hw.rambase + + DMA_RX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); + + for (i = 0; i < N_DMA_RX_BUF; i++, ptdescr++) { + cpc_writel(&ptdescr->next, (u32)(DMA_RX_BD_BASE + + (ch_factor + ((i + 1) & (N_DMA_RX_BUF - 1))) * sizeof(pcsca_bd_t))); + cpc_writel(&ptdescr->ptbuf, + (u32)(DMA_RX_BASE + (ch_factor + i) * BD_DEF_LEN)); + } +} + +static void rx_dma_buf_init(pc300_t * card, int ch) +{ + int i; + int ch_factor = ch * N_DMA_RX_BUF; + volatile pcsca_bd_t __iomem *ptdescr = (card->hw.rambase + + DMA_RX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); + + for (i = 0; i < N_DMA_RX_BUF; i++, ptdescr++) { + memset_io(ptdescr, 0, sizeof(pcsca_bd_t)); + cpc_writew(&ptdescr->len, 0); + cpc_writeb(&ptdescr->status, 0); + } + rx_dma_buf_pt_init(card, ch); +} + +static void tx_dma_buf_check(pc300_t * card, int ch) +{ + volatile pcsca_bd_t __iomem *ptdescr; + int i; + u16 first_bd = card->chan[ch].tx_first_bd; + u16 next_bd = card->chan[ch].tx_next_bd; + + printk("#CH%d: f_bd = %d(0x%08zx), n_bd = %d(0x%08zx)\n", ch, + first_bd, TX_BD_ADDR(ch, first_bd), + next_bd, TX_BD_ADDR(ch, next_bd)); + for (i = first_bd, + ptdescr = (card->hw.rambase + TX_BD_ADDR(ch, first_bd)); + i != ((next_bd + 1) & (N_DMA_TX_BUF - 1)); + i = (i + 1) & (N_DMA_TX_BUF - 1), + ptdescr = (card->hw.rambase + TX_BD_ADDR(ch, i))) { + printk("\n CH%d TX%d: next=0x%x, ptbuf=0x%x, ST=0x%x, len=%d", + ch, i, cpc_readl(&ptdescr->next), + cpc_readl(&ptdescr->ptbuf), + cpc_readb(&ptdescr->status), cpc_readw(&ptdescr->len)); + } + printk("\n"); +} + +#ifdef PC300_DEBUG_OTHER +/* Show all TX buffer descriptors */ +static void tx1_dma_buf_check(pc300_t * card, int ch) +{ + volatile pcsca_bd_t __iomem *ptdescr; + int i; + u16 first_bd = card->chan[ch].tx_first_bd; + u16 next_bd = card->chan[ch].tx_next_bd; + u32 scabase = card->hw.scabase; + + printk ("\nnfree_tx_bd = %d\n", card->chan[ch].nfree_tx_bd); + printk("#CH%d: f_bd = %d(0x%08x), n_bd = %d(0x%08x)\n", ch, + first_bd, TX_BD_ADDR(ch, first_bd), + next_bd, TX_BD_ADDR(ch, next_bd)); + printk("TX_CDA=0x%08x, TX_EDA=0x%08x\n", + cpc_readl(scabase + DTX_REG(CDAL, ch)), + cpc_readl(scabase + DTX_REG(EDAL, ch))); + for (i = 0; i < N_DMA_TX_BUF; i++) { + ptdescr = (card->hw.rambase + TX_BD_ADDR(ch, i)); + printk("\n CH%d TX%d: next=0x%x, ptbuf=0x%x, ST=0x%x, len=%d", + ch, i, cpc_readl(&ptdescr->next), + cpc_readl(&ptdescr->ptbuf), + cpc_readb(&ptdescr->status), cpc_readw(&ptdescr->len)); + } + printk("\n"); +} +#endif + +static void rx_dma_buf_check(pc300_t * card, int ch) +{ + volatile pcsca_bd_t __iomem *ptdescr; + int i; + u16 first_bd = card->chan[ch].rx_first_bd; + u16 last_bd = card->chan[ch].rx_last_bd; + int ch_factor; + + ch_factor = ch * N_DMA_RX_BUF; + printk("#CH%d: f_bd = %d, l_bd = %d\n", ch, first_bd, last_bd); + for (i = 0, ptdescr = (card->hw.rambase + + DMA_RX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); + i < N_DMA_RX_BUF; i++, ptdescr++) { + if (cpc_readb(&ptdescr->status) & DST_OSB) + printk ("\n CH%d RX%d: next=0x%x, ptbuf=0x%x, ST=0x%x, len=%d", + ch, i, cpc_readl(&ptdescr->next), + cpc_readl(&ptdescr->ptbuf), + cpc_readb(&ptdescr->status), + cpc_readw(&ptdescr->len)); + } + printk("\n"); +} + +static int dma_get_rx_frame_size(pc300_t * card, int ch) +{ + volatile pcsca_bd_t __iomem *ptdescr; + u16 first_bd = card->chan[ch].rx_first_bd; + int rcvd = 0; + volatile u8 status; + + ptdescr = (card->hw.rambase + RX_BD_ADDR(ch, first_bd)); + while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) { + rcvd += cpc_readw(&ptdescr->len); + first_bd = (first_bd + 1) & (N_DMA_RX_BUF - 1); + if ((status & DST_EOM) || (first_bd == card->chan[ch].rx_last_bd)) { + /* Return the size of a good frame or incomplete bad frame + * (dma_buf_read will clean the buffer descriptors in this case). */ + return rcvd; + } + ptdescr = (card->hw.rambase + cpc_readl(&ptdescr->next)); + } + return -1; +} + +/* + * dma_buf_write: writes a frame to the Tx DMA buffers + * NOTE: this function writes one frame at a time. + */ +static int dma_buf_write(pc300_t *card, int ch, u8 *ptdata, int len) +{ + int i, nchar; + volatile pcsca_bd_t __iomem *ptdescr; + int tosend = len; + u8 nbuf = ((len - 1) / BD_DEF_LEN) + 1; + + if (nbuf >= card->chan[ch].nfree_tx_bd) { + return -ENOMEM; + } + + for (i = 0; i < nbuf; i++) { + ptdescr = (card->hw.rambase + + TX_BD_ADDR(ch, card->chan[ch].tx_next_bd)); + nchar = cpc_min(BD_DEF_LEN, tosend); + if (cpc_readb(&ptdescr->status) & DST_OSB) { + memcpy_toio((card->hw.rambase + cpc_readl(&ptdescr->ptbuf)), + &ptdata[len - tosend], nchar); + cpc_writew(&ptdescr->len, nchar); + card->chan[ch].nfree_tx_bd--; + if ((i + 1) == nbuf) { + /* This must be the last BD to be used */ + cpc_writeb(&ptdescr->status, DST_EOM); + } else { + cpc_writeb(&ptdescr->status, 0); + } + } else { + return -ENOMEM; + } + tosend -= nchar; + card->chan[ch].tx_next_bd = + (card->chan[ch].tx_next_bd + 1) & (N_DMA_TX_BUF - 1); + } + /* If it gets to here, it means we have sent the whole frame */ + return 0; +} + +/* + * dma_buf_read: reads a frame from the Rx DMA buffers + * NOTE: this function reads one frame at a time. + */ +static int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb) +{ + int nchar; + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + volatile pcsca_bd_t __iomem *ptdescr; + int rcvd = 0; + volatile u8 status; + + ptdescr = (card->hw.rambase + + RX_BD_ADDR(ch, chan->rx_first_bd)); + while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) { + nchar = cpc_readw(&ptdescr->len); + if ((status & (DST_OVR | DST_CRC | DST_RBIT | DST_SHRT | DST_ABT)) || + (nchar > BD_DEF_LEN)) { + + if (nchar > BD_DEF_LEN) + status |= DST_RBIT; + rcvd = -status; + /* Discard remaining descriptors used by the bad frame */ + while (chan->rx_first_bd != chan->rx_last_bd) { + cpc_writeb(&ptdescr->status, 0); + chan->rx_first_bd = (chan->rx_first_bd+1) & (N_DMA_RX_BUF-1); + if (status & DST_EOM) + break; + ptdescr = (card->hw.rambase + + cpc_readl(&ptdescr->next)); + status = cpc_readb(&ptdescr->status); + } + break; + } + if (nchar != 0) { + if (skb) { + memcpy_fromio(skb_put(skb, nchar), + (card->hw.rambase+cpc_readl(&ptdescr->ptbuf)),nchar); + } + rcvd += nchar; + } + cpc_writeb(&ptdescr->status, 0); + cpc_writeb(&ptdescr->len, 0); + chan->rx_first_bd = (chan->rx_first_bd + 1) & (N_DMA_RX_BUF - 1); + + if (status & DST_EOM) + break; + + ptdescr = (card->hw.rambase + cpc_readl(&ptdescr->next)); + } + + if (rcvd != 0) { + /* Update pointer */ + chan->rx_last_bd = (chan->rx_first_bd - 1) & (N_DMA_RX_BUF - 1); + /* Update EDA */ + cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), + RX_BD_ADDR(ch, chan->rx_last_bd)); + } + return rcvd; +} + +static void tx_dma_stop(pc300_t * card, int ch) +{ + void __iomem *scabase = card->hw.scabase; + u8 drr_ena_bit = 1 << (5 + 2 * ch); + u8 drr_rst_bit = 1 << (1 + 2 * ch); + + /* Disable DMA */ + cpc_writeb(scabase + DRR, drr_ena_bit); + cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit); +} + +static void rx_dma_stop(pc300_t * card, int ch) +{ + void __iomem *scabase = card->hw.scabase; + u8 drr_ena_bit = 1 << (4 + 2 * ch); + u8 drr_rst_bit = 1 << (2 * ch); + + /* Disable DMA */ + cpc_writeb(scabase + DRR, drr_ena_bit); + cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit); +} + +static void rx_dma_start(pc300_t * card, int ch) +{ + void __iomem *scabase = card->hw.scabase; + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + + /* Start DMA */ + cpc_writel(scabase + DRX_REG(CDAL, ch), + RX_BD_ADDR(ch, chan->rx_first_bd)); + if (cpc_readl(scabase + DRX_REG(CDAL,ch)) != + RX_BD_ADDR(ch, chan->rx_first_bd)) { + cpc_writel(scabase + DRX_REG(CDAL, ch), + RX_BD_ADDR(ch, chan->rx_first_bd)); + } + cpc_writel(scabase + DRX_REG(EDAL, ch), + RX_BD_ADDR(ch, chan->rx_last_bd)); + cpc_writew(scabase + DRX_REG(BFLL, ch), BD_DEF_LEN); + cpc_writeb(scabase + DSR_RX(ch), DSR_DE); + if (!(cpc_readb(scabase + DSR_RX(ch)) & DSR_DE)) { + cpc_writeb(scabase + DSR_RX(ch), DSR_DE); + } +} + +/*************************/ +/*** FALC Routines ***/ +/*************************/ +static void falc_issue_cmd(pc300_t *card, int ch, u8 cmd) +{ + void __iomem *falcbase = card->hw.falcbase; + unsigned long i = 0; + + while (cpc_readb(falcbase + F_REG(SIS, ch)) & SIS_CEC) { + if (i++ >= PC300_FALC_MAXLOOP) { + printk("%s: FALC command locked(cmd=0x%x).\n", + card->chan[ch].d.name, cmd); + break; + } + } + cpc_writeb(falcbase + F_REG(CMDR, ch), cmd); +} + +static void falc_intr_enable(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + + /* Interrupt pins are open-drain */ + cpc_writeb(falcbase + F_REG(IPC, ch), + cpc_readb(falcbase + F_REG(IPC, ch)) & ~IPC_IC0); + /* Conters updated each second */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_ECM); + /* Enable SEC and ES interrupts */ + cpc_writeb(falcbase + F_REG(IMR3, ch), + cpc_readb(falcbase + F_REG(IMR3, ch)) & ~(IMR3_SEC | IMR3_ES)); + if (conf->fr_mode == PC300_FR_UNFRAMED) { + cpc_writeb(falcbase + F_REG(IMR4, ch), + cpc_readb(falcbase + F_REG(IMR4, ch)) & ~(IMR4_LOS)); + } else { + cpc_writeb(falcbase + F_REG(IMR4, ch), + cpc_readb(falcbase + F_REG(IMR4, ch)) & + ~(IMR4_LFA | IMR4_AIS | IMR4_LOS | IMR4_SLIP)); + } + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(IMR3, ch), + cpc_readb(falcbase + F_REG(IMR3, ch)) & ~IMR3_LLBSC); + } else { + cpc_writeb(falcbase + F_REG(IPC, ch), + cpc_readb(falcbase + F_REG(IPC, ch)) | IPC_SCI); + if (conf->fr_mode == PC300_FR_UNFRAMED) { + cpc_writeb(falcbase + F_REG(IMR2, ch), + cpc_readb(falcbase + F_REG(IMR2, ch)) & ~(IMR2_LOS)); + } else { + cpc_writeb(falcbase + F_REG(IMR2, ch), + cpc_readb(falcbase + F_REG(IMR2, ch)) & + ~(IMR2_FAR | IMR2_LFA | IMR2_AIS | IMR2_LOS)); + if (pfalc->multiframe_mode) { + cpc_writeb(falcbase + F_REG(IMR2, ch), + cpc_readb(falcbase + F_REG(IMR2, ch)) & + ~(IMR2_T400MS | IMR2_MFAR)); + } else { + cpc_writeb(falcbase + F_REG(IMR2, ch), + cpc_readb(falcbase + F_REG(IMR2, ch)) | + IMR2_T400MS | IMR2_MFAR); + } + } + } +} + +static void falc_open_timeslot(pc300_t * card, int ch, int timeslot) +{ + void __iomem *falcbase = card->hw.falcbase; + u8 tshf = card->chan[ch].falc.offset; + + cpc_writeb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch), + cpc_readb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch)) & + ~(0x80 >> ((timeslot - tshf) & 0x07))); + cpc_writeb(falcbase + F_REG((TTR1 + timeslot / 8), ch), + cpc_readb(falcbase + F_REG((TTR1 + timeslot / 8), ch)) | + (0x80 >> (timeslot & 0x07))); + cpc_writeb(falcbase + F_REG((RTR1 + timeslot / 8), ch), + cpc_readb(falcbase + F_REG((RTR1 + timeslot / 8), ch)) | + (0x80 >> (timeslot & 0x07))); +} + +static void falc_close_timeslot(pc300_t * card, int ch, int timeslot) +{ + void __iomem *falcbase = card->hw.falcbase; + u8 tshf = card->chan[ch].falc.offset; + + cpc_writeb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch), + cpc_readb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch)) | + (0x80 >> ((timeslot - tshf) & 0x07))); + cpc_writeb(falcbase + F_REG((TTR1 + timeslot / 8), ch), + cpc_readb(falcbase + F_REG((TTR1 + timeslot / 8), ch)) & + ~(0x80 >> (timeslot & 0x07))); + cpc_writeb(falcbase + F_REG((RTR1 + timeslot / 8), ch), + cpc_readb(falcbase + F_REG((RTR1 + timeslot / 8), ch)) & + ~(0x80 >> (timeslot & 0x07))); +} + +static void falc_close_all_timeslots(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + void __iomem *falcbase = card->hw.falcbase; + + cpc_writeb(falcbase + F_REG(ICB1, ch), 0xff); + cpc_writeb(falcbase + F_REG(TTR1, ch), 0); + cpc_writeb(falcbase + F_REG(RTR1, ch), 0); + cpc_writeb(falcbase + F_REG(ICB2, ch), 0xff); + cpc_writeb(falcbase + F_REG(TTR2, ch), 0); + cpc_writeb(falcbase + F_REG(RTR2, ch), 0); + cpc_writeb(falcbase + F_REG(ICB3, ch), 0xff); + cpc_writeb(falcbase + F_REG(TTR3, ch), 0); + cpc_writeb(falcbase + F_REG(RTR3, ch), 0); + if (conf->media == IF_IFACE_E1) { + cpc_writeb(falcbase + F_REG(ICB4, ch), 0xff); + cpc_writeb(falcbase + F_REG(TTR4, ch), 0); + cpc_writeb(falcbase + F_REG(RTR4, ch), 0); + } +} + +static void falc_open_all_timeslots(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + void __iomem *falcbase = card->hw.falcbase; + + cpc_writeb(falcbase + F_REG(ICB1, ch), 0); + if (conf->fr_mode == PC300_FR_UNFRAMED) { + cpc_writeb(falcbase + F_REG(TTR1, ch), 0xff); + cpc_writeb(falcbase + F_REG(RTR1, ch), 0xff); + } else { + /* Timeslot 0 is never enabled */ + cpc_writeb(falcbase + F_REG(TTR1, ch), 0x7f); + cpc_writeb(falcbase + F_REG(RTR1, ch), 0x7f); + } + cpc_writeb(falcbase + F_REG(ICB2, ch), 0); + cpc_writeb(falcbase + F_REG(TTR2, ch), 0xff); + cpc_writeb(falcbase + F_REG(RTR2, ch), 0xff); + cpc_writeb(falcbase + F_REG(ICB3, ch), 0); + cpc_writeb(falcbase + F_REG(TTR3, ch), 0xff); + cpc_writeb(falcbase + F_REG(RTR3, ch), 0xff); + if (conf->media == IF_IFACE_E1) { + cpc_writeb(falcbase + F_REG(ICB4, ch), 0); + cpc_writeb(falcbase + F_REG(TTR4, ch), 0xff); + cpc_writeb(falcbase + F_REG(RTR4, ch), 0xff); + } else { + cpc_writeb(falcbase + F_REG(ICB4, ch), 0xff); + cpc_writeb(falcbase + F_REG(TTR4, ch), 0x80); + cpc_writeb(falcbase + F_REG(RTR4, ch), 0x80); + } +} + +static void falc_init_timeslot(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + int tslot; + + for (tslot = 0; tslot < pfalc->num_channels; tslot++) { + if (conf->tslot_bitmap & (1 << tslot)) { + // Channel enabled + falc_open_timeslot(card, ch, tslot + 1); + } else { + // Channel disabled + falc_close_timeslot(card, ch, tslot + 1); + } + } +} + +static void falc_enable_comm(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + + if (pfalc->full_bandwidth) { + falc_open_all_timeslots(card, ch); + } else { + falc_init_timeslot(card, ch); + } + // CTS/DCD ON + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) & + ~((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch))); +} + +static void falc_disable_comm(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + + if (pfalc->loop_active != 2) { + falc_close_all_timeslots(card, ch); + } + // CTS/DCD OFF + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) | + ((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch))); +} + +static void falc_init_t1(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + u8 dja = (ch ? (LIM2_DJA2 | LIM2_DJA1) : 0); + + /* Switch to T1 mode (PCM 24) */ + cpc_writeb(falcbase + F_REG(FMR1, ch), FMR1_PMOD); + + /* Wait 20 us for setup */ + udelay(20); + + /* Transmit Buffer Size (1 frame) */ + cpc_writeb(falcbase + F_REG(SIC1, ch), SIC1_XBS0); + + /* Clock mode */ + if (conf->phys_settings.clock_type == CLOCK_INT) { /* Master mode */ + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_MAS); + } else { /* Slave mode */ + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_MAS); + cpc_writeb(falcbase + F_REG(LOOP, ch), + cpc_readb(falcbase + F_REG(LOOP, ch)) & ~LOOP_RTM); + } + + cpc_writeb(falcbase + F_REG(IPC, ch), IPC_SCI); + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) & + ~(FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1)); + + switch (conf->lcode) { + case PC300_LC_AMI: + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) | + FMR0_XC1 | FMR0_RC1); + /* Clear Channel register to ON for all channels */ + cpc_writeb(falcbase + F_REG(CCB1, ch), 0xff); + cpc_writeb(falcbase + F_REG(CCB2, ch), 0xff); + cpc_writeb(falcbase + F_REG(CCB3, ch), 0xff); + break; + + case PC300_LC_B8ZS: + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) | + FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1); + break; + + case PC300_LC_NRZ: + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) | 0x00); + break; + } + + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_ELOS); + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) & ~(LIM0_SCL1 | LIM0_SCL0)); + /* Set interface mode to 2 MBPS */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_IMOD); + + switch (conf->fr_mode) { + case PC300_FR_ESF: + pfalc->multiframe_mode = 0; + cpc_writeb(falcbase + F_REG(FMR4, ch), + cpc_readb(falcbase + F_REG(FMR4, ch)) | FMR4_FM1); + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | + FMR1_CRC | FMR1_EDL); + cpc_writeb(falcbase + F_REG(XDL1, ch), 0); + cpc_writeb(falcbase + F_REG(XDL2, ch), 0); + cpc_writeb(falcbase + F_REG(XDL3, ch), 0); + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) & ~FMR0_SRAF); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2,ch)) | FMR2_MCSP | FMR2_SSP); + break; + + case PC300_FR_D4: + pfalc->multiframe_mode = 1; + cpc_writeb(falcbase + F_REG(FMR4, ch), + cpc_readb(falcbase + F_REG(FMR4, ch)) & + ~(FMR4_FM1 | FMR4_FM0)); + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) | FMR0_SRAF); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_SSP); + break; + } + + /* Enable Automatic Resynchronization */ + cpc_writeb(falcbase + F_REG(FMR4, ch), + cpc_readb(falcbase + F_REG(FMR4, ch)) | FMR4_AUTO); + + /* Transmit Automatic Remote Alarm */ + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_AXRA); + + /* Channel translation mode 1 : one to one */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_CTM); + + /* No signaling */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_SIGM); + cpc_writeb(falcbase + F_REG(FMR5, ch), + cpc_readb(falcbase + F_REG(FMR5, ch)) & + ~(FMR5_EIBR | FMR5_SRS)); + cpc_writeb(falcbase + F_REG(CCR1, ch), 0); + + cpc_writeb(falcbase + F_REG(LIM1, ch), + cpc_readb(falcbase + F_REG(LIM1, ch)) | LIM1_RIL0 | LIM1_RIL1); + + switch (conf->lbo) { + /* Provides proper Line Build Out */ + case PC300_LBO_0_DB: + cpc_writeb(falcbase + F_REG(LIM2, ch), (LIM2_LOS1 | dja)); + cpc_writeb(falcbase + F_REG(XPM0, ch), 0x5a); + cpc_writeb(falcbase + F_REG(XPM1, ch), 0x8f); + cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20); + break; + case PC300_LBO_7_5_DB: + cpc_writeb(falcbase + F_REG(LIM2, ch), (0x40 | LIM2_LOS1 | dja)); + cpc_writeb(falcbase + F_REG(XPM0, ch), 0x11); + cpc_writeb(falcbase + F_REG(XPM1, ch), 0x02); + cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20); + break; + case PC300_LBO_15_DB: + cpc_writeb(falcbase + F_REG(LIM2, ch), (0x80 | LIM2_LOS1 | dja)); + cpc_writeb(falcbase + F_REG(XPM0, ch), 0x8e); + cpc_writeb(falcbase + F_REG(XPM1, ch), 0x01); + cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20); + break; + case PC300_LBO_22_5_DB: + cpc_writeb(falcbase + F_REG(LIM2, ch), (0xc0 | LIM2_LOS1 | dja)); + cpc_writeb(falcbase + F_REG(XPM0, ch), 0x09); + cpc_writeb(falcbase + F_REG(XPM1, ch), 0x01); + cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20); + break; + } + + /* Transmit Clock-Slot Offset */ + cpc_writeb(falcbase + F_REG(XC0, ch), + cpc_readb(falcbase + F_REG(XC0, ch)) | 0x01); + /* Transmit Time-slot Offset */ + cpc_writeb(falcbase + F_REG(XC1, ch), 0x3e); + /* Receive Clock-Slot offset */ + cpc_writeb(falcbase + F_REG(RC0, ch), 0x05); + /* Receive Time-slot offset */ + cpc_writeb(falcbase + F_REG(RC1, ch), 0x00); + + /* LOS Detection after 176 consecutive 0s */ + cpc_writeb(falcbase + F_REG(PCDR, ch), 0x0a); + /* LOS Recovery after 22 ones in the time window of PCD */ + cpc_writeb(falcbase + F_REG(PCRR, ch), 0x15); + + cpc_writeb(falcbase + F_REG(IDLE, ch), 0x7f); + + if (conf->fr_mode == PC300_FR_ESF_JAPAN) { + cpc_writeb(falcbase + F_REG(RC1, ch), + cpc_readb(falcbase + F_REG(RC1, ch)) | 0x80); + } + + falc_close_all_timeslots(card, ch); +} + +static void falc_init_e1(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + u8 dja = (ch ? (LIM2_DJA2 | LIM2_DJA1) : 0); + + /* Switch to E1 mode (PCM 30) */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_PMOD); + + /* Clock mode */ + if (conf->phys_settings.clock_type == CLOCK_INT) { /* Master mode */ + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_MAS); + } else { /* Slave mode */ + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_MAS); + } + cpc_writeb(falcbase + F_REG(LOOP, ch), + cpc_readb(falcbase + F_REG(LOOP, ch)) & ~LOOP_SFM); + + cpc_writeb(falcbase + F_REG(IPC, ch), IPC_SCI); + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) & + ~(FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1)); + + switch (conf->lcode) { + case PC300_LC_AMI: + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) | + FMR0_XC1 | FMR0_RC1); + break; + + case PC300_LC_HDB3: + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) | + FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1); + break; + + case PC300_LC_NRZ: + break; + } + + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) & ~(LIM0_SCL1 | LIM0_SCL0)); + /* Set interface mode to 2 MBPS */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_IMOD); + + cpc_writeb(falcbase + F_REG(XPM0, ch), 0x18); + cpc_writeb(falcbase + F_REG(XPM1, ch), 0x03); + cpc_writeb(falcbase + F_REG(XPM2, ch), 0x00); + + switch (conf->fr_mode) { + case PC300_FR_MF_CRC4: + pfalc->multiframe_mode = 1; + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_XFS); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_RFS1); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_RFS0); + cpc_writeb(falcbase + F_REG(FMR3, ch), + cpc_readb(falcbase + F_REG(FMR3, ch)) & ~FMR3_EXTIW); + + /* MultiFrame Resynchronization */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_MFCS); + + /* Automatic Loss of Multiframe > 914 CRC errors */ + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_ALMF); + + /* S1 and SI1/SI2 spare Bits set to 1 */ + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) & ~XSP_AXS); + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_EBP); + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_XS13 | XSP_XS15); + + /* Automatic Force Resynchronization */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_AFR); + + /* Transmit Automatic Remote Alarm */ + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_AXRA); + + /* Transmit Spare Bits for National Use (Y, Sn, Sa) */ + cpc_writeb(falcbase + F_REG(XSW, ch), + cpc_readb(falcbase + F_REG(XSW, ch)) | + XSW_XY0 | XSW_XY1 | XSW_XY2 | XSW_XY3 | XSW_XY4); + break; + + case PC300_FR_MF_NON_CRC4: + case PC300_FR_D4: + pfalc->multiframe_mode = 0; + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_XFS); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) & + ~(FMR2_RFS1 | FMR2_RFS0)); + cpc_writeb(falcbase + F_REG(XSW, ch), + cpc_readb(falcbase + F_REG(XSW, ch)) | XSW_XSIS); + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_XSIF); + + /* Automatic Force Resynchronization */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_AFR); + + /* Transmit Automatic Remote Alarm */ + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_AXRA); + + /* Transmit Spare Bits for National Use (Y, Sn, Sa) */ + cpc_writeb(falcbase + F_REG(XSW, ch), + cpc_readb(falcbase + F_REG(XSW, ch)) | + XSW_XY0 | XSW_XY1 | XSW_XY2 | XSW_XY3 | XSW_XY4); + break; + + case PC300_FR_UNFRAMED: + pfalc->multiframe_mode = 0; + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_XFS); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) & + ~(FMR2_RFS1 | FMR2_RFS0)); + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_TT0); + cpc_writeb(falcbase + F_REG(XSW, ch), + cpc_readb(falcbase + F_REG(XSW, ch)) & + ~(XSW_XTM|XSW_XY0|XSW_XY1|XSW_XY2|XSW_XY3|XSW_XY4)); + cpc_writeb(falcbase + F_REG(TSWM, ch), 0xff); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) | + (FMR2_RTM | FMR2_DAIS)); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_AXRA); + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_AFR); + pfalc->sync = 1; + cpc_writeb(falcbase + card->hw.cpld_reg2, + cpc_readb(falcbase + card->hw.cpld_reg2) | + (CPLD_REG2_FALC_LED2 << (2 * ch))); + break; + } + + /* No signaling */ + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) & ~XSP_CASEN); + cpc_writeb(falcbase + F_REG(CCR1, ch), 0); + + cpc_writeb(falcbase + F_REG(LIM1, ch), + cpc_readb(falcbase + F_REG(LIM1, ch)) | LIM1_RIL0 | LIM1_RIL1); + cpc_writeb(falcbase + F_REG(LIM2, ch), (LIM2_LOS1 | dja)); + + /* Transmit Clock-Slot Offset */ + cpc_writeb(falcbase + F_REG(XC0, ch), + cpc_readb(falcbase + F_REG(XC0, ch)) | 0x01); + /* Transmit Time-slot Offset */ + cpc_writeb(falcbase + F_REG(XC1, ch), 0x3e); + /* Receive Clock-Slot offset */ + cpc_writeb(falcbase + F_REG(RC0, ch), 0x05); + /* Receive Time-slot offset */ + cpc_writeb(falcbase + F_REG(RC1, ch), 0x00); + + /* LOS Detection after 176 consecutive 0s */ + cpc_writeb(falcbase + F_REG(PCDR, ch), 0x0a); + /* LOS Recovery after 22 ones in the time window of PCD */ + cpc_writeb(falcbase + F_REG(PCRR, ch), 0x15); + + cpc_writeb(falcbase + F_REG(IDLE, ch), 0x7f); + + falc_close_all_timeslots(card, ch); +} + +static void falc_init_hdlc(pc300_t * card, int ch) +{ + void __iomem *falcbase = card->hw.falcbase; + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + + /* Enable transparent data transfer */ + if (conf->fr_mode == PC300_FR_UNFRAMED) { + cpc_writeb(falcbase + F_REG(MODE, ch), 0); + } else { + cpc_writeb(falcbase + F_REG(MODE, ch), + cpc_readb(falcbase + F_REG(MODE, ch)) | + (MODE_HRAC | MODE_MDS2)); + cpc_writeb(falcbase + F_REG(RAH2, ch), 0xff); + cpc_writeb(falcbase + F_REG(RAH1, ch), 0xff); + cpc_writeb(falcbase + F_REG(RAL2, ch), 0xff); + cpc_writeb(falcbase + F_REG(RAL1, ch), 0xff); + } + + /* Tx/Rx reset */ + falc_issue_cmd(card, ch, CMDR_RRES | CMDR_XRES | CMDR_SRES); + + /* Enable interrupt sources */ + falc_intr_enable(card, ch); +} + +static void te_config(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + u8 dummy; + unsigned long flags; + + memset(pfalc, 0, sizeof(falc_t)); + switch (conf->media) { + case IF_IFACE_T1: + pfalc->num_channels = NUM_OF_T1_CHANNELS; + pfalc->offset = 1; + break; + case IF_IFACE_E1: + pfalc->num_channels = NUM_OF_E1_CHANNELS; + pfalc->offset = 0; + break; + } + if (conf->tslot_bitmap == 0xffffffffUL) + pfalc->full_bandwidth = 1; + else + pfalc->full_bandwidth = 0; + + CPC_LOCK(card, flags); + /* Reset the FALC chip */ + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) | + (CPLD_REG1_FALC_RESET << (2 * ch))); + udelay(10000); + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) & + ~(CPLD_REG1_FALC_RESET << (2 * ch))); + + if (conf->media == IF_IFACE_T1) { + falc_init_t1(card, ch); + } else { + falc_init_e1(card, ch); + } + falc_init_hdlc(card, ch); + if (conf->rx_sens == PC300_RX_SENS_SH) { + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_EQON); + } else { + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_EQON); + } + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) | + ((CPLD_REG2_FALC_TX_CLK | CPLD_REG2_FALC_RX_CLK) << (2 * ch))); + + /* Clear all interrupt registers */ + dummy = cpc_readb(falcbase + F_REG(FISR0, ch)) + + cpc_readb(falcbase + F_REG(FISR1, ch)) + + cpc_readb(falcbase + F_REG(FISR2, ch)) + + cpc_readb(falcbase + F_REG(FISR3, ch)); + CPC_UNLOCK(card, flags); +} + +static void falc_check_status(pc300_t * card, int ch, unsigned char frs0) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + + /* Verify LOS */ + if (frs0 & FRS0_LOS) { + if (!pfalc->red_alarm) { + pfalc->red_alarm = 1; + pfalc->los++; + if (!pfalc->blue_alarm) { + // EVENT_FALC_ABNORMAL + if (conf->media == IF_IFACE_T1) { + /* Disable this interrupt as it may otherwise interfere + * with other working boards. */ + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) + | IMR0_PDEN); + } + falc_disable_comm(card, ch); + // EVENT_FALC_ABNORMAL + } + } + } else { + if (pfalc->red_alarm) { + pfalc->red_alarm = 0; + pfalc->losr++; + } + } + + if (conf->fr_mode != PC300_FR_UNFRAMED) { + /* Verify AIS alarm */ + if (frs0 & FRS0_AIS) { + if (!pfalc->blue_alarm) { + pfalc->blue_alarm = 1; + pfalc->ais++; + // EVENT_AIS + if (conf->media == IF_IFACE_T1) { + /* Disable this interrupt as it may otherwise interfere with other working boards. */ + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN); + } + falc_disable_comm(card, ch); + // EVENT_AIS + } + } else { + pfalc->blue_alarm = 0; + } + + /* Verify LFA */ + if (frs0 & FRS0_LFA) { + if (!pfalc->loss_fa) { + pfalc->loss_fa = 1; + pfalc->lfa++; + if (!pfalc->blue_alarm && !pfalc->red_alarm) { + // EVENT_FALC_ABNORMAL + if (conf->media == IF_IFACE_T1) { + /* Disable this interrupt as it may otherwise + * interfere with other working boards. */ + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) + | IMR0_PDEN); + } + falc_disable_comm(card, ch); + // EVENT_FALC_ABNORMAL + } + } + } else { + if (pfalc->loss_fa) { + pfalc->loss_fa = 0; + pfalc->farec++; + } + } + + /* Verify LMFA */ + if (pfalc->multiframe_mode && (frs0 & FRS0_LMFA)) { + /* D4 or CRC4 frame mode */ + if (!pfalc->loss_mfa) { + pfalc->loss_mfa = 1; + pfalc->lmfa++; + if (!pfalc->blue_alarm && !pfalc->red_alarm && + !pfalc->loss_fa) { + // EVENT_FALC_ABNORMAL + if (conf->media == IF_IFACE_T1) { + /* Disable this interrupt as it may otherwise + * interfere with other working boards. */ + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) + | IMR0_PDEN); + } + falc_disable_comm(card, ch); + // EVENT_FALC_ABNORMAL + } + } + } else { + pfalc->loss_mfa = 0; + } + + /* Verify Remote Alarm */ + if (frs0 & FRS0_RRA) { + if (!pfalc->yellow_alarm) { + pfalc->yellow_alarm = 1; + pfalc->rai++; + if (pfalc->sync) { + // EVENT_RAI + falc_disable_comm(card, ch); + // EVENT_RAI + } + } + } else { + pfalc->yellow_alarm = 0; + } + } /* if !PC300_UNFRAMED */ + + if (pfalc->red_alarm || pfalc->loss_fa || + pfalc->loss_mfa || pfalc->blue_alarm) { + if (pfalc->sync) { + pfalc->sync = 0; + chan->d.line_off++; + cpc_writeb(falcbase + card->hw.cpld_reg2, + cpc_readb(falcbase + card->hw.cpld_reg2) & + ~(CPLD_REG2_FALC_LED2 << (2 * ch))); + } + } else { + if (!pfalc->sync) { + pfalc->sync = 1; + chan->d.line_on++; + cpc_writeb(falcbase + card->hw.cpld_reg2, + cpc_readb(falcbase + card->hw.cpld_reg2) | + (CPLD_REG2_FALC_LED2 << (2 * ch))); + } + } + + if (pfalc->sync && !pfalc->yellow_alarm) { + if (!pfalc->active) { + // EVENT_FALC_NORMAL + if (pfalc->loop_active) { + return; + } + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) & ~IMR0_PDEN); + } + falc_enable_comm(card, ch); + // EVENT_FALC_NORMAL + pfalc->active = 1; + } + } else { + if (pfalc->active) { + pfalc->active = 0; + } + } +} + +static void falc_update_stats(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + u16 counter; + + counter = cpc_readb(falcbase + F_REG(FECL, ch)); + counter |= cpc_readb(falcbase + F_REG(FECH, ch)) << 8; + pfalc->fec += counter; + + counter = cpc_readb(falcbase + F_REG(CVCL, ch)); + counter |= cpc_readb(falcbase + F_REG(CVCH, ch)) << 8; + pfalc->cvc += counter; + + counter = cpc_readb(falcbase + F_REG(CECL, ch)); + counter |= cpc_readb(falcbase + F_REG(CECH, ch)) << 8; + pfalc->cec += counter; + + counter = cpc_readb(falcbase + F_REG(EBCL, ch)); + counter |= cpc_readb(falcbase + F_REG(EBCH, ch)) << 8; + pfalc->ebc += counter; + + if (cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_EPRM) { + mdelay(10); + counter = cpc_readb(falcbase + F_REG(BECL, ch)); + counter |= cpc_readb(falcbase + F_REG(BECH, ch)) << 8; + pfalc->bec += counter; + + if (((conf->media == IF_IFACE_T1) && + (cpc_readb(falcbase + F_REG(FRS1, ch)) & FRS1_LLBAD) && + (!(cpc_readb(falcbase + F_REG(FRS1, ch)) & FRS1_PDEN))) || + ((conf->media == IF_IFACE_E1) && + (cpc_readb(falcbase + F_REG(RSP, ch)) & RSP_LLBAD))) { + pfalc->prbs = 2; + } else { + pfalc->prbs = 1; + } + } +} + +/*---------------------------------------------------------------------------- + * falc_remote_loop + *---------------------------------------------------------------------------- + * Description: In the remote loopback mode the clock and data recovered + * from the line inputs RL1/2 or RDIP/RDIN are routed back + * to the line outputs XL1/2 or XDOP/XDON via the analog + * transmitter. As in normal mode they are processed by + * the synchronizer and then sent to the system interface. + *---------------------------------------------------------------------------- + */ +static void falc_remote_loop(pc300_t * card, int ch, int loop_on) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + + if (loop_on) { + // EVENT_FALC_ABNORMAL + if (conf->media == IF_IFACE_T1) { + /* Disable this interrupt as it may otherwise interfere with + * other working boards. */ + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN); + } + falc_disable_comm(card, ch); + // EVENT_FALC_ABNORMAL + cpc_writeb(falcbase + F_REG(LIM1, ch), + cpc_readb(falcbase + F_REG(LIM1, ch)) | LIM1_RL); + pfalc->loop_active = 1; + } else { + cpc_writeb(falcbase + F_REG(LIM1, ch), + cpc_readb(falcbase + F_REG(LIM1, ch)) & ~LIM1_RL); + pfalc->sync = 0; + cpc_writeb(falcbase + card->hw.cpld_reg2, + cpc_readb(falcbase + card->hw.cpld_reg2) & + ~(CPLD_REG2_FALC_LED2 << (2 * ch))); + pfalc->active = 0; + falc_issue_cmd(card, ch, CMDR_XRES); + pfalc->loop_active = 0; + } +} + +/*---------------------------------------------------------------------------- + * falc_local_loop + *---------------------------------------------------------------------------- + * Description: The local loopback mode disconnects the receive lines + * RL1/RL2 resp. RDIP/RDIN from the receiver. Instead of the + * signals coming from the line the data provided by system + * interface are routed through the analog receiver back to + * the system interface. The unipolar bit stream will be + * undisturbed transmitted on the line. Receiver and transmitter + * coding must be identical. + *---------------------------------------------------------------------------- + */ +static void falc_local_loop(pc300_t * card, int ch, int loop_on) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + + if (loop_on) { + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_LL); + pfalc->loop_active = 1; + } else { + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_LL); + pfalc->loop_active = 0; + } +} + +/*---------------------------------------------------------------------------- + * falc_payload_loop + *---------------------------------------------------------------------------- + * Description: This routine allows to enable/disable payload loopback. + * When the payload loop is activated, the received 192 bits + * of payload data will be looped back to the transmit + * direction. The framing bits, CRC6 and DL bits are not + * looped. They are originated by the FALC-LH transmitter. + *---------------------------------------------------------------------------- + */ +static void falc_payload_loop(pc300_t * card, int ch, int loop_on) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + + if (loop_on) { + // EVENT_FALC_ABNORMAL + if (conf->media == IF_IFACE_T1) { + /* Disable this interrupt as it may otherwise interfere with + * other working boards. */ + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN); + } + falc_disable_comm(card, ch); + // EVENT_FALC_ABNORMAL + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_PLB); + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(FMR4, ch), + cpc_readb(falcbase + F_REG(FMR4, ch)) | FMR4_TM); + } else { + cpc_writeb(falcbase + F_REG(FMR5, ch), + cpc_readb(falcbase + F_REG(FMR5, ch)) | XSP_TT0); + } + falc_open_all_timeslots(card, ch); + pfalc->loop_active = 2; + } else { + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_PLB); + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(FMR4, ch), + cpc_readb(falcbase + F_REG(FMR4, ch)) & ~FMR4_TM); + } else { + cpc_writeb(falcbase + F_REG(FMR5, ch), + cpc_readb(falcbase + F_REG(FMR5, ch)) & ~XSP_TT0); + } + pfalc->sync = 0; + cpc_writeb(falcbase + card->hw.cpld_reg2, + cpc_readb(falcbase + card->hw.cpld_reg2) & + ~(CPLD_REG2_FALC_LED2 << (2 * ch))); + pfalc->active = 0; + falc_issue_cmd(card, ch, CMDR_XRES); + pfalc->loop_active = 0; + } +} + +/*---------------------------------------------------------------------------- + * turn_off_xlu + *---------------------------------------------------------------------------- + * Description: Turns XLU bit off in the proper register + *---------------------------------------------------------------------------- + */ +static void turn_off_xlu(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + void __iomem *falcbase = card->hw.falcbase; + + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(FMR5, ch), + cpc_readb(falcbase + F_REG(FMR5, ch)) & ~FMR5_XLU); + } else { + cpc_writeb(falcbase + F_REG(FMR3, ch), + cpc_readb(falcbase + F_REG(FMR3, ch)) & ~FMR3_XLU); + } +} + +/*---------------------------------------------------------------------------- + * turn_off_xld + *---------------------------------------------------------------------------- + * Description: Turns XLD bit off in the proper register + *---------------------------------------------------------------------------- + */ +static void turn_off_xld(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + void __iomem *falcbase = card->hw.falcbase; + + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(FMR5, ch), + cpc_readb(falcbase + F_REG(FMR5, ch)) & ~FMR5_XLD); + } else { + cpc_writeb(falcbase + F_REG(FMR3, ch), + cpc_readb(falcbase + F_REG(FMR3, ch)) & ~FMR3_XLD); + } +} + +/*---------------------------------------------------------------------------- + * falc_generate_loop_up_code + *---------------------------------------------------------------------------- + * Description: This routine writes the proper FALC chip register in order + * to generate a LOOP activation code over a T1/E1 line. + *---------------------------------------------------------------------------- + */ +static void falc_generate_loop_up_code(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(FMR5, ch), + cpc_readb(falcbase + F_REG(FMR5, ch)) | FMR5_XLU); + } else { + cpc_writeb(falcbase + F_REG(FMR3, ch), + cpc_readb(falcbase + F_REG(FMR3, ch)) | FMR3_XLU); + } + // EVENT_FALC_ABNORMAL + if (conf->media == IF_IFACE_T1) { + /* Disable this interrupt as it may otherwise interfere with + * other working boards. */ + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN); + } + falc_disable_comm(card, ch); + // EVENT_FALC_ABNORMAL + pfalc->loop_gen = 1; +} + +/*---------------------------------------------------------------------------- + * falc_generate_loop_down_code + *---------------------------------------------------------------------------- + * Description: This routine writes the proper FALC chip register in order + * to generate a LOOP deactivation code over a T1/E1 line. + *---------------------------------------------------------------------------- + */ +static void falc_generate_loop_down_code(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(FMR5, ch), + cpc_readb(falcbase + F_REG(FMR5, ch)) | FMR5_XLD); + } else { + cpc_writeb(falcbase + F_REG(FMR3, ch), + cpc_readb(falcbase + F_REG(FMR3, ch)) | FMR3_XLD); + } + pfalc->sync = 0; + cpc_writeb(falcbase + card->hw.cpld_reg2, + cpc_readb(falcbase + card->hw.cpld_reg2) & + ~(CPLD_REG2_FALC_LED2 << (2 * ch))); + pfalc->active = 0; +//? falc_issue_cmd(card, ch, CMDR_XRES); + pfalc->loop_gen = 0; +} + +/*---------------------------------------------------------------------------- + * falc_pattern_test + *---------------------------------------------------------------------------- + * Description: This routine generates a pattern code and checks + * it on the reception side. + *---------------------------------------------------------------------------- + */ +static void falc_pattern_test(pc300_t * card, int ch, unsigned int activate) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + + if (activate) { + pfalc->prbs = 1; + pfalc->bec = 0; + if (conf->media == IF_IFACE_T1) { + /* Disable local loop activation/deactivation detect */ + cpc_writeb(falcbase + F_REG(IMR3, ch), + cpc_readb(falcbase + F_REG(IMR3, ch)) | IMR3_LLBSC); + } else { + /* Disable local loop activation/deactivation detect */ + cpc_writeb(falcbase + F_REG(IMR1, ch), + cpc_readb(falcbase + F_REG(IMR1, ch)) | IMR1_LLBSC); + } + /* Activates generation and monitoring of PRBS + * (Pseudo Random Bit Sequence) */ + cpc_writeb(falcbase + F_REG(LCR1, ch), + cpc_readb(falcbase + F_REG(LCR1, ch)) | LCR1_EPRM | LCR1_XPRBS); + } else { + pfalc->prbs = 0; + /* Deactivates generation and monitoring of PRBS + * (Pseudo Random Bit Sequence) */ + cpc_writeb(falcbase + F_REG(LCR1, ch), + cpc_readb(falcbase+F_REG(LCR1,ch)) & ~(LCR1_EPRM | LCR1_XPRBS)); + if (conf->media == IF_IFACE_T1) { + /* Enable local loop activation/deactivation detect */ + cpc_writeb(falcbase + F_REG(IMR3, ch), + cpc_readb(falcbase + F_REG(IMR3, ch)) & ~IMR3_LLBSC); + } else { + /* Enable local loop activation/deactivation detect */ + cpc_writeb(falcbase + F_REG(IMR1, ch), + cpc_readb(falcbase + F_REG(IMR1, ch)) & ~IMR1_LLBSC); + } + } +} + +/*---------------------------------------------------------------------------- + * falc_pattern_test_error + *---------------------------------------------------------------------------- + * Description: This routine returns the bit error counter value + *---------------------------------------------------------------------------- + */ +static u16 falc_pattern_test_error(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + + return pfalc->bec; +} + +/**********************************/ +/*** Net Interface Routines ***/ +/**********************************/ + +static void +cpc_trace(struct net_device *dev, struct sk_buff *skb_main, char rx_tx) +{ + struct sk_buff *skb; + + if ((skb = dev_alloc_skb(10 + skb_main->len)) == NULL) { + printk("%s: out of memory\n", dev->name); + return; + } + skb_put(skb, 10 + skb_main->len); + + skb->dev = dev; + skb->protocol = htons(ETH_P_CUST); + skb_reset_mac_header(skb); + skb->pkt_type = PACKET_HOST; + skb->len = 10 + skb_main->len; + + skb_copy_to_linear_data(skb, dev->name, 5); + skb->data[5] = '['; + skb->data[6] = rx_tx; + skb->data[7] = ']'; + skb->data[8] = ':'; + skb->data[9] = ' '; + skb_copy_from_linear_data(skb_main, &skb->data[10], skb_main->len); + + netif_rx(skb); +} + +static void cpc_tx_timeout(struct net_device *dev) +{ + pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv; + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + int ch = chan->channel; + unsigned long flags; + u8 ilar; + + dev->stats.tx_errors++; + dev->stats.tx_aborted_errors++; + CPC_LOCK(card, flags); + if ((ilar = cpc_readb(card->hw.scabase + ILAR)) != 0) { + printk("%s: ILAR=0x%x\n", dev->name, ilar); + cpc_writeb(card->hw.scabase + ILAR, ilar); + cpc_writeb(card->hw.scabase + DMER, 0x80); + } + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) & + ~(CPLD_REG2_FALC_LED1 << (2 * ch))); + } + dev->trans_start = jiffies; /* prevent tx timeout */ + CPC_UNLOCK(card, flags); + netif_wake_queue(dev); +} + +static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev) +{ + pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv; + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + int ch = chan->channel; + unsigned long flags; +#ifdef PC300_DEBUG_TX + int i; +#endif + + if (!netif_carrier_ok(dev)) { + /* DCD must be OFF: drop packet */ + dev_kfree_skb(skb); + dev->stats.tx_errors++; + dev->stats.tx_carrier_errors++; + return 0; + } else if (cpc_readb(card->hw.scabase + M_REG(ST3, ch)) & ST3_DCD) { + printk("%s: DCD is OFF. Going administrative down.\n", dev->name); + dev->stats.tx_errors++; + dev->stats.tx_carrier_errors++; + dev_kfree_skb(skb); + netif_carrier_off(dev); + CPC_LOCK(card, flags); + cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_BUF_CLR); + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) & + ~(CPLD_REG2_FALC_LED1 << (2 * ch))); + } + CPC_UNLOCK(card, flags); + netif_wake_queue(dev); + return 0; + } + + /* Write buffer to DMA buffers */ + if (dma_buf_write(card, ch, (u8 *)skb->data, skb->len) != 0) { +// printk("%s: write error. Dropping TX packet.\n", dev->name); + netif_stop_queue(dev); + dev_kfree_skb(skb); + dev->stats.tx_errors++; + dev->stats.tx_dropped++; + return 0; + } +#ifdef PC300_DEBUG_TX + printk("%s T:", dev->name); + for (i = 0; i < skb->len; i++) + printk(" %02x", *(skb->data + i)); + printk("\n"); +#endif + + if (d->trace_on) { + cpc_trace(dev, skb, 'T'); + } + + /* Start transmission */ + CPC_LOCK(card, flags); + /* verify if it has more than one free descriptor */ + if (card->chan[ch].nfree_tx_bd <= 1) { + /* don't have so stop the queue */ + netif_stop_queue(dev); + } + cpc_writel(card->hw.scabase + DTX_REG(EDAL, ch), + TX_BD_ADDR(ch, chan->tx_next_bd)); + cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_ENA); + cpc_writeb(card->hw.scabase + DSR_TX(ch), DSR_DE); + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) | + (CPLD_REG2_FALC_LED1 << (2 * ch))); + } + CPC_UNLOCK(card, flags); + dev_kfree_skb(skb); + + return 0; +} + +static void cpc_net_rx(struct net_device *dev) +{ + pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv; + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + int ch = chan->channel; +#ifdef PC300_DEBUG_RX + int i; +#endif + int rxb; + struct sk_buff *skb; + + while (1) { + if ((rxb = dma_get_rx_frame_size(card, ch)) == -1) + return; + + if (!netif_carrier_ok(dev)) { + /* DCD must be OFF: drop packet */ + printk("%s : DCD is OFF - drop %d rx bytes\n", dev->name, rxb); + skb = NULL; + } else { + if (rxb > (dev->mtu + 40)) { /* add headers */ + printk("%s : MTU exceeded %d\n", dev->name, rxb); + skb = NULL; + } else { + skb = dev_alloc_skb(rxb); + if (skb == NULL) { + printk("%s: Memory squeeze!!\n", dev->name); + return; + } + skb->dev = dev; + } + } + + if (((rxb = dma_buf_read(card, ch, skb)) <= 0) || (skb == NULL)) { +#ifdef PC300_DEBUG_RX + printk("%s: rxb = %x\n", dev->name, rxb); +#endif + if ((skb == NULL) && (rxb > 0)) { + /* rxb > dev->mtu */ + dev->stats.rx_errors++; + dev->stats.rx_length_errors++; + continue; + } + + if (rxb < 0) { /* Invalid frame */ + rxb = -rxb; + if (rxb & DST_OVR) { + dev->stats.rx_errors++; + dev->stats.rx_fifo_errors++; + } + if (rxb & DST_CRC) { + dev->stats.rx_errors++; + dev->stats.rx_crc_errors++; + } + if (rxb & (DST_RBIT | DST_SHRT | DST_ABT)) { + dev->stats.rx_errors++; + dev->stats.rx_frame_errors++; + } + } + if (skb) { + dev_kfree_skb_irq(skb); + } + continue; + } + + dev->stats.rx_bytes += rxb; + +#ifdef PC300_DEBUG_RX + printk("%s R:", dev->name); + for (i = 0; i < skb->len; i++) + printk(" %02x", *(skb->data + i)); + printk("\n"); +#endif + if (d->trace_on) { + cpc_trace(dev, skb, 'R'); + } + dev->stats.rx_packets++; + skb->protocol = hdlc_type_trans(skb, dev); + netif_rx(skb); + } +} + +/************************************/ +/*** PC300 Interrupt Routines ***/ +/************************************/ +static void sca_tx_intr(pc300dev_t *dev) +{ + pc300ch_t *chan = (pc300ch_t *)dev->chan; + pc300_t *card = (pc300_t *)chan->card; + int ch = chan->channel; + volatile pcsca_bd_t __iomem * ptdescr; + + /* Clean up descriptors from previous transmission */ + ptdescr = (card->hw.rambase + + TX_BD_ADDR(ch,chan->tx_first_bd)); + while ((cpc_readl(card->hw.scabase + DTX_REG(CDAL,ch)) != + TX_BD_ADDR(ch,chan->tx_first_bd)) && + (cpc_readb(&ptdescr->status) & DST_OSB)) { + dev->dev->stats.tx_packets++; + dev->dev->stats.tx_bytes += cpc_readw(&ptdescr->len); + cpc_writeb(&ptdescr->status, DST_OSB); + cpc_writew(&ptdescr->len, 0); + chan->nfree_tx_bd++; + chan->tx_first_bd = (chan->tx_first_bd + 1) & (N_DMA_TX_BUF - 1); + ptdescr = (card->hw.rambase + TX_BD_ADDR(ch,chan->tx_first_bd)); + } + +#ifdef CONFIG_PC300_MLPPP + if (chan->conf.proto == PC300_PROTO_MLPPP) { + cpc_tty_trigger_poll(dev); + } else { +#endif + /* Tell the upper layer we are ready to transmit more packets */ + netif_wake_queue(dev->dev); +#ifdef CONFIG_PC300_MLPPP + } +#endif +} + +static void sca_intr(pc300_t * card) +{ + void __iomem *scabase = card->hw.scabase; + volatile u32 status; + int ch; + int intr_count = 0; + unsigned char dsr_rx; + + while ((status = cpc_readl(scabase + ISR0)) != 0) { + for (ch = 0; ch < card->hw.nchan; ch++) { + pc300ch_t *chan = &card->chan[ch]; + pc300dev_t *d = &chan->d; + struct net_device *dev = d->dev; + + spin_lock(&card->card_lock); + + /**** Reception ****/ + if (status & IR0_DRX((IR0_DMIA | IR0_DMIB), ch)) { + u8 drx_stat = cpc_readb(scabase + DSR_RX(ch)); + + /* Clear RX interrupts */ + cpc_writeb(scabase + DSR_RX(ch), drx_stat | DSR_DWE); + +#ifdef PC300_DEBUG_INTR + printk ("sca_intr: RX intr chan[%d] (st=0x%08lx, dsr=0x%02x)\n", + ch, status, drx_stat); +#endif + if (status & IR0_DRX(IR0_DMIA, ch)) { + if (drx_stat & DSR_BOF) { +#ifdef CONFIG_PC300_MLPPP + if (chan->conf.proto == PC300_PROTO_MLPPP) { + /* verify if driver is TTY */ + if ((cpc_readb(scabase + DSR_RX(ch)) & DSR_DE)) { + rx_dma_stop(card, ch); + } + cpc_tty_receive(d); + rx_dma_start(card, ch); + } else +#endif + { + if ((cpc_readb(scabase + DSR_RX(ch)) & DSR_DE)) { + rx_dma_stop(card, ch); + } + cpc_net_rx(dev); + /* Discard invalid frames */ + dev->stats.rx_errors++; + dev->stats.rx_over_errors++; + chan->rx_first_bd = 0; + chan->rx_last_bd = N_DMA_RX_BUF - 1; + rx_dma_start(card, ch); + } + } + } + if (status & IR0_DRX(IR0_DMIB, ch)) { + if (drx_stat & DSR_EOM) { + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + + card->hw.cpld_reg2, + cpc_readb (card->hw.falcbase + + card->hw.cpld_reg2) | + (CPLD_REG2_FALC_LED1 << (2 * ch))); + } +#ifdef CONFIG_PC300_MLPPP + if (chan->conf.proto == PC300_PROTO_MLPPP) { + /* verify if driver is TTY */ + cpc_tty_receive(d); + } else { + cpc_net_rx(dev); + } +#else + cpc_net_rx(dev); +#endif + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + + card->hw.cpld_reg2, + cpc_readb (card->hw.falcbase + + card->hw.cpld_reg2) & + ~ (CPLD_REG2_FALC_LED1 << (2 * ch))); + } + } + } + if (!(dsr_rx = cpc_readb(scabase + DSR_RX(ch)) & DSR_DE)) { +#ifdef PC300_DEBUG_INTR + printk("%s: RX intr chan[%d] (st=0x%08lx, dsr=0x%02x, dsr2=0x%02x)\n", + dev->name, ch, status, drx_stat, dsr_rx); +#endif + cpc_writeb(scabase + DSR_RX(ch), (dsr_rx | DSR_DE) & 0xfe); + } + } + + /**** Transmission ****/ + if (status & IR0_DTX((IR0_EFT | IR0_DMIA | IR0_DMIB), ch)) { + u8 dtx_stat = cpc_readb(scabase + DSR_TX(ch)); + + /* Clear TX interrupts */ + cpc_writeb(scabase + DSR_TX(ch), dtx_stat | DSR_DWE); + +#ifdef PC300_DEBUG_INTR + printk ("sca_intr: TX intr chan[%d] (st=0x%08lx, dsr=0x%02x)\n", + ch, status, dtx_stat); +#endif + if (status & IR0_DTX(IR0_EFT, ch)) { + if (dtx_stat & DSR_UDRF) { + if (cpc_readb (scabase + M_REG(TBN, ch)) != 0) { + cpc_writeb(scabase + M_REG(CMD,ch), CMD_TX_BUF_CLR); + } + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb (card->hw.falcbase + + card->hw.cpld_reg2) & + ~ (CPLD_REG2_FALC_LED1 << (2 * ch))); + } + dev->stats.tx_errors++; + dev->stats.tx_fifo_errors++; + sca_tx_intr(d); + } + } + if (status & IR0_DTX(IR0_DMIA, ch)) { + if (dtx_stat & DSR_BOF) { + } + } + if (status & IR0_DTX(IR0_DMIB, ch)) { + if (dtx_stat & DSR_EOM) { + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb (card->hw.falcbase + + card->hw.cpld_reg2) & + ~ (CPLD_REG2_FALC_LED1 << (2 * ch))); + } + sca_tx_intr(d); + } + } + } + + /**** MSCI ****/ + if (status & IR0_M(IR0_RXINTA, ch)) { + u8 st1 = cpc_readb(scabase + M_REG(ST1, ch)); + + /* Clear MSCI interrupts */ + cpc_writeb(scabase + M_REG(ST1, ch), st1); + +#ifdef PC300_DEBUG_INTR + printk("sca_intr: MSCI intr chan[%d] (st=0x%08lx, st1=0x%02x)\n", + ch, status, st1); +#endif + if (st1 & ST1_CDCD) { /* DCD changed */ + if (cpc_readb(scabase + M_REG(ST3, ch)) & ST3_DCD) { + printk ("%s: DCD is OFF. Going administrative down.\n", + dev->name); +#ifdef CONFIG_PC300_MLPPP + if (chan->conf.proto != PC300_PROTO_MLPPP) { + netif_carrier_off(dev); + } +#else + netif_carrier_off(dev); + +#endif + card->chan[ch].d.line_off++; + } else { /* DCD = 1 */ + printk ("%s: DCD is ON. Going administrative up.\n", + dev->name); +#ifdef CONFIG_PC300_MLPPP + if (chan->conf.proto != PC300_PROTO_MLPPP) + /* verify if driver is not TTY */ +#endif + netif_carrier_on(dev); + card->chan[ch].d.line_on++; + } + } + } + spin_unlock(&card->card_lock); + } + if (++intr_count == 10) + /* Too much work at this board. Force exit */ + break; + } +} + +static void falc_t1_loop_detection(pc300_t *card, int ch, u8 frs1) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + + if (((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_XPRBS) == 0) && + !pfalc->loop_gen) { + if (frs1 & FRS1_LLBDD) { + // A Line Loop Back Deactivation signal detected + if (pfalc->loop_active) { + falc_remote_loop(card, ch, 0); + } + } else { + if ((frs1 & FRS1_LLBAD) && + ((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_EPRM) == 0)) { + // A Line Loop Back Activation signal detected + if (!pfalc->loop_active) { + falc_remote_loop(card, ch, 1); + } + } + } + } +} + +static void falc_e1_loop_detection(pc300_t *card, int ch, u8 rsp) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + + if (((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_XPRBS) == 0) && + !pfalc->loop_gen) { + if (rsp & RSP_LLBDD) { + // A Line Loop Back Deactivation signal detected + if (pfalc->loop_active) { + falc_remote_loop(card, ch, 0); + } + } else { + if ((rsp & RSP_LLBAD) && + ((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_EPRM) == 0)) { + // A Line Loop Back Activation signal detected + if (!pfalc->loop_active) { + falc_remote_loop(card, ch, 1); + } + } + } + } +} + +static void falc_t1_intr(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + u8 isr0, isr3, gis; + u8 dummy; + + while ((gis = cpc_readb(falcbase + F_REG(GIS, ch))) != 0) { + if (gis & GIS_ISR0) { + isr0 = cpc_readb(falcbase + F_REG(FISR0, ch)); + if (isr0 & FISR0_PDEN) { + /* Read the bit to clear the situation */ + if (cpc_readb(falcbase + F_REG(FRS1, ch)) & + FRS1_PDEN) { + pfalc->pden++; + } + } + } + + if (gis & GIS_ISR1) { + dummy = cpc_readb(falcbase + F_REG(FISR1, ch)); + } + + if (gis & GIS_ISR2) { + dummy = cpc_readb(falcbase + F_REG(FISR2, ch)); + } + + if (gis & GIS_ISR3) { + isr3 = cpc_readb(falcbase + F_REG(FISR3, ch)); + if (isr3 & FISR3_SEC) { + pfalc->sec++; + falc_update_stats(card, ch); + falc_check_status(card, ch, + cpc_readb(falcbase + F_REG(FRS0, ch))); + } + if (isr3 & FISR3_ES) { + pfalc->es++; + } + if (isr3 & FISR3_LLBSC) { + falc_t1_loop_detection(card, ch, + cpc_readb(falcbase + F_REG(FRS1, ch))); + } + } + } +} + +static void falc_e1_intr(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + u8 isr1, isr2, isr3, gis, rsp; + u8 dummy; + + while ((gis = cpc_readb(falcbase + F_REG(GIS, ch))) != 0) { + rsp = cpc_readb(falcbase + F_REG(RSP, ch)); + + if (gis & GIS_ISR0) { + dummy = cpc_readb(falcbase + F_REG(FISR0, ch)); + } + if (gis & GIS_ISR1) { + isr1 = cpc_readb(falcbase + F_REG(FISR1, ch)); + if (isr1 & FISR1_XMB) { + if ((pfalc->xmb_cause & 2) && + pfalc->multiframe_mode) { + if (cpc_readb (falcbase + F_REG(FRS0, ch)) & + (FRS0_LOS | FRS0_AIS | FRS0_LFA)) { + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) + & ~XSP_AXS); + } else { + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) + | XSP_AXS); + } + } + pfalc->xmb_cause = 0; + cpc_writeb(falcbase + F_REG(IMR1, ch), + cpc_readb(falcbase + F_REG(IMR1, ch)) | IMR1_XMB); + } + if (isr1 & FISR1_LLBSC) { + falc_e1_loop_detection(card, ch, rsp); + } + } + if (gis & GIS_ISR2) { + isr2 = cpc_readb(falcbase + F_REG(FISR2, ch)); + if (isr2 & FISR2_T400MS) { + cpc_writeb(falcbase + F_REG(XSW, ch), + cpc_readb(falcbase + F_REG(XSW, ch)) | XSW_XRA); + } + if (isr2 & FISR2_MFAR) { + cpc_writeb(falcbase + F_REG(XSW, ch), + cpc_readb(falcbase + F_REG(XSW, ch)) & ~XSW_XRA); + } + if (isr2 & (FISR2_FAR | FISR2_LFA | FISR2_AIS | FISR2_LOS)) { + pfalc->xmb_cause |= 2; + cpc_writeb(falcbase + F_REG(IMR1, ch), + cpc_readb(falcbase + F_REG(IMR1, ch)) & ~IMR1_XMB); + } + } + if (gis & GIS_ISR3) { + isr3 = cpc_readb(falcbase + F_REG(FISR3, ch)); + if (isr3 & FISR3_SEC) { + pfalc->sec++; + falc_update_stats(card, ch); + falc_check_status(card, ch, + cpc_readb(falcbase + F_REG(FRS0, ch))); + } + if (isr3 & FISR3_ES) { + pfalc->es++; + } + } + } +} + +static void falc_intr(pc300_t * card) +{ + int ch; + + for (ch = 0; ch < card->hw.nchan; ch++) { + pc300ch_t *chan = &card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + + if (conf->media == IF_IFACE_T1) { + falc_t1_intr(card, ch); + } else { + falc_e1_intr(card, ch); + } + } +} + +static irqreturn_t cpc_intr(int irq, void *dev_id) +{ + pc300_t *card = dev_id; + volatile u8 plx_status; + + if (!card) { +#ifdef PC300_DEBUG_INTR + printk("cpc_intr: spurious intr %d\n", irq); +#endif + return IRQ_NONE; /* spurious intr */ + } + + if (!card->hw.rambase) { +#ifdef PC300_DEBUG_INTR + printk("cpc_intr: spurious intr2 %d\n", irq); +#endif + return IRQ_NONE; /* spurious intr */ + } + + switch (card->hw.type) { + case PC300_RSV: + case PC300_X21: + sca_intr(card); + break; + + case PC300_TE: + while ( (plx_status = (cpc_readb(card->hw.plxbase + card->hw.intctl_reg) & + (PLX_9050_LINT1_STATUS | PLX_9050_LINT2_STATUS))) != 0) { + if (plx_status & PLX_9050_LINT1_STATUS) { /* SCA Interrupt */ + sca_intr(card); + } + if (plx_status & PLX_9050_LINT2_STATUS) { /* FALC Interrupt */ + falc_intr(card); + } + } + break; + } + return IRQ_HANDLED; +} + +static void cpc_sca_status(pc300_t * card, int ch) +{ + u8 ilar; + void __iomem *scabase = card->hw.scabase; + unsigned long flags; + + tx_dma_buf_check(card, ch); + rx_dma_buf_check(card, ch); + ilar = cpc_readb(scabase + ILAR); + printk ("ILAR=0x%02x, WCRL=0x%02x, PCR=0x%02x, BTCR=0x%02x, BOLR=0x%02x\n", + ilar, cpc_readb(scabase + WCRL), cpc_readb(scabase + PCR), + cpc_readb(scabase + BTCR), cpc_readb(scabase + BOLR)); + printk("TX_CDA=0x%08x, TX_EDA=0x%08x\n", + cpc_readl(scabase + DTX_REG(CDAL, ch)), + cpc_readl(scabase + DTX_REG(EDAL, ch))); + printk("RX_CDA=0x%08x, RX_EDA=0x%08x, BFL=0x%04x\n", + cpc_readl(scabase + DRX_REG(CDAL, ch)), + cpc_readl(scabase + DRX_REG(EDAL, ch)), + cpc_readw(scabase + DRX_REG(BFLL, ch))); + printk("DMER=0x%02x, DSR_TX=0x%02x, DSR_RX=0x%02x\n", + cpc_readb(scabase + DMER), cpc_readb(scabase + DSR_TX(ch)), + cpc_readb(scabase + DSR_RX(ch))); + printk("DMR_TX=0x%02x, DMR_RX=0x%02x, DIR_TX=0x%02x, DIR_RX=0x%02x\n", + cpc_readb(scabase + DMR_TX(ch)), cpc_readb(scabase + DMR_RX(ch)), + cpc_readb(scabase + DIR_TX(ch)), + cpc_readb(scabase + DIR_RX(ch))); + printk("DCR_TX=0x%02x, DCR_RX=0x%02x, FCT_TX=0x%02x, FCT_RX=0x%02x\n", + cpc_readb(scabase + DCR_TX(ch)), cpc_readb(scabase + DCR_RX(ch)), + cpc_readb(scabase + FCT_TX(ch)), + cpc_readb(scabase + FCT_RX(ch))); + printk("MD0=0x%02x, MD1=0x%02x, MD2=0x%02x, MD3=0x%02x, IDL=0x%02x\n", + cpc_readb(scabase + M_REG(MD0, ch)), + cpc_readb(scabase + M_REG(MD1, ch)), + cpc_readb(scabase + M_REG(MD2, ch)), + cpc_readb(scabase + M_REG(MD3, ch)), + cpc_readb(scabase + M_REG(IDL, ch))); + printk("CMD=0x%02x, SA0=0x%02x, SA1=0x%02x, TFN=0x%02x, CTL=0x%02x\n", + cpc_readb(scabase + M_REG(CMD, ch)), + cpc_readb(scabase + M_REG(SA0, ch)), + cpc_readb(scabase + M_REG(SA1, ch)), + cpc_readb(scabase + M_REG(TFN, ch)), + cpc_readb(scabase + M_REG(CTL, ch))); + printk("ST0=0x%02x, ST1=0x%02x, ST2=0x%02x, ST3=0x%02x, ST4=0x%02x\n", + cpc_readb(scabase + M_REG(ST0, ch)), + cpc_readb(scabase + M_REG(ST1, ch)), + cpc_readb(scabase + M_REG(ST2, ch)), + cpc_readb(scabase + M_REG(ST3, ch)), + cpc_readb(scabase + M_REG(ST4, ch))); + printk ("CST0=0x%02x, CST1=0x%02x, CST2=0x%02x, CST3=0x%02x, FST=0x%02x\n", + cpc_readb(scabase + M_REG(CST0, ch)), + cpc_readb(scabase + M_REG(CST1, ch)), + cpc_readb(scabase + M_REG(CST2, ch)), + cpc_readb(scabase + M_REG(CST3, ch)), + cpc_readb(scabase + M_REG(FST, ch))); + printk("TRC0=0x%02x, TRC1=0x%02x, RRC=0x%02x, TBN=0x%02x, RBN=0x%02x\n", + cpc_readb(scabase + M_REG(TRC0, ch)), + cpc_readb(scabase + M_REG(TRC1, ch)), + cpc_readb(scabase + M_REG(RRC, ch)), + cpc_readb(scabase + M_REG(TBN, ch)), + cpc_readb(scabase + M_REG(RBN, ch))); + printk("TFS=0x%02x, TNR0=0x%02x, TNR1=0x%02x, RNR=0x%02x\n", + cpc_readb(scabase + M_REG(TFS, ch)), + cpc_readb(scabase + M_REG(TNR0, ch)), + cpc_readb(scabase + M_REG(TNR1, ch)), + cpc_readb(scabase + M_REG(RNR, ch))); + printk("TCR=0x%02x, RCR=0x%02x, TNR1=0x%02x, RNR=0x%02x\n", + cpc_readb(scabase + M_REG(TCR, ch)), + cpc_readb(scabase + M_REG(RCR, ch)), + cpc_readb(scabase + M_REG(TNR1, ch)), + cpc_readb(scabase + M_REG(RNR, ch))); + printk("TXS=0x%02x, RXS=0x%02x, EXS=0x%02x, TMCT=0x%02x, TMCR=0x%02x\n", + cpc_readb(scabase + M_REG(TXS, ch)), + cpc_readb(scabase + M_REG(RXS, ch)), + cpc_readb(scabase + M_REG(EXS, ch)), + cpc_readb(scabase + M_REG(TMCT, ch)), + cpc_readb(scabase + M_REG(TMCR, ch))); + printk("IE0=0x%02x, IE1=0x%02x, IE2=0x%02x, IE4=0x%02x, FIE=0x%02x\n", + cpc_readb(scabase + M_REG(IE0, ch)), + cpc_readb(scabase + M_REG(IE1, ch)), + cpc_readb(scabase + M_REG(IE2, ch)), + cpc_readb(scabase + M_REG(IE4, ch)), + cpc_readb(scabase + M_REG(FIE, ch))); + printk("IER0=0x%08x\n", cpc_readl(scabase + IER0)); + + if (ilar != 0) { + CPC_LOCK(card, flags); + cpc_writeb(scabase + ILAR, ilar); + cpc_writeb(scabase + DMER, 0x80); + CPC_UNLOCK(card, flags); + } +} + +static void cpc_falc_status(pc300_t * card, int ch) +{ + pc300ch_t *chan = &card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + unsigned long flags; + + CPC_LOCK(card, flags); + printk("CH%d: %s %s %d channels\n", + ch, (pfalc->sync ? "SYNC" : ""), (pfalc->active ? "ACTIVE" : ""), + pfalc->num_channels); + + printk(" pden=%d, los=%d, losr=%d, lfa=%d, farec=%d\n", + pfalc->pden, pfalc->los, pfalc->losr, pfalc->lfa, pfalc->farec); + printk(" lmfa=%d, ais=%d, sec=%d, es=%d, rai=%d\n", + pfalc->lmfa, pfalc->ais, pfalc->sec, pfalc->es, pfalc->rai); + printk(" bec=%d, fec=%d, cvc=%d, cec=%d, ebc=%d\n", + pfalc->bec, pfalc->fec, pfalc->cvc, pfalc->cec, pfalc->ebc); + + printk("\n"); + printk(" STATUS: %s %s %s %s %s %s\n", + (pfalc->red_alarm ? "RED" : ""), + (pfalc->blue_alarm ? "BLU" : ""), + (pfalc->yellow_alarm ? "YEL" : ""), + (pfalc->loss_fa ? "LFA" : ""), + (pfalc->loss_mfa ? "LMF" : ""), (pfalc->prbs ? "PRB" : "")); + CPC_UNLOCK(card, flags); +} + +static int cpc_change_mtu(struct net_device *dev, int new_mtu) +{ + if ((new_mtu < 128) || (new_mtu > PC300_DEF_MTU)) + return -EINVAL; + dev->mtu = new_mtu; + return 0; +} + +static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv; + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + pc300conf_t conf_aux; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + int ch = chan->channel; + void __user *arg = ifr->ifr_data; + struct if_settings *settings = &ifr->ifr_settings; + void __iomem *scabase = card->hw.scabase; + + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + switch (cmd) { + case SIOCGPC300CONF: +#ifdef CONFIG_PC300_MLPPP + if (conf->proto != PC300_PROTO_MLPPP) { + conf->proto = /* FIXME hdlc->proto.id */ 0; + } +#else + conf->proto = /* FIXME hdlc->proto.id */ 0; +#endif + memcpy(&conf_aux.conf, conf, sizeof(pc300chconf_t)); + memcpy(&conf_aux.hw, &card->hw, sizeof(pc300hw_t)); + if (!arg || + copy_to_user(arg, &conf_aux, sizeof(pc300conf_t))) + return -EINVAL; + return 0; + case SIOCSPC300CONF: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (!arg || + copy_from_user(&conf_aux.conf, arg, sizeof(pc300chconf_t))) + return -EINVAL; + if (card->hw.cpld_id < 0x02 && + conf_aux.conf.fr_mode == PC300_FR_UNFRAMED) { + /* CPLD_ID < 0x02 doesn't support Unframed E1 */ + return -EINVAL; + } +#ifdef CONFIG_PC300_MLPPP + if (conf_aux.conf.proto == PC300_PROTO_MLPPP) { + if (conf->proto != PC300_PROTO_MLPPP) { + memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t)); + cpc_tty_init(d); /* init TTY driver */ + } + } else { + if (conf_aux.conf.proto == 0xffff) { + if (conf->proto == PC300_PROTO_MLPPP){ + /* ifdown interface */ + cpc_close(dev); + } + } else { + memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t)); + /* FIXME hdlc->proto.id = conf->proto; */ + } + } +#else + memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t)); + /* FIXME hdlc->proto.id = conf->proto; */ +#endif + return 0; + case SIOCGPC300STATUS: + cpc_sca_status(card, ch); + return 0; + case SIOCGPC300FALCSTATUS: + cpc_falc_status(card, ch); + return 0; + + case SIOCGPC300UTILSTATS: + { + if (!arg) { /* clear statistics */ + memset(&dev->stats, 0, sizeof(dev->stats)); + if (card->hw.type == PC300_TE) { + memset(&chan->falc, 0, sizeof(falc_t)); + } + } else { + pc300stats_t pc300stats; + + memset(&pc300stats, 0, sizeof(pc300stats_t)); + pc300stats.hw_type = card->hw.type; + pc300stats.line_on = card->chan[ch].d.line_on; + pc300stats.line_off = card->chan[ch].d.line_off; + memcpy(&pc300stats.gen_stats, &dev->stats, + sizeof(dev->stats)); + if (card->hw.type == PC300_TE) + memcpy(&pc300stats.te_stats,&chan->falc,sizeof(falc_t)); + if (copy_to_user(arg, &pc300stats, sizeof(pc300stats_t))) + return -EFAULT; + } + return 0; + } + + case SIOCGPC300UTILSTATUS: + { + struct pc300status pc300status; + + pc300status.hw_type = card->hw.type; + if (card->hw.type == PC300_TE) { + pc300status.te_status.sync = chan->falc.sync; + pc300status.te_status.red_alarm = chan->falc.red_alarm; + pc300status.te_status.blue_alarm = chan->falc.blue_alarm; + pc300status.te_status.loss_fa = chan->falc.loss_fa; + pc300status.te_status.yellow_alarm =chan->falc.yellow_alarm; + pc300status.te_status.loss_mfa = chan->falc.loss_mfa; + pc300status.te_status.prbs = chan->falc.prbs; + } else { + pc300status.gen_status.dcd = + !(cpc_readb (scabase + M_REG(ST3, ch)) & ST3_DCD); + pc300status.gen_status.cts = + !(cpc_readb (scabase + M_REG(ST3, ch)) & ST3_CTS); + pc300status.gen_status.rts = + !(cpc_readb (scabase + M_REG(CTL, ch)) & CTL_RTS); + pc300status.gen_status.dtr = + !(cpc_readb (scabase + M_REG(CTL, ch)) & CTL_DTR); + /* There is no DSR in HD64572 */ + } + if (!arg || + copy_to_user(arg, &pc300status, sizeof(pc300status_t))) + return -EINVAL; + return 0; + } + + case SIOCSPC300TRACE: + /* Sets/resets a trace_flag for the respective device */ + if (!arg || copy_from_user(&d->trace_on, arg,sizeof(unsigned char))) + return -EINVAL; + return 0; + + case SIOCSPC300LOOPBACK: + { + struct pc300loopback pc300loop; + + /* TE boards only */ + if (card->hw.type != PC300_TE) + return -EINVAL; + + if (!arg || + copy_from_user(&pc300loop, arg, sizeof(pc300loopback_t))) + return -EINVAL; + switch (pc300loop.loop_type) { + case PC300LOCLOOP: /* Turn the local loop on/off */ + falc_local_loop(card, ch, pc300loop.loop_on); + return 0; + + case PC300REMLOOP: /* Turn the remote loop on/off */ + falc_remote_loop(card, ch, pc300loop.loop_on); + return 0; + + case PC300PAYLOADLOOP: /* Turn the payload loop on/off */ + falc_payload_loop(card, ch, pc300loop.loop_on); + return 0; + + case PC300GENLOOPUP: /* Generate loop UP */ + if (pc300loop.loop_on) { + falc_generate_loop_up_code (card, ch); + } else { + turn_off_xlu(card, ch); + } + return 0; + + case PC300GENLOOPDOWN: /* Generate loop DOWN */ + if (pc300loop.loop_on) { + falc_generate_loop_down_code (card, ch); + } else { + turn_off_xld(card, ch); + } + return 0; + + default: + return -EINVAL; + } + } + + case SIOCSPC300PATTERNTEST: + /* Turn the pattern test on/off and show the errors counter */ + { + struct pc300patterntst pc300patrntst; + + /* TE boards only */ + if (card->hw.type != PC300_TE) + return -EINVAL; + + if (card->hw.cpld_id < 0x02) { + /* CPLD_ID < 0x02 doesn't support pattern test */ + return -EINVAL; + } + + if (!arg || + copy_from_user(&pc300patrntst,arg,sizeof(pc300patterntst_t))) + return -EINVAL; + if (pc300patrntst.patrntst_on == 2) { + if (chan->falc.prbs == 0) { + falc_pattern_test(card, ch, 1); + } + pc300patrntst.num_errors = + falc_pattern_test_error(card, ch); + if (copy_to_user(arg, &pc300patrntst, + sizeof(pc300patterntst_t))) + return -EINVAL; + } else { + falc_pattern_test(card, ch, pc300patrntst.patrntst_on); + } + return 0; + } + + case SIOCWANDEV: + switch (ifr->ifr_settings.type) { + case IF_GET_IFACE: + { + const size_t size = sizeof(sync_serial_settings); + ifr->ifr_settings.type = conf->media; + if (ifr->ifr_settings.size < size) { + /* data size wanted */ + ifr->ifr_settings.size = size; + return -ENOBUFS; + } + + if (copy_to_user(settings->ifs_ifsu.sync, + &conf->phys_settings, size)) { + return -EFAULT; + } + return 0; + } + + case IF_IFACE_V35: + case IF_IFACE_V24: + case IF_IFACE_X21: + { + const size_t size = sizeof(sync_serial_settings); + + if (!capable(CAP_NET_ADMIN)) { + return -EPERM; + } + /* incorrect data len? */ + if (ifr->ifr_settings.size != size) { + return -ENOBUFS; + } + + if (copy_from_user(&conf->phys_settings, + settings->ifs_ifsu.sync, size)) { + return -EFAULT; + } + + if (conf->phys_settings.loopback) { + cpc_writeb(card->hw.scabase + M_REG(MD2, ch), + cpc_readb(card->hw.scabase + M_REG(MD2, ch)) | + MD2_LOOP_MIR); + } + conf->media = ifr->ifr_settings.type; + return 0; + } + + case IF_IFACE_T1: + case IF_IFACE_E1: + { + const size_t te_size = sizeof(te1_settings); + const size_t size = sizeof(sync_serial_settings); + + if (!capable(CAP_NET_ADMIN)) { + return -EPERM; + } + + /* incorrect data len? */ + if (ifr->ifr_settings.size != te_size) { + return -ENOBUFS; + } + + if (copy_from_user(&conf->phys_settings, + settings->ifs_ifsu.te1, size)) { + return -EFAULT; + }/* Ignoring HDLC slot_map for a while */ + + if (conf->phys_settings.loopback) { + cpc_writeb(card->hw.scabase + M_REG(MD2, ch), + cpc_readb(card->hw.scabase + M_REG(MD2, ch)) | + MD2_LOOP_MIR); + } + conf->media = ifr->ifr_settings.type; + return 0; + } + default: + return hdlc_ioctl(dev, ifr, cmd); + } + + default: + return hdlc_ioctl(dev, ifr, cmd); + } +} + +static int clock_rate_calc(u32 rate, u32 clock, int *br_io) +{ + int br, tc; + int br_pwr, error; + + *br_io = 0; + + if (rate == 0) + return 0; + + for (br = 0, br_pwr = 1; br <= 9; br++, br_pwr <<= 1) { + if ((tc = clock / br_pwr / rate) <= 0xff) { + *br_io = br; + break; + } + } + + if (tc <= 0xff) { + error = ((rate - (clock / br_pwr / rate)) / rate) * 1000; + /* Errors bigger than +/- 1% won't be tolerated */ + if (error < -10 || error > 10) + return -1; + else + return tc; + } else { + return -1; + } +} + +static int ch_config(pc300dev_t * d) +{ + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + pc300_t *card = (pc300_t *) chan->card; + void __iomem *scabase = card->hw.scabase; + void __iomem *plxbase = card->hw.plxbase; + int ch = chan->channel; + u32 clkrate = chan->conf.phys_settings.clock_rate; + u32 clktype = chan->conf.phys_settings.clock_type; + u16 encoding = chan->conf.proto_settings.encoding; + u16 parity = chan->conf.proto_settings.parity; + u8 md0, md2; + + /* Reset the channel */ + cpc_writeb(scabase + M_REG(CMD, ch), CMD_CH_RST); + + /* Configure the SCA registers */ + switch (parity) { + case PARITY_NONE: + md0 = MD0_BIT_SYNC; + break; + case PARITY_CRC16_PR0: + md0 = MD0_CRC16_0|MD0_CRCC0|MD0_BIT_SYNC; + break; + case PARITY_CRC16_PR1: + md0 = MD0_CRC16_1|MD0_CRCC0|MD0_BIT_SYNC; + break; + case PARITY_CRC32_PR1_CCITT: + md0 = MD0_CRC32|MD0_CRCC0|MD0_BIT_SYNC; + break; + case PARITY_CRC16_PR1_CCITT: + default: + md0 = MD0_CRC_CCITT|MD0_CRCC0|MD0_BIT_SYNC; + break; + } + switch (encoding) { + case ENCODING_NRZI: + md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_NRZI; + break; + case ENCODING_FM_MARK: /* FM1 */ + md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_FM|MD2_FM1; + break; + case ENCODING_FM_SPACE: /* FM0 */ + md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_FM|MD2_FM0; + break; + case ENCODING_MANCHESTER: /* It's not working... */ + md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_FM|MD2_MANCH; + break; + case ENCODING_NRZ: + default: + md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_NRZ; + break; + } + cpc_writeb(scabase + M_REG(MD0, ch), md0); + cpc_writeb(scabase + M_REG(MD1, ch), 0); + cpc_writeb(scabase + M_REG(MD2, ch), md2); + cpc_writeb(scabase + M_REG(IDL, ch), 0x7e); + cpc_writeb(scabase + M_REG(CTL, ch), CTL_URSKP | CTL_IDLC); + + /* Configure HW media */ + switch (card->hw.type) { + case PC300_RSV: + if (conf->media == IF_IFACE_V35) { + cpc_writel((plxbase + card->hw.gpioc_reg), + cpc_readl(plxbase + card->hw.gpioc_reg) | PC300_CHMEDIA_MASK(ch)); + } else { + cpc_writel((plxbase + card->hw.gpioc_reg), + cpc_readl(plxbase + card->hw.gpioc_reg) & ~PC300_CHMEDIA_MASK(ch)); + } + break; + + case PC300_X21: + break; + + case PC300_TE: + te_config(card, ch); + break; + } + + switch (card->hw.type) { + case PC300_RSV: + case PC300_X21: + if (clktype == CLOCK_INT || clktype == CLOCK_TXINT) { + int tmc, br; + + /* Calculate the clkrate parameters */ + tmc = clock_rate_calc(clkrate, card->hw.clock, &br); + if (tmc < 0) + return -EIO; + cpc_writeb(scabase + M_REG(TMCT, ch), tmc); + cpc_writeb(scabase + M_REG(TXS, ch), + (TXS_DTRXC | TXS_IBRG | br)); + if (clktype == CLOCK_INT) { + cpc_writeb(scabase + M_REG(TMCR, ch), tmc); + cpc_writeb(scabase + M_REG(RXS, ch), + (RXS_IBRG | br)); + } else { + cpc_writeb(scabase + M_REG(TMCR, ch), 1); + cpc_writeb(scabase + M_REG(RXS, ch), 0); + } + if (card->hw.type == PC300_X21) { + cpc_writeb(scabase + M_REG(GPO, ch), 1); + cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1 | EXS_RES1); + } else { + cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1); + } + } else { + cpc_writeb(scabase + M_REG(TMCT, ch), 1); + if (clktype == CLOCK_EXT) { + cpc_writeb(scabase + M_REG(TXS, ch), + TXS_DTRXC); + } else { + cpc_writeb(scabase + M_REG(TXS, ch), + TXS_DTRXC|TXS_RCLK); + } + cpc_writeb(scabase + M_REG(TMCR, ch), 1); + cpc_writeb(scabase + M_REG(RXS, ch), 0); + if (card->hw.type == PC300_X21) { + cpc_writeb(scabase + M_REG(GPO, ch), 0); + cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1 | EXS_RES1); + } else { + cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1); + } + } + break; + + case PC300_TE: + /* SCA always receives clock from the FALC chip */ + cpc_writeb(scabase + M_REG(TMCT, ch), 1); + cpc_writeb(scabase + M_REG(TXS, ch), 0); + cpc_writeb(scabase + M_REG(TMCR, ch), 1); + cpc_writeb(scabase + M_REG(RXS, ch), 0); + cpc_writeb(scabase + M_REG(EXS, ch), 0); + break; + } + + /* Enable Interrupts */ + cpc_writel(scabase + IER0, + cpc_readl(scabase + IER0) | + IR0_M(IR0_RXINTA, ch) | + IR0_DRX(IR0_EFT | IR0_DMIA | IR0_DMIB, ch) | + IR0_DTX(IR0_EFT | IR0_DMIA | IR0_DMIB, ch)); + cpc_writeb(scabase + M_REG(IE0, ch), + cpc_readl(scabase + M_REG(IE0, ch)) | IE0_RXINTA); + cpc_writeb(scabase + M_REG(IE1, ch), + cpc_readl(scabase + M_REG(IE1, ch)) | IE1_CDCD); + + return 0; +} + +static int rx_config(pc300dev_t * d) +{ + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + void __iomem *scabase = card->hw.scabase; + int ch = chan->channel; + + cpc_writeb(scabase + DSR_RX(ch), 0); + + /* General RX settings */ + cpc_writeb(scabase + M_REG(RRC, ch), 0); + cpc_writeb(scabase + M_REG(RNR, ch), 16); + + /* Enable reception */ + cpc_writeb(scabase + M_REG(CMD, ch), CMD_RX_CRC_INIT); + cpc_writeb(scabase + M_REG(CMD, ch), CMD_RX_ENA); + + /* Initialize DMA stuff */ + chan->rx_first_bd = 0; + chan->rx_last_bd = N_DMA_RX_BUF - 1; + rx_dma_buf_init(card, ch); + cpc_writeb(scabase + DCR_RX(ch), DCR_FCT_CLR); + cpc_writeb(scabase + DMR_RX(ch), (DMR_TMOD | DMR_NF)); + cpc_writeb(scabase + DIR_RX(ch), (DIR_EOM | DIR_BOF)); + + /* Start DMA */ + rx_dma_start(card, ch); + + return 0; +} + +static int tx_config(pc300dev_t * d) +{ + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + void __iomem *scabase = card->hw.scabase; + int ch = chan->channel; + + cpc_writeb(scabase + DSR_TX(ch), 0); + + /* General TX settings */ + cpc_writeb(scabase + M_REG(TRC0, ch), 0); + cpc_writeb(scabase + M_REG(TFS, ch), 32); + cpc_writeb(scabase + M_REG(TNR0, ch), 20); + cpc_writeb(scabase + M_REG(TNR1, ch), 48); + cpc_writeb(scabase + M_REG(TCR, ch), 8); + + /* Enable transmission */ + cpc_writeb(scabase + M_REG(CMD, ch), CMD_TX_CRC_INIT); + + /* Initialize DMA stuff */ + chan->tx_first_bd = 0; + chan->tx_next_bd = 0; + tx_dma_buf_init(card, ch); + cpc_writeb(scabase + DCR_TX(ch), DCR_FCT_CLR); + cpc_writeb(scabase + DMR_TX(ch), (DMR_TMOD | DMR_NF)); + cpc_writeb(scabase + DIR_TX(ch), (DIR_EOM | DIR_BOF | DIR_UDRF)); + cpc_writel(scabase + DTX_REG(CDAL, ch), TX_BD_ADDR(ch, chan->tx_first_bd)); + cpc_writel(scabase + DTX_REG(EDAL, ch), TX_BD_ADDR(ch, chan->tx_next_bd)); + + return 0; +} + +static int cpc_attach(struct net_device *dev, unsigned short encoding, + unsigned short parity) +{ + pc300dev_t *d = (pc300dev_t *)dev_to_hdlc(dev)->priv; + pc300ch_t *chan = (pc300ch_t *)d->chan; + pc300_t *card = (pc300_t *)chan->card; + pc300chconf_t *conf = (pc300chconf_t *)&chan->conf; + + if (card->hw.type == PC300_TE) { + if (encoding != ENCODING_NRZ && encoding != ENCODING_NRZI) { + return -EINVAL; + } + } else { + if (encoding != ENCODING_NRZ && encoding != ENCODING_NRZI && + encoding != ENCODING_FM_MARK && encoding != ENCODING_FM_SPACE) { + /* Driver doesn't support ENCODING_MANCHESTER yet */ + return -EINVAL; + } + } + + if (parity != PARITY_NONE && parity != PARITY_CRC16_PR0 && + parity != PARITY_CRC16_PR1 && parity != PARITY_CRC32_PR1_CCITT && + parity != PARITY_CRC16_PR1_CCITT) { + return -EINVAL; + } + + conf->proto_settings.encoding = encoding; + conf->proto_settings.parity = parity; + return 0; +} + +static int cpc_opench(pc300dev_t * d) +{ + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + int ch = chan->channel, rc; + void __iomem *scabase = card->hw.scabase; + + rc = ch_config(d); + if (rc) + return rc; + + rx_config(d); + + tx_config(d); + + /* Assert RTS and DTR */ + cpc_writeb(scabase + M_REG(CTL, ch), + cpc_readb(scabase + M_REG(CTL, ch)) & ~(CTL_RTS | CTL_DTR)); + + return 0; +} + +static void cpc_closech(pc300dev_t * d) +{ + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + falc_t *pfalc = (falc_t *) & chan->falc; + int ch = chan->channel; + + cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_CH_RST); + rx_dma_stop(card, ch); + tx_dma_stop(card, ch); + + if (card->hw.type == PC300_TE) { + memset(pfalc, 0, sizeof(falc_t)); + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) & + ~((CPLD_REG2_FALC_TX_CLK | CPLD_REG2_FALC_RX_CLK | + CPLD_REG2_FALC_LED2) << (2 * ch))); + /* Reset the FALC chip */ + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) | + (CPLD_REG1_FALC_RESET << (2 * ch))); + udelay(10000); + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) & + ~(CPLD_REG1_FALC_RESET << (2 * ch))); + } +} + +int cpc_open(struct net_device *dev) +{ + pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv; + struct ifreq ifr; + int result; + +#ifdef PC300_DEBUG_OTHER + printk("pc300: cpc_open"); +#endif + + result = hdlc_open(dev); + + if (result) + return result; + + sprintf(ifr.ifr_name, "%s", dev->name); + result = cpc_opench(d); + if (result) + goto err_out; + + netif_start_queue(dev); + return 0; + +err_out: + hdlc_close(dev); + return result; +} + +static int cpc_close(struct net_device *dev) +{ + pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv; + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + unsigned long flags; + +#ifdef PC300_DEBUG_OTHER + printk("pc300: cpc_close"); +#endif + + netif_stop_queue(dev); + + CPC_LOCK(card, flags); + cpc_closech(d); + CPC_UNLOCK(card, flags); + + hdlc_close(dev); + +#ifdef CONFIG_PC300_MLPPP + if (chan->conf.proto == PC300_PROTO_MLPPP) { + cpc_tty_unregister_service(d); + chan->conf.proto = 0xffff; + } +#endif + + return 0; +} + +static u32 detect_ram(pc300_t * card) +{ + u32 i; + u8 data; + void __iomem *rambase = card->hw.rambase; + + card->hw.ramsize = PC300_RAMSIZE; + /* Let's find out how much RAM is present on this board */ + for (i = 0; i < card->hw.ramsize; i++) { + data = (u8)(i & 0xff); + cpc_writeb(rambase + i, data); + if (cpc_readb(rambase + i) != data) { + break; + } + } + return i; +} + +static void plx_init(pc300_t * card) +{ + struct RUNTIME_9050 __iomem *plx_ctl = card->hw.plxbase; + + /* Reset PLX */ + cpc_writel(&plx_ctl->init_ctrl, + cpc_readl(&plx_ctl->init_ctrl) | 0x40000000); + udelay(10000L); + cpc_writel(&plx_ctl->init_ctrl, + cpc_readl(&plx_ctl->init_ctrl) & ~0x40000000); + + /* Reload Config. Registers from EEPROM */ + cpc_writel(&plx_ctl->init_ctrl, + cpc_readl(&plx_ctl->init_ctrl) | 0x20000000); + udelay(10000L); + cpc_writel(&plx_ctl->init_ctrl, + cpc_readl(&plx_ctl->init_ctrl) & ~0x20000000); + +} + +static void show_version(void) +{ + char *rcsvers, *rcsdate, *tmp; + + rcsvers = strchr(rcsid, ' '); + rcsvers++; + tmp = strchr(rcsvers, ' '); + *tmp++ = '\0'; + rcsdate = strchr(tmp, ' '); + rcsdate++; + tmp = strrchr(rcsdate, ' '); + *tmp = '\0'; + pr_info("Cyclades-PC300 driver %s %s\n", rcsvers, rcsdate); +} /* show_version */ + +static const struct net_device_ops cpc_netdev_ops = { + .ndo_open = cpc_open, + .ndo_stop = cpc_close, + .ndo_tx_timeout = cpc_tx_timeout, + .ndo_set_mac_address = NULL, + .ndo_change_mtu = cpc_change_mtu, + .ndo_do_ioctl = cpc_ioctl, + .ndo_validate_addr = eth_validate_addr, +}; + +static void cpc_init_card(pc300_t * card) +{ + int i, devcount = 0; + static int board_nbr = 1; + + /* Enable interrupts on the PCI bridge */ + plx_init(card); + cpc_writew(card->hw.plxbase + card->hw.intctl_reg, + cpc_readw(card->hw.plxbase + card->hw.intctl_reg) | 0x0040); + +#ifdef USE_PCI_CLOCK + /* Set board clock to PCI clock */ + cpc_writel(card->hw.plxbase + card->hw.gpioc_reg, + cpc_readl(card->hw.plxbase + card->hw.gpioc_reg) | 0x00000004UL); + card->hw.clock = PC300_PCI_CLOCK; +#else + /* Set board clock to internal oscillator clock */ + cpc_writel(card->hw.plxbase + card->hw.gpioc_reg, + cpc_readl(card->hw.plxbase + card->hw.gpioc_reg) & ~0x00000004UL); + card->hw.clock = PC300_OSC_CLOCK; +#endif + + /* Detect actual on-board RAM size */ + card->hw.ramsize = detect_ram(card); + + /* Set Global SCA-II registers */ + cpc_writeb(card->hw.scabase + PCR, PCR_PR2); + cpc_writeb(card->hw.scabase + BTCR, 0x10); + cpc_writeb(card->hw.scabase + WCRL, 0); + cpc_writeb(card->hw.scabase + DMER, 0x80); + + if (card->hw.type == PC300_TE) { + u8 reg1; + + /* Check CPLD version */ + reg1 = cpc_readb(card->hw.falcbase + CPLD_REG1); + cpc_writeb(card->hw.falcbase + CPLD_REG1, (reg1 + 0x5a)); + if (cpc_readb(card->hw.falcbase + CPLD_REG1) == reg1) { + /* New CPLD */ + card->hw.cpld_id = cpc_readb(card->hw.falcbase + CPLD_ID_REG); + card->hw.cpld_reg1 = CPLD_V2_REG1; + card->hw.cpld_reg2 = CPLD_V2_REG2; + } else { + /* old CPLD */ + card->hw.cpld_id = 0; + card->hw.cpld_reg1 = CPLD_REG1; + card->hw.cpld_reg2 = CPLD_REG2; + cpc_writeb(card->hw.falcbase + CPLD_REG1, reg1); + } + + /* Enable the board's global clock */ + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) | + CPLD_REG1_GLOBAL_CLK); + + } + + for (i = 0; i < card->hw.nchan; i++) { + pc300ch_t *chan = &card->chan[i]; + pc300dev_t *d = &chan->d; + hdlc_device *hdlc; + struct net_device *dev; + + chan->card = card; + chan->channel = i; + chan->conf.phys_settings.clock_rate = 0; + chan->conf.phys_settings.clock_type = CLOCK_EXT; + chan->conf.proto_settings.encoding = ENCODING_NRZ; + chan->conf.proto_settings.parity = PARITY_CRC16_PR1_CCITT; + switch (card->hw.type) { + case PC300_TE: + chan->conf.media = IF_IFACE_T1; + chan->conf.lcode = PC300_LC_B8ZS; + chan->conf.fr_mode = PC300_FR_ESF; + chan->conf.lbo = PC300_LBO_0_DB; + chan->conf.rx_sens = PC300_RX_SENS_SH; + chan->conf.tslot_bitmap = 0xffffffffUL; + break; + + case PC300_X21: + chan->conf.media = IF_IFACE_X21; + break; + + case PC300_RSV: + default: + chan->conf.media = IF_IFACE_V35; + break; + } + chan->conf.proto = IF_PROTO_PPP; + chan->tx_first_bd = 0; + chan->tx_next_bd = 0; + chan->rx_first_bd = 0; + chan->rx_last_bd = N_DMA_RX_BUF - 1; + chan->nfree_tx_bd = N_DMA_TX_BUF; + + d->chan = chan; + d->trace_on = 0; + d->line_on = 0; + d->line_off = 0; + + dev = alloc_hdlcdev(d); + if (dev == NULL) + continue; + + hdlc = dev_to_hdlc(dev); + hdlc->xmit = cpc_queue_xmit; + hdlc->attach = cpc_attach; + d->dev = dev; + dev->mem_start = card->hw.ramphys; + dev->mem_end = card->hw.ramphys + card->hw.ramsize - 1; + dev->irq = card->hw.irq; + dev->tx_queue_len = PC300_TX_QUEUE_LEN; + dev->mtu = PC300_DEF_MTU; + + dev->netdev_ops = &cpc_netdev_ops; + dev->watchdog_timeo = PC300_TX_TIMEOUT; + + if (register_hdlc_device(dev) == 0) { + printk("%s: Cyclades-PC300/", dev->name); + switch (card->hw.type) { + case PC300_TE: + if (card->hw.bus == PC300_PMC) { + printk("TE-M"); + } else { + printk("TE "); + } + break; + + case PC300_X21: + printk("X21 "); + break; + + case PC300_RSV: + default: + printk("RSV "); + break; + } + printk (" #%d, %dKB of RAM at 0x%08x, IRQ%d, channel %d.\n", + board_nbr, card->hw.ramsize / 1024, + card->hw.ramphys, card->hw.irq, i + 1); + devcount++; + } else { + printk ("Dev%d on card(0x%08x): unable to allocate i/f name.\n", + i + 1, card->hw.ramphys); + free_netdev(dev); + continue; + } + } + spin_lock_init(&card->card_lock); + + board_nbr++; +} + +static int __devinit +cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + int err, eeprom_outdated = 0; + u16 device_id; + pc300_t *card; + + if ((err = pci_enable_device(pdev)) < 0) + return err; + + card = kzalloc(sizeof(pc300_t), GFP_KERNEL); + if (card == NULL) { + printk("PC300 found at RAM 0x%016llx, " + "but could not allocate card structure.\n", + (unsigned long long)pci_resource_start(pdev, 3)); + err = -ENOMEM; + goto err_disable_dev; + } + + err = -ENODEV; + + /* read PCI configuration area */ + device_id = ent->device; + card->hw.irq = pdev->irq; + card->hw.iophys = pci_resource_start(pdev, 1); + card->hw.iosize = pci_resource_len(pdev, 1); + card->hw.scaphys = pci_resource_start(pdev, 2); + card->hw.scasize = pci_resource_len(pdev, 2); + card->hw.ramphys = pci_resource_start(pdev, 3); + card->hw.alloc_ramsize = pci_resource_len(pdev, 3); + card->hw.falcphys = pci_resource_start(pdev, 4); + card->hw.falcsize = pci_resource_len(pdev, 4); + card->hw.plxphys = pci_resource_start(pdev, 5); + card->hw.plxsize = pci_resource_len(pdev, 5); + + switch (device_id) { + case PCI_DEVICE_ID_PC300_RX_1: + case PCI_DEVICE_ID_PC300_TE_1: + case PCI_DEVICE_ID_PC300_TE_M_1: + card->hw.nchan = 1; + break; + + case PCI_DEVICE_ID_PC300_RX_2: + case PCI_DEVICE_ID_PC300_TE_2: + case PCI_DEVICE_ID_PC300_TE_M_2: + default: + card->hw.nchan = PC300_MAXCHAN; + break; + } +#ifdef PC300_DEBUG_PCI + printk("cpc (bus=0x0%x,pci_id=0x%x,", pdev->bus->number, pdev->devfn); + printk("rev_id=%d) IRQ%d\n", pdev->revision, card->hw.irq); + printk("cpc:found ramaddr=0x%08lx plxaddr=0x%08lx " + "ctladdr=0x%08lx falcaddr=0x%08lx\n", + card->hw.ramphys, card->hw.plxphys, card->hw.scaphys, + card->hw.falcphys); +#endif + /* Although we don't use this I/O region, we should + * request it from the kernel anyway, to avoid problems + * with other drivers accessing it. */ + if (!request_region(card->hw.iophys, card->hw.iosize, "PLX Registers")) { + /* In case we can't allocate it, warn user */ + printk("WARNING: couldn't allocate I/O region for PC300 board " + "at 0x%08x!\n", card->hw.ramphys); + } + + if (card->hw.plxphys) { + pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, card->hw.plxphys); + } else { + eeprom_outdated = 1; + card->hw.plxphys = pci_resource_start(pdev, 0); + card->hw.plxsize = pci_resource_len(pdev, 0); + } + + if (!request_mem_region(card->hw.plxphys, card->hw.plxsize, + "PLX Registers")) { + printk("PC300 found at RAM 0x%08x, " + "but could not allocate PLX mem region.\n", + card->hw.ramphys); + goto err_release_io; + } + if (!request_mem_region(card->hw.ramphys, card->hw.alloc_ramsize, + "On-board RAM")) { + printk("PC300 found at RAM 0x%08x, " + "but could not allocate RAM mem region.\n", + card->hw.ramphys); + goto err_release_plx; + } + if (!request_mem_region(card->hw.scaphys, card->hw.scasize, + "SCA-II Registers")) { + printk("PC300 found at RAM 0x%08x, " + "but could not allocate SCA mem region.\n", + card->hw.ramphys); + goto err_release_ram; + } + + card->hw.plxbase = ioremap(card->hw.plxphys, card->hw.plxsize); + card->hw.rambase = ioremap(card->hw.ramphys, card->hw.alloc_ramsize); + card->hw.scabase = ioremap(card->hw.scaphys, card->hw.scasize); + switch (device_id) { + case PCI_DEVICE_ID_PC300_TE_1: + case PCI_DEVICE_ID_PC300_TE_2: + case PCI_DEVICE_ID_PC300_TE_M_1: + case PCI_DEVICE_ID_PC300_TE_M_2: + request_mem_region(card->hw.falcphys, card->hw.falcsize, + "FALC Registers"); + card->hw.falcbase = ioremap(card->hw.falcphys, card->hw.falcsize); + break; + + case PCI_DEVICE_ID_PC300_RX_1: + case PCI_DEVICE_ID_PC300_RX_2: + default: + card->hw.falcbase = NULL; + break; + } + +#ifdef PC300_DEBUG_PCI + printk("cpc: relocate ramaddr=0x%08lx plxaddr=0x%08lx " + "ctladdr=0x%08lx falcaddr=0x%08lx\n", + card->hw.rambase, card->hw.plxbase, card->hw.scabase, + card->hw.falcbase); +#endif + + /* Set PCI drv pointer to the card structure */ + pci_set_drvdata(pdev, card); + + /* Set board type */ + switch (device_id) { + case PCI_DEVICE_ID_PC300_TE_1: + case PCI_DEVICE_ID_PC300_TE_2: + case PCI_DEVICE_ID_PC300_TE_M_1: + case PCI_DEVICE_ID_PC300_TE_M_2: + card->hw.type = PC300_TE; + + if ((device_id == PCI_DEVICE_ID_PC300_TE_M_1) || + (device_id == PCI_DEVICE_ID_PC300_TE_M_2)) { + card->hw.bus = PC300_PMC; + /* Set PLX register offsets */ + card->hw.gpioc_reg = 0x54; + card->hw.intctl_reg = 0x4c; + } else { + card->hw.bus = PC300_PCI; + /* Set PLX register offsets */ + card->hw.gpioc_reg = 0x50; + card->hw.intctl_reg = 0x4c; + } + break; + + case PCI_DEVICE_ID_PC300_RX_1: + case PCI_DEVICE_ID_PC300_RX_2: + default: + card->hw.bus = PC300_PCI; + /* Set PLX register offsets */ + card->hw.gpioc_reg = 0x50; + card->hw.intctl_reg = 0x4c; + + if ((cpc_readl(card->hw.plxbase + card->hw.gpioc_reg) & PC300_CTYPE_MASK)) { + card->hw.type = PC300_X21; + } else { + card->hw.type = PC300_RSV; + } + break; + } + + /* Allocate IRQ */ + if (request_irq(card->hw.irq, cpc_intr, IRQF_SHARED, "Cyclades-PC300", card)) { + printk ("PC300 found at RAM 0x%08x, but could not allocate IRQ%d.\n", + card->hw.ramphys, card->hw.irq); + goto err_io_unmap; + } + + cpc_init_card(card); + + if (eeprom_outdated) + printk("WARNING: PC300 with outdated EEPROM.\n"); + return 0; + +err_io_unmap: + iounmap(card->hw.plxbase); + iounmap(card->hw.scabase); + iounmap(card->hw.rambase); + if (card->hw.type == PC300_TE) { + iounmap(card->hw.falcbase); + release_mem_region(card->hw.falcphys, card->hw.falcsize); + } + release_mem_region(card->hw.scaphys, card->hw.scasize); +err_release_ram: + release_mem_region(card->hw.ramphys, card->hw.alloc_ramsize); +err_release_plx: + release_mem_region(card->hw.plxphys, card->hw.plxsize); +err_release_io: + release_region(card->hw.iophys, card->hw.iosize); + kfree(card); +err_disable_dev: + pci_disable_device(pdev); + return err; +} + +static void __devexit cpc_remove_one(struct pci_dev *pdev) +{ + pc300_t *card = pci_get_drvdata(pdev); + + if (card->hw.rambase) { + int i; + + /* Disable interrupts on the PCI bridge */ + cpc_writew(card->hw.plxbase + card->hw.intctl_reg, + cpc_readw(card->hw.plxbase + card->hw.intctl_reg) & ~(0x0040)); + + for (i = 0; i < card->hw.nchan; i++) { + unregister_hdlc_device(card->chan[i].d.dev); + } + iounmap(card->hw.plxbase); + iounmap(card->hw.scabase); + iounmap(card->hw.rambase); + release_mem_region(card->hw.plxphys, card->hw.plxsize); + release_mem_region(card->hw.ramphys, card->hw.alloc_ramsize); + release_mem_region(card->hw.scaphys, card->hw.scasize); + release_region(card->hw.iophys, card->hw.iosize); + if (card->hw.type == PC300_TE) { + iounmap(card->hw.falcbase); + release_mem_region(card->hw.falcphys, card->hw.falcsize); + } + for (i = 0; i < card->hw.nchan; i++) + if (card->chan[i].d.dev) + free_netdev(card->chan[i].d.dev); + if (card->hw.irq) + free_irq(card->hw.irq, card); + kfree(card); + pci_disable_device(pdev); + } +} + +static struct pci_driver cpc_driver = { + .name = "pc300", + .id_table = cpc_pci_dev_id, + .probe = cpc_init_one, + .remove = __devexit_p(cpc_remove_one), +}; + +static int __init cpc_init(void) +{ + show_version(); + return pci_register_driver(&cpc_driver); +} + +static void __exit cpc_cleanup_module(void) +{ + pci_unregister_driver(&cpc_driver); +} + +module_init(cpc_init); +module_exit(cpc_cleanup_module); + +MODULE_DESCRIPTION("Cyclades-PC300 cards driver"); +MODULE_AUTHOR( "Author: Ivan Passos \r\n" + "Maintainer: PC300 Maintainer + * + * Copyright: (c) 1999-2002 Cyclades Corp. + * + * 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. + * + * $Log: pc300_tty.c,v $ + * Revision 3.7 2002/03/07 14:17:09 henrique + * License data fixed + * + * Revision 3.6 2001/12/10 12:29:42 regina + * Fix the MLPPP bug + * + * Revision 3.5 2001/10/31 11:20:05 regina + * automatic pppd starts + * + * Revision 3.4 2001/08/06 12:01:51 regina + * problem in DSR_DE bit + * + * Revision 3.3 2001/07/26 22:58:41 regina + * update EDA value + * + * Revision 3.2 2001/07/12 13:11:20 regina + * bug fix - DCD-OFF in pc300 tty driver + * + * DMA transmission bug fix + * + * Revision 3.1 2001/06/22 13:13:02 regina + * MLPPP implementation + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/* TTY includes */ +#include +#include +#include + +#include +#include + +#include "pc300.h" + +/* defines and macros */ +/* TTY Global definitions */ +#define CPC_TTY_NPORTS 8 /* maximum number of the sync tty connections */ +#define CPC_TTY_MAJOR CYCLADES_MAJOR +#define CPC_TTY_MINOR_START 240 /* minor of the first PC300 interface */ + +#define CPC_TTY_MAX_MTU 2000 + +/* tty interface state */ +#define CPC_TTY_ST_IDLE 0 +#define CPC_TTY_ST_INIT 1 /* configured with MLPPP and up */ +#define CPC_TTY_ST_OPEN 2 /* opened by application */ + +#define CPC_TTY_LOCK(card,flags)\ + do {\ + spin_lock_irqsave(&card->card_lock, flags); \ + } while (0) + +#define CPC_TTY_UNLOCK(card,flags) \ + do {\ + spin_unlock_irqrestore(&card->card_lock, flags); \ + } while (0) + +//#define CPC_TTY_DBG(format,a...) printk(format,##a) +#define CPC_TTY_DBG(format,a...) + +/* data structures */ +typedef struct _st_cpc_rx_buf { + struct _st_cpc_rx_buf *next; + int size; + unsigned char data[1]; +} st_cpc_rx_buf; + +struct st_cpc_rx_list { + st_cpc_rx_buf *first; + st_cpc_rx_buf *last; +}; + +typedef struct _st_cpc_tty_area { + int state; /* state of the TTY interface */ + int num_open; + unsigned int tty_minor; /* minor this interface */ + volatile struct st_cpc_rx_list buf_rx; /* ptr. to reception buffer */ + unsigned char* buf_tx; /* ptr. to transmission buffer */ + pc300dev_t* pc300dev; /* ptr. to info struct in PC300 driver */ + unsigned char name[20]; /* interf. name + "-tty" */ + struct tty_struct *tty; + struct work_struct tty_tx_work; /* tx work - tx interrupt */ + struct work_struct tty_rx_work; /* rx work - rx interrupt */ + } st_cpc_tty_area; + +/* TTY data structures */ +static struct tty_driver serial_drv; + +/* local variables */ +static st_cpc_tty_area cpc_tty_area[CPC_TTY_NPORTS]; + +static int cpc_tty_cnt = 0; /* number of intrfaces configured with MLPPP */ +static int cpc_tty_unreg_flag = 0; + +/* TTY functions prototype */ +static int cpc_tty_open(struct tty_struct *tty, struct file *flip); +static void cpc_tty_close(struct tty_struct *tty, struct file *flip); +static int cpc_tty_write(struct tty_struct *tty, const unsigned char *buf, int count); +static int cpc_tty_write_room(struct tty_struct *tty); +static int cpc_tty_chars_in_buffer(struct tty_struct *tty); +static void cpc_tty_flush_buffer(struct tty_struct *tty); +static void cpc_tty_hangup(struct tty_struct *tty); +static void cpc_tty_rx_work(struct work_struct *work); +static void cpc_tty_tx_work(struct work_struct *work); +static int cpc_tty_send_to_card(pc300dev_t *dev,void *buf, int len); +static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx); +static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char); +static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char); + +static int pc300_tiocmset(struct tty_struct *, unsigned int, unsigned int); +static int pc300_tiocmget(struct tty_struct *); + +/* functions called by PC300 driver */ +void cpc_tty_init(pc300dev_t *dev); +void cpc_tty_unregister_service(pc300dev_t *pc300dev); +void cpc_tty_receive(pc300dev_t *pc300dev); +void cpc_tty_trigger_poll(pc300dev_t *pc300dev); + +/* + * PC300 TTY clear "signal" + */ +static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char signal) +{ + pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; + pc300_t *card = (pc300_t *) pc300chan->card; + int ch = pc300chan->channel; + unsigned long flags; + + CPC_TTY_DBG("%s-tty: Clear signal %x\n", + pc300dev->dev->name, signal); + CPC_TTY_LOCK(card, flags); + cpc_writeb(card->hw.scabase + M_REG(CTL,ch), + cpc_readb(card->hw.scabase+M_REG(CTL,ch))& signal); + CPC_TTY_UNLOCK(card,flags); +} + +/* + * PC300 TTY set "signal" to ON + */ +static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char signal) +{ + pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; + pc300_t *card = (pc300_t *) pc300chan->card; + int ch = pc300chan->channel; + unsigned long flags; + + CPC_TTY_DBG("%s-tty: Set signal %x\n", + pc300dev->dev->name, signal); + CPC_TTY_LOCK(card, flags); + cpc_writeb(card->hw.scabase + M_REG(CTL,ch), + cpc_readb(card->hw.scabase+M_REG(CTL,ch))& ~signal); + CPC_TTY_UNLOCK(card,flags); +} + + +static const struct tty_operations pc300_ops = { + .open = cpc_tty_open, + .close = cpc_tty_close, + .write = cpc_tty_write, + .write_room = cpc_tty_write_room, + .chars_in_buffer = cpc_tty_chars_in_buffer, + .tiocmset = pc300_tiocmset, + .tiocmget = pc300_tiocmget, + .flush_buffer = cpc_tty_flush_buffer, + .hangup = cpc_tty_hangup, +}; + + +/* + * PC300 TTY initialization routine + * + * This routine is called by the PC300 driver during board configuration + * (ioctl=SIOCSP300CONF). At this point the adapter is completely + * initialized. + * o verify kernel version (only 2.4.x) + * o register TTY driver + * o init cpc_tty_area struct + */ +void cpc_tty_init(pc300dev_t *pc300dev) +{ + unsigned long port; + int aux; + st_cpc_tty_area * cpc_tty; + + /* hdlcX - X=interface number */ + port = pc300dev->dev->name[4] - '0'; + if (port >= CPC_TTY_NPORTS) { + printk("%s-tty: invalid interface selected (0-%i): %li", + pc300dev->dev->name, + CPC_TTY_NPORTS-1,port); + return; + } + + if (cpc_tty_cnt == 0) { /* first TTY connection -> register driver */ + CPC_TTY_DBG("%s-tty: driver init, major:%i, minor range:%i=%i\n", + pc300dev->dev->name, + CPC_TTY_MAJOR, CPC_TTY_MINOR_START, + CPC_TTY_MINOR_START+CPC_TTY_NPORTS); + /* initialize tty driver struct */ + memset(&serial_drv,0,sizeof(struct tty_driver)); + serial_drv.magic = TTY_DRIVER_MAGIC; + serial_drv.owner = THIS_MODULE; + serial_drv.driver_name = "pc300_tty"; + serial_drv.name = "ttyCP"; + serial_drv.major = CPC_TTY_MAJOR; + serial_drv.minor_start = CPC_TTY_MINOR_START; + serial_drv.num = CPC_TTY_NPORTS; + serial_drv.type = TTY_DRIVER_TYPE_SERIAL; + serial_drv.subtype = SERIAL_TYPE_NORMAL; + + serial_drv.init_termios = tty_std_termios; + serial_drv.init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; + serial_drv.flags = TTY_DRIVER_REAL_RAW; + + /* interface routines from the upper tty layer to the tty driver */ + tty_set_operations(&serial_drv, &pc300_ops); + + /* register the TTY driver */ + if (tty_register_driver(&serial_drv)) { + printk("%s-tty: Failed to register serial driver! ", + pc300dev->dev->name); + return; + } + + memset((void *)cpc_tty_area, 0, + sizeof(st_cpc_tty_area) * CPC_TTY_NPORTS); + } + + cpc_tty = &cpc_tty_area[port]; + + if (cpc_tty->state != CPC_TTY_ST_IDLE) { + CPC_TTY_DBG("%s-tty: TTY port %i, already in use.\n", + pc300dev->dev->name, port); + return; + } + + cpc_tty_cnt++; + cpc_tty->state = CPC_TTY_ST_INIT; + cpc_tty->num_open= 0; + cpc_tty->tty_minor = port + CPC_TTY_MINOR_START; + cpc_tty->pc300dev = pc300dev; + + INIT_WORK(&cpc_tty->tty_tx_work, cpc_tty_tx_work); + INIT_WORK(&cpc_tty->tty_rx_work, cpc_tty_rx_work); + + cpc_tty->buf_rx.first = cpc_tty->buf_rx.last = NULL; + + pc300dev->cpc_tty = (void *)cpc_tty; + + aux = strlen(pc300dev->dev->name); + memcpy(cpc_tty->name, pc300dev->dev->name, aux); + memcpy(&cpc_tty->name[aux], "-tty", 5); + + cpc_open(pc300dev->dev); + cpc_tty_signal_off(pc300dev, CTL_DTR); + + CPC_TTY_DBG("%s: Initializing TTY Sync Driver, tty major#%d minor#%i\n", + cpc_tty->name,CPC_TTY_MAJOR,cpc_tty->tty_minor); + return; +} + +/* + * PC300 TTY OPEN routine + * + * This routine is called by the tty driver to open the interface + * o verify minor + * o allocate buffer to Rx and Tx + */ +static int cpc_tty_open(struct tty_struct *tty, struct file *flip) +{ + int port ; + st_cpc_tty_area *cpc_tty; + + if (!tty) { + return -ENODEV; + } + + port = tty->index; + + if ((port < 0) || (port >= CPC_TTY_NPORTS)){ + CPC_TTY_DBG("pc300_tty: open invalid port %d\n", port); + return -ENODEV; + } + + cpc_tty = &cpc_tty_area[port]; + + if (cpc_tty->state == CPC_TTY_ST_IDLE){ + CPC_TTY_DBG("%s: open - invalid interface, port=%d\n", + cpc_tty->name, tty->index); + return -ENODEV; + } + + if (cpc_tty->num_open == 0) { /* first open of this tty */ + if (!cpc_tty_area[port].buf_tx){ + cpc_tty_area[port].buf_tx = kmalloc(CPC_TTY_MAX_MTU,GFP_KERNEL); + if (!cpc_tty_area[port].buf_tx) { + CPC_TTY_DBG("%s: error in memory allocation\n",cpc_tty->name); + return -ENOMEM; + } + } + + if (cpc_tty_area[port].buf_rx.first) { + unsigned char * aux; + while (cpc_tty_area[port].buf_rx.first) { + aux = (unsigned char *)cpc_tty_area[port].buf_rx.first; + cpc_tty_area[port].buf_rx.first = cpc_tty_area[port].buf_rx.first->next; + kfree(aux); + } + cpc_tty_area[port].buf_rx.first = NULL; + cpc_tty_area[port].buf_rx.last = NULL; + } + + cpc_tty_area[port].state = CPC_TTY_ST_OPEN; + cpc_tty_area[port].tty = tty; + tty->driver_data = &cpc_tty_area[port]; + + cpc_tty_signal_on(cpc_tty->pc300dev, CTL_DTR); + } + + cpc_tty->num_open++; + + CPC_TTY_DBG("%s: opening TTY driver\n", cpc_tty->name); + + /* avisar driver PC300 */ + return 0; +} + +/* + * PC300 TTY CLOSE routine + * + * This routine is called by the tty driver to close the interface + * o call close channel in PC300 driver (cpc_closech) + * o free Rx and Tx buffers + */ + +static void cpc_tty_close(struct tty_struct *tty, struct file *flip) +{ + st_cpc_tty_area *cpc_tty; + unsigned long flags; + int res; + + if (!tty || !tty->driver_data ) { + CPC_TTY_DBG("hdlx-tty: no TTY in close\n"); + return; + } + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + if ((cpc_tty->tty != tty)|| (cpc_tty->state != CPC_TTY_ST_OPEN)) { + CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name); + return; + } + + if (!cpc_tty->num_open) { + CPC_TTY_DBG("%s: TTY is closed\n",cpc_tty->name); + return; + } + + if (--cpc_tty->num_open > 0) { + CPC_TTY_DBG("%s: TTY closed\n",cpc_tty->name); + return; + } + + cpc_tty_signal_off(cpc_tty->pc300dev, CTL_DTR); + + CPC_TTY_LOCK(cpc_tty->pc300dev->chan->card, flags); /* lock irq */ + cpc_tty->tty = NULL; + cpc_tty->state = CPC_TTY_ST_INIT; + CPC_TTY_UNLOCK(cpc_tty->pc300dev->chan->card, flags); /* unlock irq */ + + if (cpc_tty->buf_rx.first) { + unsigned char * aux; + while (cpc_tty->buf_rx.first) { + aux = (unsigned char *)cpc_tty->buf_rx.first; + cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next; + kfree(aux); + } + cpc_tty->buf_rx.first = NULL; + cpc_tty->buf_rx.last = NULL; + } + + kfree(cpc_tty->buf_tx); + cpc_tty->buf_tx = NULL; + + CPC_TTY_DBG("%s: TTY closed\n",cpc_tty->name); + + if (!serial_drv.refcount && cpc_tty_unreg_flag) { + cpc_tty_unreg_flag = 0; + CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name); + if ((res=tty_unregister_driver(&serial_drv))) { + CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n", + cpc_tty->name,res); + } + } + return; +} + +/* + * PC300 TTY WRITE routine + * + * This routine is called by the tty driver to write a series of characters + * to the tty device. The characters may come from user or kernel space. + * o verify the DCD signal + * o send characters to board and start the transmission + */ +static int cpc_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) +{ + st_cpc_tty_area *cpc_tty; + pc300ch_t *pc300chan; + pc300_t *card; + int ch; + unsigned long flags; + struct net_device_stats *stats; + + if (!tty || !tty->driver_data ) { + CPC_TTY_DBG("hdlcX-tty: no TTY in write\n"); + return -ENODEV; + } + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { + CPC_TTY_DBG("%s: TTY is not opened\n", cpc_tty->name); + return -ENODEV; + } + + if (count > CPC_TTY_MAX_MTU) { + CPC_TTY_DBG("%s: count is invalid\n",cpc_tty->name); + return -EINVAL; /* frame too big */ + } + + CPC_TTY_DBG("%s: cpc_tty_write data len=%i\n",cpc_tty->name,count); + + pc300chan = (pc300ch_t *)((pc300dev_t*)cpc_tty->pc300dev)->chan; + stats = &cpc_tty->pc300dev->dev->stats; + card = (pc300_t *) pc300chan->card; + ch = pc300chan->channel; + + /* verify DCD signal*/ + if (cpc_readb(card->hw.scabase + M_REG(ST3,ch)) & ST3_DCD) { + /* DCD is OFF */ + CPC_TTY_DBG("%s : DCD is OFF\n", cpc_tty->name); + stats->tx_errors++; + stats->tx_carrier_errors++; + CPC_TTY_LOCK(card, flags); + cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_BUF_CLR); + + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) & + ~(CPLD_REG2_FALC_LED1 << (2 *ch))); + } + + CPC_TTY_UNLOCK(card, flags); + + return -EINVAL; + } + + if (cpc_tty_send_to_card(cpc_tty->pc300dev, (void*)buf, count)) { + /* failed to send */ + CPC_TTY_DBG("%s: trasmition error\n", cpc_tty->name); + return 0; + } + return count; +} + +/* + * PC300 TTY Write Room routine + * + * This routine returns the numbers of characteres the tty driver will accept + * for queuing to be written. + * o return MTU + */ +static int cpc_tty_write_room(struct tty_struct *tty) +{ + st_cpc_tty_area *cpc_tty; + + if (!tty || !tty->driver_data ) { + CPC_TTY_DBG("hdlcX-tty: no TTY to write room\n"); + return -ENODEV; + } + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { + CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name); + return -ENODEV; + } + + CPC_TTY_DBG("%s: write room\n",cpc_tty->name); + + return CPC_TTY_MAX_MTU; +} + +/* + * PC300 TTY chars in buffer routine + * + * This routine returns the chars number in the transmission buffer + * o returns 0 + */ +static int cpc_tty_chars_in_buffer(struct tty_struct *tty) +{ + st_cpc_tty_area *cpc_tty; + + if (!tty || !tty->driver_data ) { + CPC_TTY_DBG("hdlcX-tty: no TTY to chars in buffer\n"); + return -ENODEV; + } + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { + CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name); + return -ENODEV; + } + + return 0; +} + +static int pc300_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) +{ + st_cpc_tty_area *cpc_tty; + + CPC_TTY_DBG("%s: set:%x clear:%x\n", __func__, set, clear); + + if (!tty || !tty->driver_data ) { + CPC_TTY_DBG("hdlcX-tty: no TTY to chars in buffer\n"); + return -ENODEV; + } + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + if (set & TIOCM_RTS) + cpc_tty_signal_on(cpc_tty->pc300dev, CTL_RTS); + if (set & TIOCM_DTR) + cpc_tty_signal_on(cpc_tty->pc300dev, CTL_DTR); + + if (clear & TIOCM_RTS) + cpc_tty_signal_off(cpc_tty->pc300dev, CTL_RTS); + if (clear & TIOCM_DTR) + cpc_tty_signal_off(cpc_tty->pc300dev, CTL_DTR); + + return 0; +} + +static int pc300_tiocmget(struct tty_struct *tty) +{ + unsigned int result; + unsigned char status; + unsigned long flags; + st_cpc_tty_area *cpc_tty = (st_cpc_tty_area *) tty->driver_data; + pc300dev_t *pc300dev = cpc_tty->pc300dev; + pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; + pc300_t *card = (pc300_t *) pc300chan->card; + int ch = pc300chan->channel; + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + CPC_TTY_DBG("%s-tty: tiocmget\n", + ((struct net_device*)(pc300dev->hdlc))->name); + + CPC_TTY_LOCK(card, flags); + status = cpc_readb(card->hw.scabase+M_REG(CTL,ch)); + CPC_TTY_UNLOCK(card,flags); + + result = ((status & CTL_DTR) ? TIOCM_DTR : 0) | + ((status & CTL_RTS) ? TIOCM_RTS : 0); + + return result; +} + +/* + * PC300 TTY Flush Buffer routine + * + * This routine resets the transmission buffer + */ +static void cpc_tty_flush_buffer(struct tty_struct *tty) +{ + st_cpc_tty_area *cpc_tty; + + if (!tty || !tty->driver_data ) { + CPC_TTY_DBG("hdlcX-tty: no TTY to flush buffer\n"); + return; + } + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { + CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name); + return; + } + + CPC_TTY_DBG("%s: call wake_up_interruptible\n",cpc_tty->name); + + tty_wakeup(tty); + return; +} + +/* + * PC300 TTY Hangup routine + * + * This routine is called by the tty driver to hangup the interface + * o clear DTR signal + */ + +static void cpc_tty_hangup(struct tty_struct *tty) +{ + st_cpc_tty_area *cpc_tty; + int res; + + if (!tty || !tty->driver_data ) { + CPC_TTY_DBG("hdlcX-tty: no TTY to hangup\n"); + return ; + } + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { + CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name); + return ; + } + if (!serial_drv.refcount && cpc_tty_unreg_flag) { + cpc_tty_unreg_flag = 0; + CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name); + if ((res=tty_unregister_driver(&serial_drv))) { + CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n", + cpc_tty->name,res); + } + } + cpc_tty_signal_off(cpc_tty->pc300dev, CTL_DTR); +} + +/* + * PC300 TTY RX work routine + * This routine treats RX work + * o verify read buffer + * o call the line disc. read + * o free memory + */ +static void cpc_tty_rx_work(struct work_struct *work) +{ + st_cpc_tty_area *cpc_tty; + unsigned long port; + int i, j; + volatile st_cpc_rx_buf *buf; + char flags=0,flg_rx=1; + struct tty_ldisc *ld; + + if (cpc_tty_cnt == 0) return; + + for (i=0; (i < 4) && flg_rx ; i++) { + flg_rx = 0; + + cpc_tty = container_of(work, st_cpc_tty_area, tty_rx_work); + port = cpc_tty - cpc_tty_area; + + for (j=0; j < CPC_TTY_NPORTS; j++) { + cpc_tty = &cpc_tty_area[port]; + + if ((buf=cpc_tty->buf_rx.first) != NULL) { + if (cpc_tty->tty) { + ld = tty_ldisc_ref(cpc_tty->tty); + if (ld) { + if (ld->ops->receive_buf) { + CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name); + ld->ops->receive_buf(cpc_tty->tty, (char *)(buf->data), &flags, buf->size); + } + tty_ldisc_deref(ld); + } + } + cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next; + kfree((void *)buf); + buf = cpc_tty->buf_rx.first; + flg_rx = 1; + } + if (++port == CPC_TTY_NPORTS) port = 0; + } + } +} + +/* + * PC300 TTY RX work routine + * + * This routine treats RX interrupt. + * o read all frames in card + * o verify the frame size + * o read the frame in rx buffer + */ +static void cpc_tty_rx_disc_frame(pc300ch_t *pc300chan) +{ + volatile pcsca_bd_t __iomem * ptdescr; + volatile unsigned char status; + pc300_t *card = (pc300_t *)pc300chan->card; + int ch = pc300chan->channel; + + /* dma buf read */ + ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + + RX_BD_ADDR(ch, pc300chan->rx_first_bd)); + while (pc300chan->rx_first_bd != pc300chan->rx_last_bd) { + status = cpc_readb(&ptdescr->status); + cpc_writeb(&ptdescr->status, 0); + cpc_writeb(&ptdescr->len, 0); + pc300chan->rx_first_bd = (pc300chan->rx_first_bd + 1) & + (N_DMA_RX_BUF - 1); + if (status & DST_EOM) { + break; /* end of message */ + } + ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + cpc_readl(&ptdescr->next)); + } +} + +void cpc_tty_receive(pc300dev_t *pc300dev) +{ + st_cpc_tty_area *cpc_tty; + pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; + pc300_t *card = (pc300_t *)pc300chan->card; + int ch = pc300chan->channel; + volatile pcsca_bd_t __iomem * ptdescr; + struct net_device_stats *stats = &pc300dev->dev->stats; + int rx_len, rx_aux; + volatile unsigned char status; + unsigned short first_bd = pc300chan->rx_first_bd; + st_cpc_rx_buf *new = NULL; + unsigned char dsr_rx; + + if (pc300dev->cpc_tty == NULL) { + return; + } + + dsr_rx = cpc_readb(card->hw.scabase + DSR_RX(ch)); + + cpc_tty = pc300dev->cpc_tty; + + while (1) { + rx_len = 0; + ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + RX_BD_ADDR(ch, first_bd)); + while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) { + rx_len += cpc_readw(&ptdescr->len); + first_bd = (first_bd + 1) & (N_DMA_RX_BUF - 1); + if (status & DST_EOM) { + break; + } + ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase+cpc_readl(&ptdescr->next)); + } + + if (!rx_len) { + if (dsr_rx & DSR_BOF) { + /* update EDA */ + cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), + RX_BD_ADDR(ch, pc300chan->rx_last_bd)); + } + kfree(new); + return; + } + + if (rx_len > CPC_TTY_MAX_MTU) { + /* Free RX descriptors */ + CPC_TTY_DBG("%s: frame size is invalid.\n",cpc_tty->name); + stats->rx_errors++; + stats->rx_frame_errors++; + cpc_tty_rx_disc_frame(pc300chan); + continue; + } + + new = kmalloc(rx_len + sizeof(st_cpc_rx_buf), GFP_ATOMIC); + if (!new) { + cpc_tty_rx_disc_frame(pc300chan); + continue; + } + + /* dma buf read */ + ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + + RX_BD_ADDR(ch, pc300chan->rx_first_bd)); + + rx_len = 0; /* counter frame size */ + + while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) { + rx_aux = cpc_readw(&ptdescr->len); + if ((status & (DST_OVR | DST_CRC | DST_RBIT | DST_SHRT | DST_ABT)) + || (rx_aux > BD_DEF_LEN)) { + CPC_TTY_DBG("%s: reception error\n", cpc_tty->name); + stats->rx_errors++; + if (status & DST_OVR) { + stats->rx_fifo_errors++; + } + if (status & DST_CRC) { + stats->rx_crc_errors++; + } + if ((status & (DST_RBIT | DST_SHRT | DST_ABT)) || + (rx_aux > BD_DEF_LEN)) { + stats->rx_frame_errors++; + } + /* discard remainig descriptors used by the bad frame */ + CPC_TTY_DBG("%s: reception error - discard descriptors", + cpc_tty->name); + cpc_tty_rx_disc_frame(pc300chan); + rx_len = 0; + kfree(new); + new = NULL; + break; /* read next frame - while(1) */ + } + + if (cpc_tty->state != CPC_TTY_ST_OPEN) { + /* Free RX descriptors */ + cpc_tty_rx_disc_frame(pc300chan); + stats->rx_dropped++; + rx_len = 0; + kfree(new); + new = NULL; + break; /* read next frame - while(1) */ + } + + /* read the segment of the frame */ + if (rx_aux != 0) { + memcpy_fromio((new->data + rx_len), + (void __iomem *)(card->hw.rambase + + cpc_readl(&ptdescr->ptbuf)), rx_aux); + rx_len += rx_aux; + } + cpc_writeb(&ptdescr->status,0); + cpc_writeb(&ptdescr->len, 0); + pc300chan->rx_first_bd = (pc300chan->rx_first_bd + 1) & + (N_DMA_RX_BUF -1); + if (status & DST_EOM)break; + + ptdescr = (pcsca_bd_t __iomem *) (card->hw.rambase + + cpc_readl(&ptdescr->next)); + } + /* update pointer */ + pc300chan->rx_last_bd = (pc300chan->rx_first_bd - 1) & + (N_DMA_RX_BUF - 1) ; + if (!(dsr_rx & DSR_BOF)) { + /* update EDA */ + cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), + RX_BD_ADDR(ch, pc300chan->rx_last_bd)); + } + if (rx_len != 0) { + stats->rx_bytes += rx_len; + + if (pc300dev->trace_on) { + cpc_tty_trace(pc300dev, new->data,rx_len, 'R'); + } + new->size = rx_len; + new->next = NULL; + if (cpc_tty->buf_rx.first == NULL) { + cpc_tty->buf_rx.first = new; + cpc_tty->buf_rx.last = new; + } else { + cpc_tty->buf_rx.last->next = new; + cpc_tty->buf_rx.last = new; + } + schedule_work(&(cpc_tty->tty_rx_work)); + stats->rx_packets++; + } + } +} + +/* + * PC300 TTY TX work routine + * + * This routine treats TX interrupt. + * o if need call line discipline wakeup + * o call wake_up_interruptible + */ +static void cpc_tty_tx_work(struct work_struct *work) +{ + st_cpc_tty_area *cpc_tty = + container_of(work, st_cpc_tty_area, tty_tx_work); + struct tty_struct *tty; + + CPC_TTY_DBG("%s: cpc_tty_tx_work init\n",cpc_tty->name); + + if ((tty = cpc_tty->tty) == NULL) { + CPC_TTY_DBG("%s: the interface is not opened\n",cpc_tty->name); + return; + } + tty_wakeup(tty); +} + +/* + * PC300 TTY send to card routine + * + * This routine send data to card. + * o clear descriptors + * o write data to DMA buffers + * o start the transmission + */ +static int cpc_tty_send_to_card(pc300dev_t *dev,void* buf, int len) +{ + pc300ch_t *chan = (pc300ch_t *)dev->chan; + pc300_t *card = (pc300_t *)chan->card; + int ch = chan->channel; + struct net_device_stats *stats = &dev->dev->stats; + unsigned long flags; + volatile pcsca_bd_t __iomem *ptdescr; + int i, nchar; + int tosend = len; + int nbuf = ((len - 1)/BD_DEF_LEN) + 1; + unsigned char *pdata=buf; + + CPC_TTY_DBG("%s:cpc_tty_send_to_cars len=%i", + (st_cpc_tty_area *)dev->cpc_tty->name,len); + + if (nbuf >= card->chan[ch].nfree_tx_bd) { + return 1; + } + + /* write buffer to DMA buffers */ + CPC_TTY_DBG("%s: call dma_buf_write\n", + (st_cpc_tty_area *)dev->cpc_tty->name); + for (i = 0 ; i < nbuf ; i++) { + ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + + TX_BD_ADDR(ch, card->chan[ch].tx_next_bd)); + nchar = (BD_DEF_LEN > tosend) ? tosend : BD_DEF_LEN; + if (cpc_readb(&ptdescr->status) & DST_OSB) { + memcpy_toio((void __iomem *)(card->hw.rambase + + cpc_readl(&ptdescr->ptbuf)), + &pdata[len - tosend], + nchar); + card->chan[ch].nfree_tx_bd--; + if ((i + 1) == nbuf) { + /* This must be the last BD to be used */ + cpc_writeb(&ptdescr->status, DST_EOM); + } else { + cpc_writeb(&ptdescr->status, 0); + } + cpc_writew(&ptdescr->len, nchar); + } else { + CPC_TTY_DBG("%s: error in dma_buf_write\n", + (st_cpc_tty_area *)dev->cpc_tty->name); + stats->tx_dropped++; + return 1; + } + tosend -= nchar; + card->chan[ch].tx_next_bd = + (card->chan[ch].tx_next_bd + 1) & (N_DMA_TX_BUF - 1); + } + + if (dev->trace_on) { + cpc_tty_trace(dev, buf, len,'T'); + } + + /* start transmission */ + CPC_TTY_DBG("%s: start transmission\n", + (st_cpc_tty_area *)dev->cpc_tty->name); + + CPC_TTY_LOCK(card, flags); + cpc_writeb(card->hw.scabase + DTX_REG(EDAL, ch), + TX_BD_ADDR(ch, chan->tx_next_bd)); + cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_ENA); + cpc_writeb(card->hw.scabase + DSR_TX(ch), DSR_DE); + + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) | + (CPLD_REG2_FALC_LED1 << (2 * ch))); + } + CPC_TTY_UNLOCK(card, flags); + return 0; +} + +/* + * PC300 TTY trace routine + * + * This routine send trace of connection to application. + * o clear descriptors + * o write data to DMA buffers + * o start the transmission + */ + +static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx) +{ + struct sk_buff *skb; + + if ((skb = dev_alloc_skb(10 + len)) == NULL) { + /* out of memory */ + CPC_TTY_DBG("%s: tty_trace - out of memory\n", dev->dev->name); + return; + } + + skb_put (skb, 10 + len); + skb->dev = dev->dev; + skb->protocol = htons(ETH_P_CUST); + skb_reset_mac_header(skb); + skb->pkt_type = PACKET_HOST; + skb->len = 10 + len; + + skb_copy_to_linear_data(skb, dev->dev->name, 5); + skb->data[5] = '['; + skb->data[6] = rxtx; + skb->data[7] = ']'; + skb->data[8] = ':'; + skb->data[9] = ' '; + skb_copy_to_linear_data_offset(skb, 10, buf, len); + netif_rx(skb); +} + +/* + * PC300 TTY unregister service routine + * + * This routine unregister one interface. + */ +void cpc_tty_unregister_service(pc300dev_t *pc300dev) +{ + st_cpc_tty_area *cpc_tty; + ulong flags; + int res; + + if ((cpc_tty= (st_cpc_tty_area *) pc300dev->cpc_tty) == NULL) { + CPC_TTY_DBG("%s: interface is not TTY\n", pc300dev->dev->name); + return; + } + CPC_TTY_DBG("%s: cpc_tty_unregister_service", cpc_tty->name); + + if (cpc_tty->pc300dev != pc300dev) { + CPC_TTY_DBG("%s: invalid tty ptr=%s\n", + pc300dev->dev->name, cpc_tty->name); + return; + } + + if (--cpc_tty_cnt == 0) { + if (serial_drv.refcount) { + CPC_TTY_DBG("%s: unregister is not possible, refcount=%d", + cpc_tty->name, serial_drv.refcount); + cpc_tty_cnt++; + cpc_tty_unreg_flag = 1; + return; + } else { + CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name); + if ((res=tty_unregister_driver(&serial_drv))) { + CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n", + cpc_tty->name,res); + } + } + } + CPC_TTY_LOCK(pc300dev->chan->card,flags); + cpc_tty->tty = NULL; + CPC_TTY_UNLOCK(pc300dev->chan->card, flags); + cpc_tty->tty_minor = 0; + cpc_tty->state = CPC_TTY_ST_IDLE; +} + +/* + * PC300 TTY trigger poll routine + * This routine is called by pc300driver to treats Tx interrupt. + */ +void cpc_tty_trigger_poll(pc300dev_t *pc300dev) +{ + st_cpc_tty_area *cpc_tty = (st_cpc_tty_area *)pc300dev->cpc_tty; + if (!cpc_tty) { + return; + } + schedule_work(&(cpc_tty->tty_tx_work)); +} -- cgit v0.10.2 From fe3f8f87edf99d9d5122f890208538e0afabd8ce Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 13 Apr 2012 10:24:18 +0100 Subject: staging:iio:light:tsl2563 channel spec buglet / always reading same adc. The IIO_LIGHT channel was not marked as being a processed_val despite clearly being in lux. The IIO_INTENSITY channel reads were dependent on channel and that isn't specified for either adc (as they now use modifiers). Hence use the modifier instead. Reported-by: Jon Brenner Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c index 546c95a..beb51d71 100644 --- a/drivers/staging/iio/light/tsl2563.c +++ b/drivers/staging/iio/light/tsl2563.c @@ -465,7 +465,7 @@ static int tsl2563_write_raw(struct iio_dev *indio_dev, { struct tsl2563_chip *chip = iio_priv(indio_dev); - if (chan->channel == 0) + if (chan->channel == IIO_MOD_LIGHT_BOTH) chip->calib0 = calib_from_sysfs(val); else chip->calib1 = calib_from_sysfs(val); @@ -534,6 +534,7 @@ static const struct iio_chan_spec tsl2563_channels[] = { { .type = IIO_LIGHT, .indexed = 1, + .processed_val = 1, .channel = 0, }, { .type = IIO_INTENSITY, -- cgit v0.10.2 From a7322fc2fa6417a5bc4f0a40e6e79608505416e2 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 13 Apr 2012 10:24:19 +0100 Subject: staging:iio:Documentation: Fix a cut and paste error. falling is repeated in some entries instead of 1x falling and 1x rising for the entry. Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio b/drivers/staging/iio/Documentation/sysfs-bus-iio index 46a995d..ca12784 100644 --- a/drivers/staging/iio/Documentation/sysfs-bus-iio +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio @@ -453,9 +453,9 @@ What: /sys/.../events/in_magn_z_raw_thresh_rising_value What: /sys/.../events/in_magn_z_raw_thresh_falling_value What: /sys/.../events/in_voltageY_supply_raw_thresh_rising_value What: /sys/.../events/in_voltageY_supply_raw_thresh_falling_value +What: /sys/.../events/in_voltageY_raw_thresh_rising_value What: /sys/.../events/in_voltageY_raw_thresh_falling_value -What: /sys/.../events/in_voltageY_raw_thresh_falling_value -What: /sys/.../events/in_tempY_raw_thresh_falling_value +What: /sys/.../events/in_tempY_raw_thresh_rising_value What: /sys/.../events/in_tempY_raw_thresh_falling_value KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org @@ -490,9 +490,9 @@ What: /sys/.../events/in_magn_z_raw_roc_rising_value What: /sys/.../events/in_magn_z_raw_roc_falling_value What: /sys/.../events/in_voltageY_supply_raw_roc_rising_value What: /sys/.../events/in_voltageY_supply_raw_roc_falling_value +What: /sys/.../events/in_voltageY_raw_roc_rising_value What: /sys/.../events/in_voltageY_raw_roc_falling_value -What: /sys/.../events/in_voltageY_raw_roc_falling_value -What: /sys/.../events/in_tempY_raw_roc_falling_value +What: /sys/.../events/in_tempY_raw_roc_rising_value What: /sys/.../events/in_tempY_raw_roc_falling_value KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org -- cgit v0.10.2 From ef97d4217389409f3c72b85dacd4be4b1bcef413 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 13 Apr 2012 10:24:20 +0100 Subject: staging:iio:iio_core.h make less dependent on other included headers There are a lot of pointers to structures used in here that are not declared unless a particular header is included first. Deal with the IIO specific ones by putting in forward declarations and the other ones by including kernel.h and device.h. Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/iio_core.h b/drivers/staging/iio/iio_core.h index c9dfcba..f652e6a 100644 --- a/drivers/staging/iio/iio_core.h +++ b/drivers/staging/iio/iio_core.h @@ -12,6 +12,12 @@ #ifndef _IIO_CORE_H_ #define _IIO_CORE_H_ +#include +#include + +struct iio_chan_spec; +struct iio_dev; + int __iio_add_chan_devattr(const char *postfix, struct iio_chan_spec const *chan, -- cgit v0.10.2 From 344692b1ed55852bc53008a999fadd10910b6f23 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 13 Apr 2012 10:24:21 +0100 Subject: staging:iio: chan_spec - take extend_name constant. I can't envision a case where this is not constant and we don't seem to have any in tree, so lets clear up this loose end. Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h index 833a849..4824812 100644 --- a/drivers/staging/iio/iio.h +++ b/drivers/staging/iio/iio.h @@ -164,7 +164,7 @@ struct iio_chan_spec { long info_mask; long event_mask; const struct iio_chan_spec_ext_info *ext_info; - char *extend_name; + const char *extend_name; const char *datasheet_name; unsigned processed_val:1; unsigned modified:1; -- cgit v0.10.2 From e81dafe94228799fa33dd98e602f269d234cbac2 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 13 Apr 2012 10:42:47 +0100 Subject: staging:iio:accel:adis16201 unwind use of IIO_CHAN macro. This macro is being removed to simplify ongoing maintenance so we need to unwind and remaining users. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c index d439e45..88d3d96 100644 --- a/drivers/staging/iio/accel/adis16201_core.c +++ b/drivers/staging/iio/accel/adis16201_core.c @@ -406,39 +406,97 @@ static int adis16201_write_raw(struct iio_dev *indio_dev, } static struct iio_chan_spec adis16201_channels[] = { - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "supply", 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - in_supply, ADIS16201_SCAN_SUPPLY, - IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, - temp, ADIS16201_SCAN_TEMP, - IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, - IIO_CHAN_INFO_SCALE_SHARED_BIT | + { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .extend_name = "supply", + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = in_supply, + .scan_index = ADIS16201_SCAN_SUPPLY, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, + .address = temp, + .scan_index = ADIS16201_SCAN_TEMP, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - accel_x, ADIS16201_SCAN_ACC_X, - IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, - IIO_CHAN_INFO_SCALE_SHARED_BIT | + .address = accel_x, + .scan_index = ADIS16201_SCAN_ACC_X, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - accel_y, ADIS16201_SCAN_ACC_Y, - IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - in_aux, ADIS16201_SCAN_AUX_ADC, - IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_X, - IIO_CHAN_INFO_SCALE_SHARED_BIT | + .address = accel_y, + .scan_index = ADIS16201_SCAN_ACC_Y, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 1, + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = in_aux, + .scan_index = ADIS16201_SCAN_AUX_ADC, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, { + .type = IIO_INCLI, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - incli_x, ADIS16201_SCAN_INCLI_X, - IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_Y, - IIO_CHAN_INFO_SCALE_SHARED_BIT | + .address = incli_x, + .scan_index = ADIS16201_SCAN_INCLI_X, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { + .type = IIO_INCLI, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - incli_y, ADIS16201_SCAN_INCLI_Y, - IIO_ST('s', 14, 16, 0), 0), + .address = incli_y, + .scan_index = ADIS16201_SCAN_INCLI_Y, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, IIO_CHAN_SOFT_TIMESTAMP(7) }; -- cgit v0.10.2 From 554ae9818500962b3df33ff39ea382231d5ac9e7 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 13 Apr 2012 10:42:48 +0100 Subject: staging:iio:accel:adis16203 unwind use of IIO_CHAN macro. This macro is being removed to simplify ongoing maintenance so we need to unwind and remaining users. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c index 1a5140f..b50f04d 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_core.c @@ -372,29 +372,70 @@ static int adis16203_read_raw(struct iio_dev *indio_dev, } static struct iio_chan_spec adis16203_channels[] = { - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "supply", 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - in_supply, ADIS16203_SCAN_SUPPLY, - IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - in_aux, ADIS16203_SCAN_AUX_ADC, - IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_X, - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - incli_x, ADIS16203_SCAN_INCLI_X, - IIO_ST('s', 14, 16, 0), 0), - /* Fixme: Not what it appears to be - see data sheet */ - IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_Y, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - incli_y, ADIS16203_SCAN_INCLI_Y, - IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, - temp, ADIS16203_SCAN_TEMP, - IIO_ST('u', 12, 16, 0), 0), + { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .extend_name = "supply", + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = in_supply, + .scan_index = ADIS16203_SCAN_SUPPLY, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 1, + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = in_aux, + .scan_index = ADIS16203_SCAN_AUX_ADC, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, { + .type = IIO_INCLI, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .address = incli_x, + .scan_index = ADIS16203_SCAN_INCLI_X, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { /* Fixme: Not what it appears to be - see data sheet */ + .type = IIO_INCLI, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = incli_y, + .scan_index = ADIS16203_SCAN_INCLI_Y, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, + .address = temp, + .scan_index = ADIS16203_SCAN_TEMP, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, IIO_CHAN_SOFT_TIMESTAMP(5), }; -- cgit v0.10.2 From 4b788176d8c228859ee92c318c03acb4775639f6 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 13 Apr 2012 10:42:49 +0100 Subject: staging:iio:accel:adis16204 unwind use of IIO_CHAN macro. This macro is being removed to simplify ongoing maintenance so we need to unwind and remaining users. Note that previously the supply was not indexed. I have made it indexed for consistency with other similar devices and for internal consistency with the aux adc port. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index fa89364..fdf31f1 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -444,31 +444,73 @@ static int adis16204_write_raw(struct iio_dev *indio_dev, } static struct iio_chan_spec adis16204_channels[] = { - IIO_CHAN(IIO_VOLTAGE, 0, 0, 0, "supply", 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - in_supply, ADIS16204_SCAN_SUPPLY, - IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - in_aux, ADIS16204_SCAN_AUX_ADC, - IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, - temp, ADIS16204_SCAN_TEMP, - IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, - accel_x, ADIS16204_SCAN_ACC_X, - IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, - accel_y, ADIS16204_SCAN_ACC_Y, - IIO_ST('s', 14, 16, 0), 0), + { + .type = IIO_VOLTAGE, + .indexed = 1, /* Note was not previously indexed */ + .channel = 0, + .extend_name = "supply", + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = in_supply, + .scan_index = ADIS16204_SCAN_SUPPLY, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 1, + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = in_aux, + .scan_index = ADIS16204_SCAN_AUX_ADC, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, + .address = temp, + .scan_index = ADIS16204_SCAN_TEMP, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + IIO_CHAN_INFO_PEAK_SEPARATE_BIT, + .address = accel_x, + .scan_index = ADIS16204_SCAN_ACC_X, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + IIO_CHAN_INFO_PEAK_SEPARATE_BIT, + .address = accel_y, + .scan_index = ADIS16204_SCAN_ACC_Y, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, IIO_CHAN_SOFT_TIMESTAMP(5), }; -- cgit v0.10.2 From f2007e5893fd584ad5d9e1c8b59b5ce15d19ea99 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 13 Apr 2012 10:42:50 +0100 Subject: staging:iio:accel:adis16209 unwind use of IIO_CHAN macro. This macro is being removed to simplify ongoing maintenance so we need to unwind and remaining users. Note the addition of extend_name = "supply" for the supply voltage adc. This brings this driver into line with the other adis parts. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index a98715f..02c003f 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -408,41 +408,106 @@ static int adis16209_read_raw(struct iio_dev *indio_dev, } static struct iio_chan_spec adis16209_channels[] = { - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - in_supply, ADIS16209_SCAN_SUPPLY, - IIO_ST('u', 14, 16, 0), 0), - IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, - temp, ADIS16209_SCAN_TEMP, - IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - accel_x, ADIS16209_SCAN_ACC_X, - IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - accel_y, ADIS16209_SCAN_ACC_Y, - IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - in_aux, ADIS16209_SCAN_AUX_ADC, - IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_X, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - incli_x, ADIS16209_SCAN_INCLI_X, - IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_Y, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - incli_y, ADIS16209_SCAN_INCLI_Y, - IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_ROT, 0, 1, 0, NULL, 0, IIO_MOD_X, - 0, - rot, ADIS16209_SCAN_ROT, - IIO_ST('s', 14, 16, 0), 0), + { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .extend_name = "supply", + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = in_supply, + .scan_index = ADIS16209_SCAN_SUPPLY, + .scan_type = { + .sign = 'u', + .realbits = 14, + .storagebits = 16, + }, + }, { + .type = IIO_TEMP, + .indexed = 0, + .channel = 0, + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, + .address = temp, + .scan_index = ADIS16209_SCAN_TEMP, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .address = accel_x, + .scan_index = ADIS16209_SCAN_ACC_X, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .address = accel_y, + .scan_index = ADIS16209_SCAN_ACC_Y, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 1, + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = in_aux, + .scan_index = ADIS16209_SCAN_AUX_ADC, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, { + .type = IIO_INCLI, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = incli_x, + .scan_index = ADIS16209_SCAN_INCLI_X, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { + .type = IIO_INCLI, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = incli_y, + .scan_index = ADIS16209_SCAN_INCLI_Y, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { + .type = IIO_ROT, + .modified = 1, + .channel2 = IIO_MOD_X, + .address = rot, + .scan_index = ADIS16209_SCAN_ROT, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, IIO_CHAN_SOFT_TIMESTAMP(8) }; -- cgit v0.10.2 From e13f3d5ac0ba8304aa6ba782e35583abcacff40c Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 13 Apr 2012 10:42:51 +0100 Subject: staging:iio:accel:adis16240 unwind use of IIO_CHAN macro. This macro is being removed to simplify ongoing maintenance so we need to unwind and remaining users. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index 17f77fe..fb0b328 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -468,33 +468,82 @@ static int adis16240_write_raw(struct iio_dev *indio_dev, } static struct iio_chan_spec adis16240_channels[] = { - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "supply", 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - in_supply, ADIS16240_SCAN_SUPPLY, - IIO_ST('u', 10, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0, - 0, - in_aux, ADIS16240_SCAN_AUX_ADC, - IIO_ST('u', 10, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - accel_x, ADIS16240_SCAN_ACC_X, - IIO_ST('s', 10, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - accel_y, ADIS16240_SCAN_ACC_Y, - IIO_ST('s', 10, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z, - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - accel_z, ADIS16240_SCAN_ACC_Z, - IIO_ST('s', 10, 16, 0), 0), - IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - temp, ADIS16240_SCAN_TEMP, - IIO_ST('u', 10, 16, 0), 0), + { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .extend_name = "supply", + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = in_supply, + .scan_index = ADIS16240_SCAN_SUPPLY, + .scan_type = { + .sign = 'u', + .realbits = 10, + .storagebits = 16, + }, + }, { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 1, + .address = in_aux, + .scan_index = ADIS16240_SCAN_AUX_ADC, + .scan_type = { + .sign = 'u', + .realbits = 10, + .storagebits = 16, + }, + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .address = accel_x, + .scan_index = ADIS16240_SCAN_ACC_X, + .scan_type = { + .sign = 's', + .realbits = 10, + .storagebits = 16, + }, + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .address = accel_y, + .scan_index = ADIS16240_SCAN_ACC_Y, + .scan_type = { + .sign = 's', + .realbits = 10, + .storagebits = 16, + }, + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_Z, + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .address = accel_z, + .scan_index = ADIS16240_SCAN_ACC_Z, + .scan_type = { + .sign = 's', + .realbits = 10, + .storagebits = 16, + }, + }, { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = temp, + .scan_index = ADIS16240_SCAN_TEMP, + .scan_type = { + .sign = 'u', + .realbits = 10, + .storagebits = 16, + }, + }, IIO_CHAN_SOFT_TIMESTAMP(6) }; -- cgit v0.10.2 From 3badbdac6c1294adc782c47d533254d014adca56 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 13 Apr 2012 10:42:52 +0100 Subject: staging:iio:accel:lis3l02dq unwind use of IIO_CHAN macro. This macro is being removed to simplify ongoing maintenance so we need to unwind and remaining users. Signed-off-by: Jonathan Cameron Reviewed-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index bcf4712..0bb7c70 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -521,13 +521,26 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private) (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \ IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)) +#define LIS3L02DQ_CHAN(index, mod) \ + { \ + .type = IIO_ACCEL, \ + .modified = 1, \ + .channel2 = mod, \ + .info_mask = LIS3L02DQ_INFO_MASK, \ + .address = index, \ + .scan_index = index, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 12, \ + .storagebits = 16, \ + }, \ + .event_mask = LIS3L02DQ_EVENT_MASK, \ + } + static struct iio_chan_spec lis3l02dq_channels[] = { - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, LIS3L02DQ_INFO_MASK, - 0, 0, IIO_ST('s', 12, 16, 0), LIS3L02DQ_EVENT_MASK), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, LIS3L02DQ_INFO_MASK, - 1, 1, IIO_ST('s', 12, 16, 0), LIS3L02DQ_EVENT_MASK), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z, LIS3L02DQ_INFO_MASK, - 2, 2, IIO_ST('s', 12, 16, 0), LIS3L02DQ_EVENT_MASK), + LIS3L02DQ_CHAN(0, IIO_MOD_X), + LIS3L02DQ_CHAN(1, IIO_MOD_Y), + LIS3L02DQ_CHAN(2, IIO_MOD_Z), IIO_CHAN_SOFT_TIMESTAMP(3) }; -- cgit v0.10.2 From 691a4ca1b57ab268aaa9472c2f8f6ebc1aca31e9 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 13 Apr 2012 10:42:53 +0100 Subject: staging:iio:accel:sca3000 unwind use of IIO_CHAN macro. This macro is being removed to simplify ongoing maintenance so we need to unwind and remaining users. Signed-off-by: Jonathan Cameron Reviewed-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index 49764fb..b4a2747 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -433,13 +433,27 @@ static IIO_DEVICE_ATTR(revision, S_IRUGO, sca3000_show_rev, NULL, 0); #define SCA3000_EVENT_MASK \ (IIO_EV_BIT(IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING)) +#define SCA3000_CHAN(index, mod) \ + { \ + .type = IIO_ACCEL, \ + .modified = 1, \ + .channel2 = mod, \ + .info_mask = SCA3000_INFO_MASK, \ + .address = index, \ + .scan_index = index, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 11, \ + .storagebits = 16, \ + .shift = 5, \ + }, \ + .event_mask = SCA3000_EVENT_MASK, \ + } + static struct iio_chan_spec sca3000_channels[] = { - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, SCA3000_INFO_MASK, - 0, 0, IIO_ST('s', 11, 16, 5), SCA3000_EVENT_MASK), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, SCA3000_INFO_MASK, - 1, 1, IIO_ST('s', 11, 16, 5), SCA3000_EVENT_MASK), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z, SCA3000_INFO_MASK, - 2, 2, IIO_ST('s', 11, 16, 5), SCA3000_EVENT_MASK), + SCA3000_CHAN(0, IIO_MOD_X), + SCA3000_CHAN(1, IIO_MOD_Y), + SCA3000_CHAN(2, IIO_MOD_Z), }; static u8 sca3000_addresses[3][3] = { -- cgit v0.10.2 From 95e48f77400c128485543d9420bcb38ec5b1dac5 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 13 Apr 2012 10:42:54 +0100 Subject: staging:iio:adc:ad7298 unwind use of IIO_CHAN macro. This macro is being removed to simplify ongoing maintenance so we need to unwind and remaining users. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c index 8dd6aa9..0cdde18 100644 --- a/drivers/staging/iio/adc/ad7298_core.c +++ b/drivers/staging/iio/adc/ad7298_core.c @@ -22,34 +22,43 @@ #include "ad7298.h" +#define AD7298_V_CHAN(index) \ + { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = index, \ + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .address = index, \ + .scan_index = index, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 12, \ + .storagebits = 16, \ + }, \ + } + static struct iio_chan_spec ad7298_channels[] = { - IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - 9, AD7298_CH_TEMP, IIO_ST('s', 32, 32, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 1, 1, IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 2, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 2, 2, IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 3, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 3, 3, IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 4, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 4, 4, IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 5, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 5, 5, IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 6, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 6, 6, IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 7, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 7, 7, IIO_ST('u', 12, 16, 0), 0), + { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = 9, + .scan_index = AD7298_CH_TEMP, + .scan_type = { + .sign = 's', + .realbits = 32, + .storagebits = 32, + }, + }, + AD7298_V_CHAN(0), + AD7298_V_CHAN(1), + AD7298_V_CHAN(2), + AD7298_V_CHAN(3), + AD7298_V_CHAN(4), + AD7298_V_CHAN(5), + AD7298_V_CHAN(6), + AD7298_V_CHAN(7), IIO_CHAN_SOFT_TIMESTAMP(8), }; -- cgit v0.10.2 From 85871cd8b1154019d05f16fb92f89a8a49c2a64c Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 13 Apr 2012 10:42:55 +0100 Subject: staging:iio:adc:ad7476 unwind use of IIO_CHAN macro. This macro is being removed to simplify ongoing maintenance so we need to unwind and remaining users. V2 has the cleanup Lars-Peter suggested. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c index 0c064d1..694b508 100644 --- a/drivers/staging/iio/adc/ad7476_core.c +++ b/drivers/staging/iio/adc/ad7476_core.c @@ -66,53 +66,50 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, return -EINVAL; } +#define AD7476_CHAN(bits) \ + { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = bits, \ + .storagebits = 16, \ + .shift = 12 - bits, \ + }, \ +} + static const struct ad7476_chip_info ad7476_chip_info_tbl[] = { [ID_AD7466] = { - .channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('u', 12, 16, 0), 0), + .channel[0] = AD7476_CHAN(12), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), }, [ID_AD7467] = { - .channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('u', 10, 16, 2), 0), + .channel[0] = AD7476_CHAN(10), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), }, [ID_AD7468] = { - .channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1 , 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('u', 8, 16, 4), 0), + .channel[0] = AD7476_CHAN(8), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), }, [ID_AD7475] = { - .channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('u', 12, 16, 0), 0), + .channel[0] = AD7476_CHAN(12), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), }, [ID_AD7476] = { - .channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('u', 12, 16, 0), 0), + .channel[0] = AD7476_CHAN(12), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), }, [ID_AD7477] = { - .channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('u', 10, 16, 2), 0), + .channel[0] = AD7476_CHAN(10), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), }, [ID_AD7478] = { - .channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('u', 8, 16, 4), 0), + .channel[0] = AD7476_CHAN(8), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), }, [ID_AD7495] = { - .channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('u', 12, 16, 0), 0), + .channel[0] = AD7476_CHAN(12), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), .int_vref_mv = 2500, }, -- cgit v0.10.2 From 7643f09e9fe057417a5f4ae345b7e43d07427e0b Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 13 Apr 2012 10:42:56 +0100 Subject: staging:iio:accel:ad7780 unwind use of IIO_CHAN macro. This macro is being removed to simplify ongoing maintenance so we need to unwind and remaining users. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c index a13e58c..4f0a6c9 100644 --- a/drivers/staging/iio/adc/ad7780.c +++ b/drivers/staging/iio/adc/ad7780.c @@ -126,14 +126,32 @@ static int ad7780_read_raw(struct iio_dev *indio_dev, static const struct ad7780_chip_info ad7780_chip_info_tbl[] = { [ID_AD7780] = { - .channel = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('s', 24, 32, 8), 0), + .channel = { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + .shift = 8, + }, + }, }, [ID_AD7781] = { - .channel = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('s', 20, 32, 12), 0), + .channel = { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .scan_type = { + .sign = 's', + .realbits = 20, + .storagebits = 32, + .shift = 12, + }, + }, }, }; -- cgit v0.10.2 From bbdb95552752ddf145c0f6017a498d1f0e11c760 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 13 Apr 2012 10:42:57 +0100 Subject: staging:iio:gyro:adis16260 unwind use of IIO_CHAN macro. This macro is being removed to simplify ongoing maintenance so we need to unwind and remaining users. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index 8f6af47..92f024e 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -389,30 +389,71 @@ enum adis16260_channel { }; #define ADIS16260_GYRO_CHANNEL_SET(axis, mod) \ struct iio_chan_spec adis16260_channels_##axis[] = { \ - IIO_CHAN(IIO_ANGL_VEL, 1, 0, 0, NULL, 0, mod, \ - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \ - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ - gyro, ADIS16260_SCAN_GYRO, \ - IIO_ST('s', 14, 16, 0), 0), \ - IIO_CHAN(IIO_ANGL, 1, 0, 0, NULL, 0, mod, \ - 0, \ - angle, ADIS16260_SCAN_ANGL, \ - IIO_ST('u', 14, 16, 0), 0), \ - IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, \ - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ - temp, ADIS16260_SCAN_TEMP, \ - IIO_ST('u', 12, 16, 0), 0), \ - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "supply", 0, 0, \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ - in_supply, ADIS16260_SCAN_SUPPLY, \ - IIO_ST('u', 12, 16, 0), 0), \ - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0, \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ - in_aux, ADIS16260_SCAN_AUX_ADC, \ - IIO_ST('u', 12, 16, 0), 0), \ - IIO_CHAN_SOFT_TIMESTAMP(5) \ + { \ + .type = IIO_ANGL_VEL, \ + .modified = 1, \ + .channel2 = mod, \ + .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \ + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .address = gyro, \ + .scan_index = ADIS16260_SCAN_GYRO, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 14, \ + .storagebits = 16, \ + }, \ + }, { \ + .type = IIO_ANGL, \ + .modified = 1, \ + .channel2 = mod, \ + .address = angle, \ + .scan_index = ADIS16260_SCAN_ANGL, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 14, \ + .storagebits = 16, \ + }, \ + }, { \ + .type = IIO_TEMP, \ + .indexed = 1, \ + .channel = 0, \ + .info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .address = temp, \ + .scan_index = ADIS16260_SCAN_TEMP, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 12, \ + .storagebits = 16, \ + }, \ + }, { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = 0, \ + .extend_name = "supply", \ + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .address = in_supply, \ + .scan_index = ADIS16260_SCAN_SUPPLY, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 12, \ + .storagebits = 16, \ + }, \ + }, { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = 1, \ + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .address = in_aux, \ + .scan_index = ADIS16260_SCAN_AUX_ADC, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 12, \ + .storagebits = 16, \ + }, \ + }, \ + IIO_CHAN_SOFT_TIMESTAMP(5), \ } static const ADIS16260_GYRO_CHANNEL_SET(x, IIO_MOD_X); -- cgit v0.10.2 From cdacc05bfa479997424fa9a3b54c07573b0ce4ed Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 13 Apr 2012 10:42:58 +0100 Subject: staging:iio:impedance-analyzer:ad5933 unwind use of IIO_CHAN macro. This macro is being removed to simplify ongoing maintenance so we need to unwind and remaining users. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index cd82b56..06b9fe2 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -109,15 +109,44 @@ static struct ad5933_platform_data ad5933_default_pdata = { }; static struct iio_chan_spec ad5933_channels[] = { - IIO_CHAN(IIO_TEMP, 0, 1, 1, NULL, 0, 0, 0, - 0, AD5933_REG_TEMP_DATA, IIO_ST('s', 14, 16, 0), 0), - /* Ring Channels */ - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "real_raw", 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - AD5933_REG_REAL_DATA, 0, IIO_ST('s', 16, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "imag_raw", 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - AD5933_REG_IMAG_DATA, 1, IIO_ST('s', 16, 16, 0), 0), + { + .type = IIO_TEMP, + .indexed = 1, + .processed_val = 1, + .channel = 0, + .address = AD5933_REG_TEMP_DATA, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { /* Ring Channels */ + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .extend_name = "real_raw", + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = AD5933_REG_REAL_DATA, + .scan_index = 0, + .scan_type = { + .sign = 's', + .realbits = 16, + .storagebits = 16, + }, + }, { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .extend_name = "imag_raw", + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = AD5933_REG_IMAG_DATA, + .scan_index = 1, + .scan_type = { + .sign = 's', + .realbits = 16, + .storagebits = 16, + }, + }, }; static int ad5933_i2c_write(struct i2c_client *client, -- cgit v0.10.2 From 926c045222aef20b61706372705662480758b10e Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 13 Apr 2012 10:42:59 +0100 Subject: staging:iio:meter:ade7758 unwind use of IIO_CHAN macro. This macro is being removed to simplify ongoing maintenance so we need to unwind and remaining users. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c index 9374d6b..4d6bffa 100644 --- a/drivers/staging/iio/meter/ade7758_core.c +++ b/drivers/staging/iio/meter/ade7758_core.c @@ -662,66 +662,202 @@ static const struct attribute_group ade7758_attribute_group = { }; static struct iio_chan_spec ade7758_channels[] = { - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "raw", 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_A, AD7758_VOLTAGE), - 0, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_CURRENT, 0, 1, 0, "raw", 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_A, AD7758_CURRENT), - 1, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_POWER, 0, 1, 0, "apparent_raw", 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_A, AD7758_APP_PWR), - 2, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_POWER, 0, 1, 0, "active_raw", 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_A, AD7758_ACT_PWR), - 3, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_POWER, 0, 1, 0, "reactive_raw", 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_A, AD7758_REACT_PWR), - 4, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "raw", 1, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_B, AD7758_VOLTAGE), - 5, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_CURRENT, 0, 1, 0, "raw", 1, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_B, AD7758_CURRENT), - 6, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_POWER, 0, 1, 0, "apparent_raw", 1, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_B, AD7758_APP_PWR), - 7, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_POWER, 0, 1, 0, "active_raw", 1, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_B, AD7758_ACT_PWR), - 8, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_POWER, 0, 1, 0, "reactive_raw", 1, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_B, AD7758_REACT_PWR), - 9, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "raw", 2, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_C, AD7758_VOLTAGE), - 10, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_CURRENT, 0, 1, 0, "raw", 2, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_C, AD7758_CURRENT), - 11, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_POWER, 0, 1, 0, "apparent_raw", 2, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_C, AD7758_APP_PWR), - 12, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_POWER, 0, 1, 0, "active_raw", 2, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_C, AD7758_ACT_PWR), - 13, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_POWER, 0, 1, 0, "reactive_raw", 2, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_C, AD7758_REACT_PWR), - 14, IIO_ST('s', 24, 32, 0), 0), + { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .extend_name = "raw", + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_A, AD7758_VOLTAGE), + .scan_index = 0, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_CURRENT, + .indexed = 1, + .channel = 0, + .extend_name = "raw", + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_A, AD7758_CURRENT), + .scan_index = 1, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_POWER, + .indexed = 1, + .channel = 0, + .extend_name = "apparent_raw", + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_A, AD7758_APP_PWR), + .scan_index = 2, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_POWER, + .indexed = 1, + .channel = 0, + .extend_name = "active_raw", + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_A, AD7758_ACT_PWR), + .scan_index = 3, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_POWER, + .indexed = 1, + .channel = 0, + .extend_name = "reactive_raw", + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_A, AD7758_REACT_PWR), + .scan_index = 4, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 1, + .extend_name = "raw", + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_B, AD7758_VOLTAGE), + .scan_index = 5, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_CURRENT, + .indexed = 1, + .channel = 1, + .extend_name = "raw", + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_B, AD7758_CURRENT), + .scan_index = 6, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_POWER, + .indexed = 1, + .channel = 1, + .extend_name = "apparent_raw", + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_B, AD7758_APP_PWR), + .scan_index = 7, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_POWER, + .indexed = 1, + .channel = 1, + .extend_name = "active_raw", + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_B, AD7758_ACT_PWR), + .scan_index = 8, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_POWER, + .indexed = 1, + .channel = 1, + .extend_name = "reactive_raw", + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_B, AD7758_REACT_PWR), + .scan_index = 9, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 2, + .extend_name = "raw", + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_C, AD7758_VOLTAGE), + .scan_index = 10, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_CURRENT, + .indexed = 1, + .channel = 2, + .extend_name = "raw", + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_C, AD7758_CURRENT), + .scan_index = 11, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_POWER, + .indexed = 1, + .channel = 2, + .extend_name = "apparent_raw", + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_C, AD7758_APP_PWR), + .scan_index = 12, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_POWER, + .indexed = 1, + .channel = 2, + .extend_name = "active_raw", + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_C, AD7758_ACT_PWR), + .scan_index = 13, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_POWER, + .indexed = 1, + .channel = 2, + .extend_name = "reactive_raw", + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_C, AD7758_REACT_PWR), + .scan_index = 14, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, IIO_CHAN_SOFT_TIMESTAMP(15), }; -- cgit v0.10.2 From 5b6bd35cc97ccd222282bdce33a8c56bf0ee3560 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 13 Apr 2012 10:43:00 +0100 Subject: staging:iio:core drop the IIO_CHAN macro for ease of maintenance. I was warned long ago that this macro would cause trouble but didn't heed the advice, hence I'm unwinding it now! Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h index 4824812..fa6fca0 100644 --- a/drivers/staging/iio/iio.h +++ b/drivers/staging/iio/iio.h @@ -176,23 +176,6 @@ struct iio_chan_spec { #define IIO_ST(si, rb, sb, sh) \ { .sign = si, .realbits = rb, .storagebits = sb, .shift = sh } -/* Macro assumes input channels */ -#define IIO_CHAN(_type, _mod, _indexed, _proc, _name, _chan, _chan2, \ - _inf_mask, _address, _si, _stype, _event_mask) \ - { .type = _type, \ - .output = 0, \ - .modified = _mod, \ - .indexed = _indexed, \ - .processed_val = _proc, \ - .extend_name = _name, \ - .channel = _chan, \ - .channel2 = _chan2, \ - .info_mask = _inf_mask, \ - .address = _address, \ - .scan_index = _si, \ - .scan_type = _stype, \ - .event_mask = _event_mask } - #define IIO_CHAN_SOFT_TIMESTAMP(_si) \ { .type = IIO_TIMESTAMP, .channel = -1, \ .scan_index = _si, .scan_type = IIO_ST('s', 64, 64, 0) } -- cgit v0.10.2 From ce85a1cbcca799f5f46340f87d2140e2c8a9e45b Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 13 Apr 2012 16:03:31 +0530 Subject: staging: iio: add channel info for sampling frequency Adding channel info IIO_CHAN_INFO_SAMP_FREQ to select different sampling frequency per channel wise. Signed-off-by: Laxman Dewangan Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h index fa6fca0..b07ddd3 100644 --- a/drivers/staging/iio/iio.h +++ b/drivers/staging/iio/iio.h @@ -36,6 +36,7 @@ enum iio_chan_info_enum { IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW, IIO_CHAN_INFO_AVERAGE_RAW, IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY, + IIO_CHAN_INFO_SAMP_FREQ, }; #define IIO_CHAN_INFO_SHARED_BIT(type) BIT(type*2) @@ -81,6 +82,10 @@ enum iio_chan_info_enum { #define IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT \ IIO_CHAN_INFO_SEPARATE_BIT( \ IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) +#define IIO_CHAN_INFO_SAMP_FREQ_SEPARATE_BIT \ + IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_SAMP_FREQ) +#define IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT \ + IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_SAMP_FREQ) enum iio_endian { IIO_CPU, diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index d303bfb..9e42713 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c @@ -90,6 +90,7 @@ static const char * const iio_chan_info_postfix[] = { [IIO_CHAN_INFO_AVERAGE_RAW] = "mean_raw", [IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY] = "filter_low_pass_3db_frequency", + [IIO_CHAN_INFO_SAMP_FREQ] = "sampling_frequency", }; const struct iio_chan_spec -- cgit v0.10.2 From 6d59ba2f9676210b4631e9c447ab1c9faf0a9577 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 13 Apr 2012 16:03:32 +0530 Subject: staging: iio: add driver for isl29028 Intersil's ISL29028 is concurrent Ambient Light and Proximity Sensor device. Add driver to access the light and IR intensity and proximity value via iio interface. Signed-off-by: Laxman Dewangan Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/light/Kconfig b/drivers/staging/iio/light/Kconfig index e7e9159..53b49f7 100644 --- a/drivers/staging/iio/light/Kconfig +++ b/drivers/staging/iio/light/Kconfig @@ -14,6 +14,16 @@ config SENSORS_ISL29018 in lux, proximity infrared sensing and normal infrared sensing. Data from sensor is accessible via sysfs. +config SENSORS_ISL29028 + tristate "Intersil ISL29028 Concurrent Light and Proximity Sensor" + depends on I2C + select REGMAP_I2C + help + Provides driver for the Intersil's ISL29028 device. + This driver supports the sysfs interface to get the ALS, IR intensity, + Proximity value via iio. The ISL29028 provides the concurrent sensing + of ambient light and proximity. + config SENSORS_TSL2563 tristate "TAOS TSL2560, TSL2561, TSL2562 and TSL2563 ambient light sensors" depends on I2C diff --git a/drivers/staging/iio/light/Makefile b/drivers/staging/iio/light/Makefile index 3011fbf..535d313 100644 --- a/drivers/staging/iio/light/Makefile +++ b/drivers/staging/iio/light/Makefile @@ -4,4 +4,5 @@ obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o obj-$(CONFIG_SENSORS_ISL29018) += isl29018.o +obj-$(CONFIG_SENSORS_ISL29028) += isl29028.o obj-$(CONFIG_TSL2583) += tsl2583.o diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c new file mode 100644 index 0000000..e705e45 --- /dev/null +++ b/drivers/staging/iio/light/isl29028.c @@ -0,0 +1,563 @@ +/* + * IIO driver for the light sensor ISL29028. + * ISL29028 is Concurrent Ambient Light and Proximity Sensor + * + * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include "../iio.h" +#include "../sysfs.h" + +#define CONVERSION_TIME_MS 100 + +#define ISL29028_REG_CONFIGURE 0x01 + +#define CONFIGURE_ALS_IR_MODE_ALS 0 +#define CONFIGURE_ALS_IR_MODE_IR BIT(0) +#define CONFIGURE_ALS_IR_MODE_MASK BIT(0) + +#define CONFIGURE_ALS_RANGE_LOW_LUX 0 +#define CONFIGURE_ALS_RANGE_HIGH_LUX BIT(1) +#define CONFIGURE_ALS_RANGE_MASK BIT(1) + +#define CONFIGURE_ALS_DIS 0 +#define CONFIGURE_ALS_EN BIT(2) +#define CONFIGURE_ALS_EN_MASK BIT(2) + +#define CONFIGURE_PROX_DRIVE BIT(3) + +#define CONFIGURE_PROX_SLP_SH 4 +#define CONFIGURE_PROX_SLP_MASK (7 << CONFIGURE_PROX_SLP_SH) + +#define CONFIGURE_PROX_EN BIT(7) +#define CONFIGURE_PROX_EN_MASK BIT(7) + +#define ISL29028_REG_INTERRUPT 0x02 + +#define ISL29028_REG_PROX_DATA 0x08 +#define ISL29028_REG_ALSIR_L 0x09 +#define ISL29028_REG_ALSIR_U 0x0A + +#define ISL29028_REG_TEST1_MODE 0x0E +#define ISL29028_REG_TEST2_MODE 0x0F + +#define ISL29028_NUM_REGS (ISL29028_REG_TEST2_MODE + 1) + +enum als_ir_mode { + MODE_NONE = 0, + MODE_ALS, + MODE_IR +}; + +struct isl29028_chip { + struct device *dev; + struct mutex lock; + struct regmap *regmap; + + unsigned int prox_sampling; + bool enable_prox; + + int lux_scale; + int als_ir_mode; +}; + +static int isl29028_set_proxim_sampling(struct isl29028_chip *chip, + unsigned int sampling) +{ + static unsigned int prox_period[] = {800, 400, 200, 100, 75, 50, 12, 0}; + int sel; + unsigned int period = DIV_ROUND_UP(1000, sampling); + + for (sel = 0; sel < ARRAY_SIZE(prox_period); ++sel) { + if (period >= prox_period[sel]) + break; + } + return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, + CONFIGURE_PROX_SLP_MASK, sel << CONFIGURE_PROX_SLP_SH); +} + +static int isl29028_enable_proximity(struct isl29028_chip *chip, bool enable) +{ + int ret; + int val = 0; + + if (enable) + val = CONFIGURE_PROX_EN; + ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, + CONFIGURE_PROX_EN_MASK, val); + if (ret < 0) + return ret; + + /* Wait for conversion to be complete for first sample */ + mdelay(DIV_ROUND_UP(1000, chip->prox_sampling)); + return 0; +} + +static int isl29028_set_als_scale(struct isl29028_chip *chip, int lux_scale) +{ + int val = (lux_scale == 2000) ? CONFIGURE_ALS_RANGE_HIGH_LUX : + CONFIGURE_ALS_RANGE_LOW_LUX; + + return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, + CONFIGURE_ALS_RANGE_MASK, val); +} + +static int isl29028_set_als_ir_mode(struct isl29028_chip *chip, + enum als_ir_mode mode) +{ + int ret = 0; + + switch (mode) { + case MODE_ALS: + ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, + CONFIGURE_ALS_IR_MODE_MASK, CONFIGURE_ALS_IR_MODE_ALS); + if (ret < 0) + return ret; + + ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, + CONFIGURE_ALS_RANGE_MASK, CONFIGURE_ALS_RANGE_HIGH_LUX); + break; + + case MODE_IR: + ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, + CONFIGURE_ALS_IR_MODE_MASK, CONFIGURE_ALS_IR_MODE_IR); + break; + + case MODE_NONE: + return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, + CONFIGURE_ALS_EN_MASK, CONFIGURE_ALS_DIS); + } + + if (ret < 0) + return ret; + + /* Enable the ALS/IR */ + ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, + CONFIGURE_ALS_EN_MASK, CONFIGURE_ALS_EN); + if (ret < 0) + return ret; + + /* Need to wait for conversion time if ALS/IR mode enabled */ + mdelay(CONVERSION_TIME_MS); + return 0; +} + +static int isl29028_read_als_ir(struct isl29028_chip *chip, int *als_ir) +{ + unsigned int lsb; + unsigned int msb; + int ret; + + ret = regmap_read(chip->regmap, ISL29028_REG_ALSIR_L, &lsb); + if (ret < 0) { + dev_err(chip->dev, + "Error in reading register ALSIR_L err %d\n", ret); + return ret; + } + + ret = regmap_read(chip->regmap, ISL29028_REG_ALSIR_U, &msb); + if (ret < 0) { + dev_err(chip->dev, + "Error in reading register ALSIR_U err %d\n", ret); + return ret; + } + + *als_ir = ((msb & 0xF) << 8) | (lsb & 0xFF); + return 0; +} + +static int isl29028_read_proxim(struct isl29028_chip *chip, int *prox) +{ + unsigned int data; + int ret; + + ret = regmap_read(chip->regmap, ISL29028_REG_PROX_DATA, &data); + if (ret < 0) { + dev_err(chip->dev, "Error in reading register %d, error %d\n", + ISL29028_REG_PROX_DATA, ret); + return ret; + } + *prox = data; + return 0; +} + +static int isl29028_proxim_get(struct isl29028_chip *chip, int *prox_data) +{ + int ret; + + if (!chip->enable_prox) { + ret = isl29028_enable_proximity(chip, true); + if (ret < 0) + return ret; + chip->enable_prox = true; + } + return isl29028_read_proxim(chip, prox_data); +} + +static int isl29028_als_get(struct isl29028_chip *chip, int *als_data) +{ + int ret; + int als_ir_data; + + if (chip->als_ir_mode != MODE_ALS) { + ret = isl29028_set_als_ir_mode(chip, MODE_ALS); + if (ret < 0) { + dev_err(chip->dev, + "Error in enabling ALS mode err %d\n", ret); + return ret; + } + chip->als_ir_mode = MODE_ALS; + } + + ret = isl29028_read_als_ir(chip, &als_ir_data); + if (ret < 0) + return ret; + + /* + * convert als data count to lux. + * if lux_scale = 125, lux = count * 0.031 + * if lux_scale = 2000, lux = count * 0.49 + */ + if (chip->lux_scale == 125) + als_ir_data = (als_ir_data * 31) / 1000; + else + als_ir_data = (als_ir_data * 49) / 100; + + *als_data = als_ir_data; + return 0; +} + +static int isl29028_ir_get(struct isl29028_chip *chip, int *ir_data) +{ + int ret; + + if (chip->als_ir_mode != MODE_IR) { + ret = isl29028_set_als_ir_mode(chip, MODE_IR); + if (ret < 0) { + dev_err(chip->dev, + "Error in enabling IR mode err %d\n", ret); + return ret; + } + chip->als_ir_mode = MODE_IR; + } + return isl29028_read_als_ir(chip, ir_data); +} + +/* Channel IO */ +static int isl29028_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, int val2, long mask) +{ + struct isl29028_chip *chip = iio_priv(indio_dev); + int ret = -EINVAL; + + mutex_lock(&chip->lock); + switch (chan->type) { + case IIO_PROXIMITY: + if (mask != IIO_CHAN_INFO_SAMP_FREQ_SEPARATE_BIT) { + dev_err(chip->dev, + "proximity: mask value 0x%08lx not supported\n", + mask); + break; + } + if (val < 1 || val > 100) { + dev_err(chip->dev, + "Samp_freq %d is not in range[1:100]\n", val); + break; + } + ret = isl29028_set_proxim_sampling(chip, val); + if (ret < 0) { + dev_err(chip->dev, + "Setting proximity samp_freq fail, err %d\n", + ret); + break; + } + chip->prox_sampling = val; + break; + + case IIO_LIGHT: + if (mask != IIO_CHAN_INFO_SCALE_SEPARATE_BIT) { + dev_err(chip->dev, + "light: mask value 0x%08lx not supported\n", + mask); + break; + } + if ((val != 125) && (val != 2000)) { + dev_err(chip->dev, + "lux scale %d is invalid [125, 2000]\n", val); + break; + } + ret = isl29028_set_als_scale(chip, val); + if (ret < 0) { + dev_err(chip->dev, + "Setting lux scale fail with error %d\n", ret); + break; + } + chip->lux_scale = val; + break; + + default: + dev_err(chip->dev, "Unsupported channel type\n"); + break; + } + mutex_unlock(&chip->lock); + return ret; +} + +static int isl29028_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, int *val2, long mask) +{ + struct isl29028_chip *chip = iio_priv(indio_dev); + int ret = -EINVAL; + + mutex_lock(&chip->lock); + switch (mask) { + case 0: + switch (chan->type) { + case IIO_LIGHT: + ret = isl29028_als_get(chip, val); + break; + case IIO_INTENSITY: + ret = isl29028_ir_get(chip, val); + break; + case IIO_PROXIMITY: + ret = isl29028_proxim_get(chip, val); + break; + default: + break; + } + if (ret < 0) + break; + ret = IIO_VAL_INT; + break; + + case IIO_CHAN_INFO_SAMP_FREQ_SEPARATE_BIT: + if (chan->type != IIO_PROXIMITY) + break; + *val = chip->prox_sampling; + ret = IIO_VAL_INT; + break; + + case IIO_CHAN_INFO_SCALE_SEPARATE_BIT: + if (chan->type != IIO_LIGHT) + break; + *val = chip->lux_scale; + ret = IIO_VAL_INT; + break; + + default: + dev_err(chip->dev, "mask value 0x%08lx not supported\n", mask); + break; + } + mutex_unlock(&chip->lock); + return ret; +} + +static IIO_CONST_ATTR(in_proximity_sampling_frequency_available, + "1, 3, 5, 10, 13, 20, 83, 100"); +static IIO_CONST_ATTR(in_illuminance_scale_available, "125, 2000"); + +#define ISL29028_DEV_ATTR(name) (&iio_dev_attr_##name.dev_attr.attr) +#define ISL29028_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr) +static struct attribute *isl29028_attributes[] = { + ISL29028_CONST_ATTR(in_proximity_sampling_frequency_available), + ISL29028_CONST_ATTR(in_illuminance_scale_available), + NULL, +}; + +static const struct attribute_group isl29108_group = { + .attrs = isl29028_attributes, +}; + +static const struct iio_chan_spec isl29028_channels[] = { + { + .type = IIO_LIGHT, + .processed_val = 1, + .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + }, { + .type = IIO_INTENSITY, + }, { + .type = IIO_PROXIMITY, + .info_mask = IIO_CHAN_INFO_SAMP_FREQ_SEPARATE_BIT, + } +}; + +static const struct iio_info isl29028_info = { + .attrs = &isl29108_group, + .driver_module = THIS_MODULE, + .read_raw = &isl29028_read_raw, + .write_raw = &isl29028_write_raw, +}; + +static int isl29028_chip_init(struct isl29028_chip *chip) +{ + int ret; + + chip->enable_prox = false; + chip->prox_sampling = 20; + chip->lux_scale = 2000; + chip->als_ir_mode = MODE_NONE; + + ret = regmap_write(chip->regmap, ISL29028_REG_TEST1_MODE, 0x0); + if (ret < 0) { + dev_err(chip->dev, "%s(): write to reg %d failed, err = %d\n", + __func__, ISL29028_REG_TEST1_MODE, ret); + return ret; + } + ret = regmap_write(chip->regmap, ISL29028_REG_TEST2_MODE, 0x0); + if (ret < 0) { + dev_err(chip->dev, "%s(): write to reg %d failed, err = %d\n", + __func__, ISL29028_REG_TEST2_MODE, ret); + return ret; + } + + ret = regmap_write(chip->regmap, ISL29028_REG_CONFIGURE, 0x0); + if (ret < 0) { + dev_err(chip->dev, "%s(): write to reg %d failed, err = %d\n", + __func__, ISL29028_REG_CONFIGURE, ret); + return ret; + } + + ret = isl29028_set_proxim_sampling(chip, chip->prox_sampling); + if (ret < 0) { + dev_err(chip->dev, "%s(): setting the proximity, err = %d\n", + __func__, ret); + return ret; + } + + ret = isl29028_set_als_scale(chip, chip->lux_scale); + if (ret < 0) + dev_err(chip->dev, "%s(): setting als scale failed, err = %d\n", + __func__, ret); + return ret; +} + +static bool is_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case ISL29028_REG_INTERRUPT: + case ISL29028_REG_PROX_DATA: + case ISL29028_REG_ALSIR_L: + case ISL29028_REG_ALSIR_U: + return true; + default: + return false; + } +} + +static const struct regmap_config isl29028_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .volatile_reg = is_volatile_reg, + .max_register = ISL29028_NUM_REGS - 1, + .num_reg_defaults_raw = ISL29028_NUM_REGS, + .cache_type = REGCACHE_RBTREE, +}; + +static int __devinit isl29028_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct isl29028_chip *chip; + struct iio_dev *indio_dev; + int ret; + + indio_dev = iio_allocate_device(sizeof(*chip)); + if (!indio_dev) { + dev_err(&client->dev, "iio allocation fails\n"); + return -ENOMEM; + } + + chip = iio_priv(indio_dev); + + i2c_set_clientdata(client, indio_dev); + chip->dev = &client->dev; + mutex_init(&chip->lock); + + chip->regmap = devm_regmap_init_i2c(client, &isl29028_regmap_config); + if (IS_ERR(chip->regmap)) { + ret = PTR_ERR(chip->regmap); + dev_err(chip->dev, "regmap initialization failed: %d\n", ret); + goto exit_iio_free; + } + + ret = isl29028_chip_init(chip); + if (ret < 0) { + dev_err(chip->dev, "chip initialization failed: %d\n", ret); + goto exit_iio_free; + } + + indio_dev->info = &isl29028_info; + indio_dev->channels = isl29028_channels; + indio_dev->num_channels = ARRAY_SIZE(isl29028_channels); + indio_dev->name = id->name; + indio_dev->dev.parent = &client->dev; + indio_dev->modes = INDIO_DIRECT_MODE; + ret = iio_device_register(indio_dev); + if (ret < 0) { + dev_err(chip->dev, "iio registration fails with error %d\n", + ret); + goto exit_iio_free; + } + return 0; + +exit_iio_free: + iio_free_device(indio_dev); + return ret; +} + +static int __devexit isl29028_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + + iio_device_unregister(indio_dev); + iio_free_device(indio_dev); + return 0; +} + +static const struct i2c_device_id isl29028_id[] = { + {"isl29028", 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, isl29028_id); + +static const struct of_device_id isl29028_of_match[] = { + { .compatible = "isl,isl29028", }, + { }, +}; +MODULE_DEVICE_TABLE(of, isl29028_of_match); + +static struct i2c_driver isl29028_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "isl29028", + .owner = THIS_MODULE, + .of_match_table = isl29028_of_match, + }, + .probe = isl29028_probe, + .remove = __devexit_p(isl29028_remove), + .id_table = isl29028_id, +}; + +module_i2c_driver(isl29028_driver); + +MODULE_DESCRIPTION("ISL29028 Ambient Light and Proximity Sensor driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Laxman Dewangan "); -- cgit v0.10.2 From b3201b563d36eb799d3f9e14871d5dda2b11f3e8 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 12 Apr 2012 11:05:35 +0200 Subject: staging:iio:adc: Add SPEAr ADC driver This patch implements the basic single data conversion support for the SPEAr600 SoC ADC. The register layout of SPEAr600 differs a bit from other SPEAr SoC variants (e.g. SPEAr3xx). These differences are handled via DT compatible testing. Resulting in a multi-arch binary. This driver is currently tested only on SPEAr600. Future patches may add support for other SoC variants (SPEAr3xx) and features like software buffer or DMA. Signed-off-by: Stefan Roese Acked-by: Jonathan Cameron Acked-by: Viresh Kumar Cc: Greg KH Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/devicetree/bindings/staging/iio/adc/spear-adc.txt b/Documentation/devicetree/bindings/staging/iio/adc/spear-adc.txt new file mode 100644 index 0000000..02ea23a --- /dev/null +++ b/Documentation/devicetree/bindings/staging/iio/adc/spear-adc.txt @@ -0,0 +1,26 @@ +* ST SPEAr ADC device driver + +Required properties: +- compatible: Should be "st,spear600-adc" +- reg: Address and length of the register set for the device +- interrupt-parent: Should be the phandle for the interrupt controller + that services interrupts for this device +- interrupts: Should contain the ADC interrupt +- sampling-frequency: Default sampling frequency + +Optional properties: +- vref-external: External voltage reference in milli-volts. If omitted + the internal voltage reference will be used. +- average-samples: Number of samples to generate an average value. If + omitted, single data conversion will be used. + +Examples: + + adc: adc@d8200000 { + compatible = "st,spear600-adc"; + reg = <0xd8200000 0x1000>; + interrupt-parent = <&vic1>; + interrupts = <6>; + sampling-frequency = <5000000>; + vref-external = <2500>; /* 2.5V VRef */ + }; diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 592eabd..ec006e7 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -202,4 +202,11 @@ config LPC32XX_ADC touchscreen driver, so you can only select one of the two drivers (lpc32xx_adc or lpc32xx_ts). Provides direct access via sysfs. +config SPEAR_ADC + tristate "ST SPEAr ADC" + depends on PLAT_SPEAR + help + Say yes here to build support for the integrated ADC inside the + ST SPEAr SoC. Provides direct access via sysfs. + endmenu diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index f83ab95..14e98b6 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -38,3 +38,4 @@ obj-$(CONFIG_ADT7310) += adt7310.o obj-$(CONFIG_ADT7410) += adt7410.o obj-$(CONFIG_AD7280) += ad7280a.o obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o +obj-$(CONFIG_SPEAR_ADC) += spear_adc.o diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c new file mode 100644 index 0000000..bea5778 --- /dev/null +++ b/drivers/staging/iio/adc/spear_adc.c @@ -0,0 +1,447 @@ +/* + * ST SPEAr ADC driver + * + * Copyright 2012 Stefan Roese + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +/* + * SPEAR registers definitions + */ + +#define SCAN_RATE_LO(x) ((x) & 0xFFFF) +#define SCAN_RATE_HI(x) (((x) >> 0x10) & 0xFFFF) +#define CLK_LOW(x) (((x) & 0xf) << 0) +#define CLK_HIGH(x) (((x) & 0xf) << 4) + +/* Bit definitions for SPEAR_ADC_STATUS */ +#define START_CONVERSION (1 << 0) +#define CHANNEL_NUM(x) ((x) << 1) +#define ADC_ENABLE (1 << 4) +#define AVG_SAMPLE(x) ((x) << 5) +#define VREF_INTERNAL (1 << 9) + +#define DATA_MASK 0x03ff +#define DATA_BITS 10 + +#define MOD_NAME "spear-adc" + +#define ADC_CHANNEL_NUM 8 + +#define CLK_MIN 2500000 +#define CLK_MAX 20000000 + +struct adc_regs_spear3xx { + u32 status; + u32 average; + u32 scan_rate; + u32 clk; /* Not avail for 1340 & 1310 */ + u32 ch_ctrl[ADC_CHANNEL_NUM]; + u32 ch_data[ADC_CHANNEL_NUM]; +}; + +struct chan_data { + u32 lsb; + u32 msb; +}; + +struct adc_regs_spear6xx { + u32 status; + u32 pad[2]; + u32 clk; + u32 ch_ctrl[ADC_CHANNEL_NUM]; + struct chan_data ch_data[ADC_CHANNEL_NUM]; + u32 scan_rate_lo; + u32 scan_rate_hi; + struct chan_data average; +}; + +struct spear_adc_info { + struct device_node *np; + struct adc_regs_spear3xx __iomem *adc_base_spear3xx; + struct adc_regs_spear6xx __iomem *adc_base_spear6xx; + struct clk *clk; + struct completion completion; + u32 current_clk; + u32 sampling_freq; + u32 avg_samples; + u32 vref_external; + u32 value; +}; + +/* + * Functions to access some SPEAr ADC register. Abstracted into + * static inline functions, because of different register offsets + * on different SoC variants (SPEAr300 vs SPEAr600 etc). + */ +static void spear_adc_set_status(struct spear_adc_info *info, u32 val) +{ + __raw_writel(val, &info->adc_base_spear6xx->status); +} + +static void spear_adc_set_clk(struct spear_adc_info *info, u32 val) +{ + u32 clk_high, clk_low, count; + u32 apb_clk = clk_get_rate(info->clk); + + count = (apb_clk + val - 1) / val; + clk_low = count / 2; + clk_high = count - clk_low; + info->current_clk = apb_clk / count; + + __raw_writel(CLK_LOW(clk_low) | CLK_HIGH(clk_high), + &info->adc_base_spear6xx->clk); +} + +static void spear_adc_set_ctrl(struct spear_adc_info *info, int n, + u32 val) +{ + __raw_writel(val, &info->adc_base_spear6xx->ch_ctrl[n]); +} + +static u32 spear_adc_get_average(struct spear_adc_info *info) +{ + if (of_device_is_compatible(info->np, "st,spear600-adc")) { + return __raw_readl(&info->adc_base_spear6xx->average.msb) & + DATA_MASK; + } else { + return __raw_readl(&info->adc_base_spear3xx->average) & + DATA_MASK; + } +} + +static void spear_adc_set_scanrate(struct spear_adc_info *info, u32 rate) +{ + if (of_device_is_compatible(info->np, "st,spear600-adc")) { + __raw_writel(SCAN_RATE_LO(rate), + &info->adc_base_spear6xx->scan_rate_lo); + __raw_writel(SCAN_RATE_HI(rate), + &info->adc_base_spear6xx->scan_rate_hi); + } else { + __raw_writel(rate, &info->adc_base_spear3xx->scan_rate); + } +} + +static int spear_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long mask) +{ + struct spear_adc_info *info = iio_priv(indio_dev); + u32 scale_mv; + u32 status; + + switch (mask) { + case 0: + mutex_lock(&indio_dev->mlock); + + status = CHANNEL_NUM(chan->channel) | + AVG_SAMPLE(info->avg_samples) | + START_CONVERSION | ADC_ENABLE; + if (info->vref_external == 0) + status |= VREF_INTERNAL; + + spear_adc_set_status(info, status); + wait_for_completion(&info->completion); /* set by ISR */ + *val = info->value; + + mutex_unlock(&indio_dev->mlock); + + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + scale_mv = (info->vref_external * 1000) >> DATA_BITS; + *val = scale_mv / 1000; + *val2 = (scale_mv % 1000) * 1000; + return IIO_VAL_INT_PLUS_MICRO; + } + + return -EINVAL; +} + +#define SPEAR_ADC_CHAN(idx) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .channel = idx, \ + .scan_type = { \ + .sign = 'u', \ + .storagebits = 16, \ + }, \ +} + +static struct iio_chan_spec spear_adc_iio_channels[] = { + SPEAR_ADC_CHAN(0), + SPEAR_ADC_CHAN(1), + SPEAR_ADC_CHAN(2), + SPEAR_ADC_CHAN(3), + SPEAR_ADC_CHAN(4), + SPEAR_ADC_CHAN(5), + SPEAR_ADC_CHAN(6), + SPEAR_ADC_CHAN(7), +}; + +static irqreturn_t spear_adc_isr(int irq, void *dev_id) +{ + struct spear_adc_info *info = (struct spear_adc_info *)dev_id; + + /* Read value to clear IRQ */ + info->value = spear_adc_get_average(info); + complete(&info->completion); + + return IRQ_HANDLED; +} + +static int spear_adc_configure(struct spear_adc_info *info) +{ + int i; + + /* Reset ADC core */ + spear_adc_set_status(info, 0); + __raw_writel(0, &info->adc_base_spear6xx->clk); + for (i = 0; i < 8; i++) + spear_adc_set_ctrl(info, i, 0); + spear_adc_set_scanrate(info, 0); + + spear_adc_set_clk(info, info->sampling_freq); + + return 0; +} + +static ssize_t spear_adc_read_frequency(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct spear_adc_info *info = iio_priv(indio_dev); + + return sprintf(buf, "%d\n", info->current_clk); +} + +static ssize_t spear_adc_write_frequency(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct spear_adc_info *info = iio_priv(indio_dev); + u32 clk_high, clk_low, count; + u32 apb_clk = clk_get_rate(info->clk); + unsigned long lval; + int ret; + + ret = kstrtoul(buf, 10, &lval); + if (ret) + return ret; + + mutex_lock(&indio_dev->mlock); + + if ((lval < CLK_MIN) || (lval > CLK_MAX)) { + ret = -EINVAL; + goto out; + } + + count = (apb_clk + lval - 1) / lval; + clk_low = count / 2; + clk_high = count - clk_low; + info->current_clk = apb_clk / count; + spear_adc_set_clk(info, lval); + +out: + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} + +static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, + spear_adc_read_frequency, + spear_adc_write_frequency); + +static struct attribute *spear_attributes[] = { + &iio_dev_attr_sampling_frequency.dev_attr.attr, + NULL +}; + +static const struct attribute_group spear_attribute_group = { + .attrs = spear_attributes, +}; + +static const struct iio_info spear_adc_iio_info = { + .read_raw = &spear_read_raw, + .attrs = &spear_attribute_group, + .driver_module = THIS_MODULE, +}; + +static int __devinit spear_adc_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct spear_adc_info *info; + struct iio_dev *iodev = NULL; + int ret = -ENODEV; + int irq; + + iodev = iio_allocate_device(sizeof(struct spear_adc_info)); + if (!iodev) { + dev_err(dev, "failed allocating iio device\n"); + ret = -ENOMEM; + goto errout1; + } + + info = iio_priv(iodev); + info->np = np; + + /* + * SPEAr600 has a different register layout than other SPEAr SoC's + * (e.g. SPEAr3xx). Let's provide two register base addresses + * to support multi-arch kernels. + */ + info->adc_base_spear6xx = of_iomap(np, 0); + if (!info->adc_base_spear6xx) { + dev_err(dev, "failed mapping memory\n"); + ret = -ENOMEM; + goto errout2; + } + info->adc_base_spear3xx = + (struct adc_regs_spear3xx *)info->adc_base_spear6xx; + + info->clk = clk_get(dev, NULL); + if (IS_ERR(info->clk)) { + dev_err(dev, "failed getting clock\n"); + goto errout3; + } + + ret = clk_prepare(info->clk); + if (ret) { + dev_err(dev, "failed preparing clock\n"); + goto errout4; + } + + ret = clk_enable(info->clk); + if (ret) { + dev_err(dev, "failed enabling clock\n"); + goto errout5; + } + + irq = platform_get_irq(pdev, 0); + if ((irq < 0) || (irq >= NR_IRQS)) { + dev_err(dev, "failed getting interrupt resource\n"); + ret = -EINVAL; + goto errout6; + } + + ret = devm_request_irq(dev, irq, spear_adc_isr, 0, MOD_NAME, info); + if (ret < 0) { + dev_err(dev, "failed requesting interrupt\n"); + goto errout6; + } + + if (of_property_read_u32(np, "sampling-frequency", + &info->sampling_freq)) { + dev_err(dev, "sampling-frequency missing in DT\n"); + ret = -EINVAL; + goto errout6; + } + + /* + * Optional avg_samples defaults to 0, resulting in single data + * conversion + */ + of_property_read_u32(np, "average-samples", &info->avg_samples); + + /* + * Optional vref_external defaults to 0, resulting in internal vref + * selection + */ + of_property_read_u32(np, "vref-external", &info->vref_external); + + spear_adc_configure(info); + + platform_set_drvdata(pdev, iodev); + + init_completion(&info->completion); + + iodev->name = MOD_NAME; + iodev->dev.parent = dev; + iodev->info = &spear_adc_iio_info; + iodev->modes = INDIO_DIRECT_MODE; + iodev->channels = spear_adc_iio_channels; + iodev->num_channels = ARRAY_SIZE(spear_adc_iio_channels); + + ret = iio_device_register(iodev); + if (ret) + goto errout6; + + dev_info(dev, "SPEAR ADC driver loaded, IRQ %d\n", irq); + + return 0; + +errout6: + clk_disable(info->clk); +errout5: + clk_unprepare(info->clk); +errout4: + clk_put(info->clk); +errout3: + iounmap(info->adc_base_spear6xx); +errout2: + iio_free_device(iodev); +errout1: + return ret; +} + +static int __devexit spear_adc_remove(struct platform_device *pdev) +{ + struct iio_dev *iodev = platform_get_drvdata(pdev); + struct spear_adc_info *info = iio_priv(iodev); + + iio_device_unregister(iodev); + platform_set_drvdata(pdev, NULL); + clk_disable(info->clk); + clk_unprepare(info->clk); + clk_put(info->clk); + iounmap(info->adc_base_spear6xx); + iio_free_device(iodev); + + return 0; +} + +static const struct of_device_id spear_adc_dt_ids[] = { + { .compatible = "st,spear600-adc", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, spear_adc_dt_ids); + +static struct platform_driver spear_adc_driver = { + .probe = spear_adc_probe, + .remove = __devexit_p(spear_adc_remove), + .driver = { + .name = MOD_NAME, + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(spear_adc_dt_ids), + }, +}; + +module_platform_driver(spear_adc_driver); + +MODULE_AUTHOR("Stefan Roese "); +MODULE_DESCRIPTION("SPEAr ADC driver"); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 4d7df821277e82ebe2fc9c9af07c928a83f572b8 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 13 Apr 2012 14:12:53 +0100 Subject: staging: comedi: Add module parameters for default buffer size For comedi subdevices that support asynchronous transfer commands, the initial buffer size and maximum buffer size for the transfer are both set to 64 KiB when the comedi device is "attached" to the hardware device. For many applications with reasonable fast sample rates and slow user-space (e.g. Python) these sizes are a bit too small. A task with CAP_SYS_ADMIN privileges can change the maximum buffer size for a comedi subdevice with an ioctl call or by writing to a device attribute file in sysfs, but that's not very convenient. For comedi devices attached during system startup, this could be done by a start-up script, but for hot-plugged devices it would require scripts run by udev rules, etc. Rather than use hardwired values, this patch introduces a couple of module parameters to set the defaults for the initial buffer size (comedi_default_buf_size_kb) and maximum buffer size (comedi_default_buf_maxsize_kb). These values are applied in place of the previous hard-wired values when the comedi device is "attached". The module parameter values are in units of KiB for consistency with the existing device attribute files. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index fdf4282..ef7bbe4 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -55,17 +55,40 @@ MODULE_AUTHOR("http://www.comedi.org"); MODULE_DESCRIPTION("Comedi core module"); MODULE_LICENSE("GPL"); +#define DEFAULT_BUF_MAXSIZE_KB 64 +#define DEFAULT_BUF_SIZE_KB 64 + #ifdef CONFIG_COMEDI_DEBUG int comedi_debug; EXPORT_SYMBOL(comedi_debug); -module_param(comedi_debug, int, 0644); +module_param(comedi_debug, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(comedi_debug, + "enable comedi core and driver debugging if non-zero (default 0)" + ); #endif bool comedi_autoconfig = 1; -module_param(comedi_autoconfig, bool, 0444); +module_param(comedi_autoconfig, bool, S_IRUGO); +MODULE_PARM_DESC(comedi_autoconfig, + "enable drivers to auto-configure comedi devices (default 1)"); static int comedi_num_legacy_minors; -module_param(comedi_num_legacy_minors, int, 0444); +module_param(comedi_num_legacy_minors, int, S_IRUGO); +MODULE_PARM_DESC(comedi_num_legacy_minors, + "number of comedi minor devices to reserve for non-auto-configured devices (default 0)" + ); + +unsigned int comedi_default_buf_size_kb = DEFAULT_BUF_SIZE_KB; +module_param(comedi_default_buf_size_kb, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(comedi_default_buf_size_kb, + "default asynchronous buffer size in KiB (default " + __MODULE_STRING(DEFAULT_BUF_SIZE_KB) ")"); + +unsigned int comedi_default_buf_maxsize_kb = DEFAULT_BUF_MAXSIZE_KB; +module_param(comedi_default_buf_maxsize_kb, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(comedi_default_buf_maxsize_kb, + "default maximum size of asynchronous buffer in KiB (default " + __MODULE_STRING(DEFAULT_BUF_MAXSIZE_KB) ")"); static DEFINE_SPINLOCK(comedi_file_info_table_lock); static struct comedi_device_file_info diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 872b598b..49681a1 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -239,6 +239,8 @@ static int postconfig(struct comedi_device *dev) s->len_chanlist = 1; if (s->do_cmd) { + unsigned int buf_size; + BUG_ON((s->subdev_flags & (SDF_CMD_READ | SDF_CMD_WRITE)) == 0); BUG_ON(!s->do_cmdtest); @@ -254,19 +256,20 @@ static int postconfig(struct comedi_device *dev) async->subdevice = s; s->async = async; -#define DEFAULT_BUF_MAXSIZE (64*1024) -#define DEFAULT_BUF_SIZE (64*1024) - - async->max_bufsize = DEFAULT_BUF_MAXSIZE; + async->max_bufsize = + comedi_default_buf_maxsize_kb * 1024; + buf_size = comedi_default_buf_size_kb * 1024; + if (buf_size > async->max_bufsize) + buf_size = async->max_bufsize; async->prealloc_buf = NULL; async->prealloc_bufsz = 0; - if (comedi_buf_alloc(dev, s, DEFAULT_BUF_SIZE) < 0) { + if (comedi_buf_alloc(dev, s, buf_size) < 0) { printk(KERN_INFO "Buffer allocation failed\n"); return -ENOMEM; } if (s->buf_change) { - ret = s->buf_change(dev, s, DEFAULT_BUF_SIZE); + ret = s->buf_change(dev, s, buf_size); if (ret < 0) return ret; } diff --git a/drivers/staging/comedi/internal.h b/drivers/staging/comedi/internal.h index 4208fb4..7ed20a0 100644 --- a/drivers/staging/comedi/internal.h +++ b/drivers/staging/comedi/internal.h @@ -1,5 +1,5 @@ /* - * various internal comedi functions + * various internal comedi stuff */ int do_rangeinfo_ioctl(struct comedi_device *dev, struct comedi_rangeinfo __user *arg); @@ -11,3 +11,6 @@ int comedi_find_board_minor(struct device *hardware_device); void comedi_reset_async_buf(struct comedi_async *async); int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size); + +extern unsigned int comedi_default_buf_size_kb; +extern unsigned int comedi_default_buf_maxsize_kb; -- cgit v0.10.2 From 234bb3c60f1f1489630750aba4adf40154e0bd70 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 13 Apr 2012 14:12:54 +0100 Subject: staging: comedi: Add kernel config for default buffer sizes Allow the default values for the module parameters for the default initial buffer size and default maximum buffer size to be specified in the kernel configuration. I'm not sure what the defaults for the defaults for the defaults should be, but 64 KiB seems to small, so I used values suggested by Bernd Porr, which are 2048 KiB for the default initial buffer size and 20480 for the default maximum buffer size. Signed-off-by: Ian Abbott Cc: Bernd Porr Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 9037d02..a1cf0b0 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -14,6 +14,26 @@ config COMEDI_DEBUG This is an option for use by developers; most people should say N here. This enables comedi core and driver debugging. +config COMEDI_DEFAULT_BUF_SIZE_KB + int "Comedi default initial asynchronous buffer size in KiB" + default "2048" + depends on COMEDI != n + ---help--- + This is the default asynchronous buffer size which is used for + commands running in the background in kernel space. This + defaults to 2048 KiB of memory so that a 16 channel card + running at 10 kHz has of 2-4 seconds of buffer. + +config COMEDI_DEFAULT_BUF_MAXSIZE_KB + int "Comedi default maximum asynchronous buffer size in KiB" + default "20480" + depends on COMEDI != n + ---help--- + This is the default maximum asynchronous buffer size which can + be requested by a userspace program without root privileges. + This is set to 20480 KiB so that a fast I/O card with 16 + channels running at 100 kHz has 2-4 seconds of buffer. + menuconfig COMEDI_MISC_DRIVERS tristate "Comedi misc drivers" depends on COMEDI diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index ef7bbe4..3222ac6 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -55,9 +55,6 @@ MODULE_AUTHOR("http://www.comedi.org"); MODULE_DESCRIPTION("Comedi core module"); MODULE_LICENSE("GPL"); -#define DEFAULT_BUF_MAXSIZE_KB 64 -#define DEFAULT_BUF_SIZE_KB 64 - #ifdef CONFIG_COMEDI_DEBUG int comedi_debug; EXPORT_SYMBOL(comedi_debug); @@ -78,17 +75,18 @@ MODULE_PARM_DESC(comedi_num_legacy_minors, "number of comedi minor devices to reserve for non-auto-configured devices (default 0)" ); -unsigned int comedi_default_buf_size_kb = DEFAULT_BUF_SIZE_KB; +unsigned int comedi_default_buf_size_kb = CONFIG_COMEDI_DEFAULT_BUF_SIZE_KB; module_param(comedi_default_buf_size_kb, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(comedi_default_buf_size_kb, "default asynchronous buffer size in KiB (default " - __MODULE_STRING(DEFAULT_BUF_SIZE_KB) ")"); + __MODULE_STRING(CONFIG_COMEDI_DEFAULT_BUF_SIZE_KB) ")"); -unsigned int comedi_default_buf_maxsize_kb = DEFAULT_BUF_MAXSIZE_KB; +unsigned int comedi_default_buf_maxsize_kb + = CONFIG_COMEDI_DEFAULT_BUF_MAXSIZE_KB; module_param(comedi_default_buf_maxsize_kb, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(comedi_default_buf_maxsize_kb, "default maximum size of asynchronous buffer in KiB (default " - __MODULE_STRING(DEFAULT_BUF_MAXSIZE_KB) ")"); + __MODULE_STRING(CONFIG_COMEDI_DEFAULT_BUF_MAXSIZE_KB) ")"); static DEFINE_SPINLOCK(comedi_file_info_table_lock); static struct comedi_device_file_info -- cgit v0.10.2 From a6c8ef9526f149ce884b36841cc2e17ca890f1a4 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 9 Apr 2012 22:51:58 +0200 Subject: staging: vt6656: Don't needlessly test for NULL before release_firmware() Checking for a NULL pointer before calling release_firmware() is redundant since the function does that check itself. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 763e028..ee5261a 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -1257,9 +1257,7 @@ static void __devexit vt6656_disconnect(struct usb_interface *intf) } device_release_WPADEV(device); - - if (device->firmware) - release_firmware(device->firmware); + release_firmware(device->firmware); usb_set_intfdata(intf, NULL); usb_put_dev(interface_to_usbdev(intf)); -- cgit v0.10.2 From c5714b5acfb0ea7816340ba37bb8631c7061448e Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 9 Apr 2012 22:51:48 +0200 Subject: staging: as102: Remove redundant NULL check before release_firmware() and pointless comments release_firmware() deals gracefullt with NULL pointers - it's redundant to check for them before calling the function. Also remove a few pointless comments - it's rather obvious from the code that kfree() free's a buffer and that release_firmware() releases firmware - comments just stating that add no value. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/media/as102/as102_fw.c b/drivers/staging/media/as102/as102_fw.c index 43ebc43..9db275e 100644 --- a/drivers/staging/media/as102/as102_fw.c +++ b/drivers/staging/media/as102/as102_fw.c @@ -230,11 +230,8 @@ int as102_fw_upload(struct as10x_bus_adapter_t *bus_adap) pr_info("%s: firmware: %s loaded with success\n", DRIVER_NAME, fw2); error: - /* free data buffer */ kfree(cmd_buf); - /* release firmware if needed */ - if (firmware != NULL) - release_firmware(firmware); + release_firmware(firmware); LEAVE(); return errno; -- cgit v0.10.2 From 892cb6dc9fbbfa7281f3aa53aa6599618aec7cb1 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Mon, 16 Apr 2012 21:27:42 +0530 Subject: staging: iio: light: isl29028: fix correct mask value The mask value in the read_raw/write_raw is absolute value, not the bit position value. Fixing this in the implemented function to check value, not with the bit position value. Signed-off-by: Laxman Dewangan Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c index e705e45..4e6ac24 100644 --- a/drivers/staging/iio/light/isl29028.c +++ b/drivers/staging/iio/light/isl29028.c @@ -272,7 +272,7 @@ static int isl29028_write_raw(struct iio_dev *indio_dev, mutex_lock(&chip->lock); switch (chan->type) { case IIO_PROXIMITY: - if (mask != IIO_CHAN_INFO_SAMP_FREQ_SEPARATE_BIT) { + if (mask != IIO_CHAN_INFO_SAMP_FREQ) { dev_err(chip->dev, "proximity: mask value 0x%08lx not supported\n", mask); @@ -294,7 +294,7 @@ static int isl29028_write_raw(struct iio_dev *indio_dev, break; case IIO_LIGHT: - if (mask != IIO_CHAN_INFO_SCALE_SEPARATE_BIT) { + if (mask != IIO_CHAN_INFO_SCALE) { dev_err(chip->dev, "light: mask value 0x%08lx not supported\n", mask); @@ -349,14 +349,14 @@ static int isl29028_read_raw(struct iio_dev *indio_dev, ret = IIO_VAL_INT; break; - case IIO_CHAN_INFO_SAMP_FREQ_SEPARATE_BIT: + case IIO_CHAN_INFO_SAMP_FREQ: if (chan->type != IIO_PROXIMITY) break; *val = chip->prox_sampling; ret = IIO_VAL_INT; break; - case IIO_CHAN_INFO_SCALE_SEPARATE_BIT: + case IIO_CHAN_INFO_SCALE: if (chan->type != IIO_LIGHT) break; *val = chip->lux_scale; -- cgit v0.10.2 From 35a36e650558855cd76981b73e282874a9c77335 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Mon, 16 Apr 2012 13:25:18 -0400 Subject: staging: comedi: COMEDI_CB_EOA is also used to report end-of-output. Update comments in comedi.h accordingly. Signed-off-by: W. Trevor King Acked-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index 14ea35a..8ea55ae 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -465,7 +465,7 @@ /* only relevant to kernel modules. */ #define COMEDI_CB_EOS 1 /* end of scan */ -#define COMEDI_CB_EOA 2 /* end of acquisition */ +#define COMEDI_CB_EOA 2 /* end of acquisition/output */ #define COMEDI_CB_BLOCK 4 /* data has arrived: * wakes up read() / write() */ #define COMEDI_CB_EOBUF 8 /* DEPRECATED: end of buffer */ -- cgit v0.10.2 From 5ccb3adbd7593b69d1355454b0c6d2dffdad51d9 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 15 Apr 2012 17:41:16 +0100 Subject: staging:iio: add a raw and processed elements to info_mask This will allow us to have drivers where the channel value may not be read or written but other information is available. Also adds the ability to have both processed and raw access to a given channel, though in most cases this doesn't make sense. Ultimately will lead to simpler code by allowing us to drop the special case handling for the value reading cases. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h index b07ddd3..dda1602 100644 --- a/drivers/staging/iio/iio.h +++ b/drivers/staging/iio/iio.h @@ -26,8 +26,9 @@ enum iio_data_type { /* Could add the raw attributes as well - allowing buffer only devices */ enum iio_chan_info_enum { - /* 0 is reserved for raw attributes */ - IIO_CHAN_INFO_SCALE = 1, + IIO_CHAN_INFO_RAW = 0, + IIO_CHAN_INFO_PROCESSED, + IIO_CHAN_INFO_SCALE, IIO_CHAN_INFO_OFFSET, IIO_CHAN_INFO_CALIBSCALE, IIO_CHAN_INFO_CALIBBIAS, @@ -42,6 +43,10 @@ enum iio_chan_info_enum { #define IIO_CHAN_INFO_SHARED_BIT(type) BIT(type*2) #define IIO_CHAN_INFO_SEPARATE_BIT(type) BIT(type*2 + 1) +#define IIO_CHAN_INFO_RAW_SEPARATE_BIT \ + IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_RAW) +#define IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT \ + IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_PROCESSED) #define IIO_CHAN_INFO_SCALE_SEPARATE_BIT \ IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_SCALE) #define IIO_CHAN_INFO_SCALE_SHARED_BIT \ diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index 9e42713..817e3fa 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c @@ -576,7 +576,8 @@ error_ret: static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev, struct iio_chan_spec const *chan) { - int ret, i, attrcount = 0; + int ret, attrcount = 0; + int i = 4; const struct iio_chan_spec_ext_info *ext_info; if (chan->channel < 0) @@ -595,7 +596,7 @@ static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev, goto error_ret; attrcount++; - for_each_set_bit(i, &chan->info_mask, sizeof(long)*8) { + for_each_set_bit_from(i, &chan->info_mask, sizeof(long)*8) { ret = __iio_add_chan_devattr(iio_chan_info_postfix[i/2], chan, &iio_read_channel_info, -- cgit v0.10.2 From 31313fc64d51bbd8979997f9d6670cc882c5f963 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 15 Apr 2012 17:41:17 +0100 Subject: staging:iio:accel Add IIO_CHAN_INFO_RAW entries to all drivers. Precursor to making value read / write attribute optional. No processed values in accelerometers. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c index 88d3d96..8022bbd 100644 --- a/drivers/staging/iio/accel/adis16201_core.c +++ b/drivers/staging/iio/accel/adis16201_core.c @@ -298,7 +298,7 @@ static int adis16201_read_raw(struct iio_dev *indio_dev, s16 val16; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); addr = adis16201_addresses[chan->address][0]; ret = adis16201_spi_read_reg_16(indio_dev, addr, &val16); @@ -411,7 +411,8 @@ static struct iio_chan_spec adis16201_channels[] = { .indexed = 1, .channel = 0, .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_supply, .scan_index = ADIS16201_SCAN_SUPPLY, .scan_type = { @@ -423,8 +424,9 @@ static struct iio_chan_spec adis16201_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, .address = temp, .scan_index = ADIS16201_SCAN_TEMP, .scan_type = { @@ -436,7 +438,8 @@ static struct iio_chan_spec adis16201_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, .address = accel_x, .scan_index = ADIS16201_SCAN_ACC_X, @@ -449,7 +452,8 @@ static struct iio_chan_spec adis16201_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, .address = accel_y, .scan_index = ADIS16201_SCAN_ACC_Y, @@ -462,7 +466,8 @@ static struct iio_chan_spec adis16201_channels[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_aux, .scan_index = ADIS16201_SCAN_AUX_ADC, .scan_type = { @@ -474,7 +479,8 @@ static struct iio_chan_spec adis16201_channels[] = { .type = IIO_INCLI, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, .address = incli_x, .scan_index = ADIS16201_SCAN_INCLI_X, @@ -487,7 +493,8 @@ static struct iio_chan_spec adis16201_channels[] = { .type = IIO_INCLI, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, .address = incli_y, .scan_index = ADIS16201_SCAN_INCLI_Y, diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c index b50f04d..f23b7c5 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_core.c @@ -305,7 +305,7 @@ static int adis16203_read_raw(struct iio_dev *indio_dev, u8 addr; s16 val16; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); addr = adis16203_addresses[chan->address][0]; ret = adis16203_spi_read_reg_16(indio_dev, addr, &val16); @@ -377,7 +377,8 @@ static struct iio_chan_spec adis16203_channels[] = { .indexed = 1, .channel = 0, .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_supply, .scan_index = ADIS16203_SCAN_SUPPLY, .scan_type = { @@ -389,7 +390,8 @@ static struct iio_chan_spec adis16203_channels[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_aux, .scan_index = ADIS16203_SCAN_AUX_ADC, .scan_type = { @@ -401,7 +403,8 @@ static struct iio_chan_spec adis16203_channels[] = { .type = IIO_INCLI, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, .address = incli_x, .scan_index = ADIS16203_SCAN_INCLI_X, @@ -414,7 +417,8 @@ static struct iio_chan_spec adis16203_channels[] = { .type = IIO_INCLI, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = incli_y, .scan_index = ADIS16203_SCAN_INCLI_Y, .scan_type = { @@ -426,7 +430,8 @@ static struct iio_chan_spec adis16203_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, .address = temp, .scan_index = ADIS16203_SCAN_TEMP, diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index fdf31f1..bffbbe8 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -342,7 +342,7 @@ static int adis16204_read_raw(struct iio_dev *indio_dev, int addrind; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); addr = adis16204_addresses[chan->address][0]; ret = adis16204_spi_read_reg_16(indio_dev, addr, &val16); @@ -449,7 +449,8 @@ static struct iio_chan_spec adis16204_channels[] = { .indexed = 1, /* Note was not previously indexed */ .channel = 0, .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_supply, .scan_index = ADIS16204_SCAN_SUPPLY, .scan_type = { @@ -461,7 +462,8 @@ static struct iio_chan_spec adis16204_channels[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_aux, .scan_index = ADIS16204_SCAN_AUX_ADC, .scan_type = { @@ -473,7 +475,8 @@ static struct iio_chan_spec adis16204_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, .address = temp, .scan_index = ADIS16204_SCAN_TEMP, @@ -486,7 +489,8 @@ static struct iio_chan_spec adis16204_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_PEAK_SEPARATE_BIT, .address = accel_x, @@ -500,7 +504,8 @@ static struct iio_chan_spec adis16204_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_PEAK_SEPARATE_BIT, .address = accel_y, diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index 02c003f..b1fbf19 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -331,7 +331,7 @@ static int adis16209_read_raw(struct iio_dev *indio_dev, s16 val16; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); addr = adis16209_addresses[chan->address][0]; ret = adis16209_spi_read_reg_16(indio_dev, addr, &val16); @@ -413,7 +413,8 @@ static struct iio_chan_spec adis16209_channels[] = { .indexed = 1, .channel = 0, .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_supply, .scan_index = ADIS16209_SCAN_SUPPLY, .scan_type = { @@ -425,7 +426,8 @@ static struct iio_chan_spec adis16209_channels[] = { .type = IIO_TEMP, .indexed = 0, .channel = 0, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, .address = temp, .scan_index = ADIS16209_SCAN_TEMP, @@ -438,7 +440,8 @@ static struct iio_chan_spec adis16209_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, .address = accel_x, .scan_index = ADIS16209_SCAN_ACC_X, @@ -451,7 +454,8 @@ static struct iio_chan_spec adis16209_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, .address = accel_y, .scan_index = ADIS16209_SCAN_ACC_Y, @@ -464,7 +468,8 @@ static struct iio_chan_spec adis16209_channels[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_aux, .scan_index = ADIS16209_SCAN_AUX_ADC, .scan_type = { @@ -476,7 +481,8 @@ static struct iio_chan_spec adis16209_channels[] = { .type = IIO_INCLI, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = incli_x, .scan_index = ADIS16209_SCAN_INCLI_X, .scan_type = { @@ -488,7 +494,8 @@ static struct iio_chan_spec adis16209_channels[] = { .type = IIO_INCLI, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = incli_y, .scan_index = ADIS16209_SCAN_INCLI_Y, .scan_type = { @@ -500,6 +507,7 @@ static struct iio_chan_spec adis16209_channels[] = { .type = IIO_ROT, .modified = 1, .channel2 = IIO_MOD_X, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = rot, .scan_index = ADIS16209_SCAN_ROT, .scan_type = { diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index 51a852d..2740c8e 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -507,7 +507,7 @@ static int adis16220_read_raw(struct iio_dev *indio_dev, u8 bits; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: addrind = 0; break; case IIO_CHAN_INFO_OFFSET: @@ -575,11 +575,13 @@ static const struct iio_chan_spec adis16220_channels[] = { .indexed = 1, .channel = 0, .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_supply, }, { .type = IIO_ACCEL, - .info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT | IIO_CHAN_INFO_PEAK_SEPARATE_BIT, .address = accel, @@ -587,20 +589,23 @@ static const struct iio_chan_spec adis16220_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = temp, }, { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_1, }, { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = in_2, } }; diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index fb0b328..18ed396 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -365,7 +365,7 @@ static int adis16240_read_raw(struct iio_dev *indio_dev, s16 val16; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); addr = adis16240_addresses[chan->address][0]; ret = adis16240_spi_read_reg_16(indio_dev, addr, &val16); @@ -473,7 +473,8 @@ static struct iio_chan_spec adis16240_channels[] = { .indexed = 1, .channel = 0, .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_supply, .scan_index = ADIS16240_SCAN_SUPPLY, .scan_type = { @@ -485,6 +486,7 @@ static struct iio_chan_spec adis16240_channels[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = in_aux, .scan_index = ADIS16240_SCAN_AUX_ADC, .scan_type = { @@ -496,7 +498,8 @@ static struct iio_chan_spec adis16240_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, .address = accel_x, .scan_index = ADIS16240_SCAN_ACC_X, @@ -509,7 +512,8 @@ static struct iio_chan_spec adis16240_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, .address = accel_y, .scan_index = ADIS16240_SCAN_ACC_Y, @@ -522,7 +526,8 @@ static struct iio_chan_spec adis16240_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, .address = accel_z, .scan_index = ADIS16240_SCAN_ACC_Z, @@ -535,7 +540,8 @@ static struct iio_chan_spec adis16240_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = temp, .scan_index = ADIS16240_SCAN_TEMP, .scan_type = { diff --git a/drivers/staging/iio/accel/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c index d13d721..601da28 100644 --- a/drivers/staging/iio/accel/kxsd9.c +++ b/drivers/staging/iio/accel/kxsd9.c @@ -158,7 +158,7 @@ static int kxsd9_read_raw(struct iio_dev *indio_dev, struct kxsd9_state *st = iio_priv(indio_dev); switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: ret = kxsd9_read(indio_dev, chan->address); if (ret < 0) goto error_ret; @@ -181,7 +181,8 @@ error_ret: .type = IIO_ACCEL, \ .modified = 1, \ .channel2 = IIO_MOD_##axis, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .address = KXSD9_REG_##axis, \ } @@ -189,6 +190,7 @@ static struct iio_chan_spec kxsd9_channels[] = { KXSD9_ACCEL_CHAN(X), KXSD9_ACCEL_CHAN(Y), KXSD9_ACCEL_CHAN(Z), { .type = IIO_VOLTAGE, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .indexed = 1, .address = KXSD9_REG_AUX, } diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index 0bb7c70..ee8ad3a 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -257,7 +257,7 @@ static int lis3l02dq_read_raw(struct iio_dev *indio_dev, u8 reg; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: /* Take the iio_dev status lock */ mutex_lock(&indio_dev->mlock); if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) { @@ -513,7 +513,8 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private) } #define LIS3L02DQ_INFO_MASK \ - (IIO_CHAN_INFO_SCALE_SHARED_BIT | \ + (IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT | \ IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT) diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index b4a2747..646e05c 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -429,7 +429,7 @@ static IIO_DEVICE_ATTR(measurement_mode, S_IRUGO | S_IWUSR, static IIO_DEVICE_ATTR(revision, S_IRUGO, sca3000_show_rev, NULL, 0); #define SCA3000_INFO_MASK \ - IIO_CHAN_INFO_SCALE_SHARED_BIT + IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT #define SCA3000_EVENT_MASK \ (IIO_EV_BIT(IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING)) @@ -476,7 +476,7 @@ static int sca3000_read_raw(struct iio_dev *indio_dev, u8 address; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&st->lock); if (st->mo_det_use_count) { mutex_unlock(&st->lock); -- cgit v0.10.2 From b11f98ff8c35d62523b2bfad07df3d756113aae3 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 15 Apr 2012 17:41:18 +0100 Subject: staging:iio:adc Add IIO_CHAN_INFO_RAW entries to all drivers. Precursor to making value read / write attribute optional. No processed values for adc's. Updated to include the spear adc driver (hence introducing a dependency on the patch that adds that driver). Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 9fd6d63..feb81f6 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -849,7 +849,7 @@ static int ad7192_read_raw(struct iio_dev *indio_dev, bool unipolar = !!(st->conf & AD7192_CONF_UNIPOLAR); switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); if (iio_buffer_enabled(indio_dev)) ret = -EBUSY; @@ -981,7 +981,8 @@ static const struct iio_info ad7195_info = { .extend_name = _name, \ .channel = _chan, \ .channel2 = _chan2, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .address = _address, \ .scan_index = _si, \ .scan_type = IIO_ST('s', 24, 32, 0)} @@ -990,7 +991,8 @@ static const struct iio_info ad7195_info = { { .type = IIO_VOLTAGE, \ .indexed = 1, \ .channel = _chan, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .address = _address, \ .scan_index = _si, \ .scan_type = IIO_ST('s', 24, 32, 0)} @@ -999,7 +1001,8 @@ static const struct iio_info ad7195_info = { { .type = IIO_TEMP, \ .indexed = 1, \ .channel = _chan, \ - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ .address = _address, \ .scan_index = _si, \ .scan_type = IIO_ST('s', 24, 32, 0)} diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c index 7dbd681..f0c0c72 100644 --- a/drivers/staging/iio/adc/ad7280a.c +++ b/drivers/staging/iio/adc/ad7280a.c @@ -508,6 +508,7 @@ static int ad7280_channel_init(struct ad7280_state *st) } st->channels[cnt].indexed = 1; st->channels[cnt].info_mask = + IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT; st->channels[cnt].address = AD7280A_DEVADDR(dev) << 8 | ch; @@ -524,7 +525,9 @@ static int ad7280_channel_init(struct ad7280_state *st) st->channels[cnt].channel2 = dev * 6; st->channels[cnt].address = AD7280A_ALL_CELLS; st->channels[cnt].indexed = 1; - st->channels[cnt].info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT; + st->channels[cnt].info_mask = + IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT; st->channels[cnt].scan_index = cnt; st->channels[cnt].scan_type.sign = 'u'; st->channels[cnt].scan_type.realbits = 32; @@ -788,7 +791,7 @@ static int ad7280_read_raw(struct iio_dev *indio_dev, int ret; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); if (chan->address == AD7280A_ALL_CELLS) ret = ad7280_read_all_channels(st, st->scan_cnt, NULL); diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c index 81d6b61..298249f 100644 --- a/drivers/staging/iio/adc/ad7291.c +++ b/drivers/staging/iio/adc/ad7291.c @@ -461,7 +461,7 @@ static int ad7291_read_raw(struct iio_dev *indio_dev, s16 signval; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: switch (chan->type) { case IIO_VOLTAGE: mutex_lock(&chip->state_lock); @@ -536,7 +536,8 @@ static int ad7291_read_raw(struct iio_dev *indio_dev, #define AD7291_VOLTAGE_CHAN(_chan) \ { \ .type = IIO_VOLTAGE, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .indexed = 1, \ .channel = _chan, \ .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)|\ @@ -554,7 +555,8 @@ static const struct iio_chan_spec ad7291_channels[] = { AD7291_VOLTAGE_CHAN(7), { .type = IIO_TEMP, - .info_mask = IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .indexed = 1, .channel = 0, diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c index 0cdde18..5d54a79 100644 --- a/drivers/staging/iio/adc/ad7298_core.c +++ b/drivers/staging/iio/adc/ad7298_core.c @@ -27,7 +27,8 @@ .type = IIO_VOLTAGE, \ .indexed = 1, \ .channel = index, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .address = index, \ .scan_index = index, \ .scan_type = { \ @@ -42,7 +43,8 @@ static struct iio_chan_spec ad7298_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = 9, .scan_index = AD7298_CH_TEMP, .scan_type = { @@ -130,7 +132,7 @@ static int ad7298_read_raw(struct iio_dev *indio_dev, unsigned int scale_uv; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) { ret = -EBUSY; diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c index 694b508..ce71522 100644 --- a/drivers/staging/iio/adc/ad7476_core.c +++ b/drivers/staging/iio/adc/ad7476_core.c @@ -43,7 +43,7 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, unsigned int scale_uv; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); if (iio_buffer_enabled(indio_dev)) ret = -EBUSY; @@ -70,7 +70,8 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .scan_type = { \ .sign = 'u', \ .realbits = bits, \ diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c index 97e8d3d..802cdaf 100644 --- a/drivers/staging/iio/adc/ad7606_core.c +++ b/drivers/staging/iio/adc/ad7606_core.c @@ -88,7 +88,7 @@ static int ad7606_read_raw(struct iio_dev *indio_dev, unsigned int scale_uv; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); if (iio_buffer_enabled(indio_dev)) ret = -EBUSY; @@ -229,14 +229,15 @@ static const struct attribute_group ad7606_attribute_group_range = { .attrs = ad7606_attributes_range, }; -#define AD7606_CHANNEL(num) \ - { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .channel = num, \ - .address = num, \ - .scan_index = num, \ - .scan_type = IIO_ST('s', 16, 16, 0), \ +#define AD7606_CHANNEL(num) \ + { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = num, \ + .address = num, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ + .scan_index = num, \ + .scan_type = IIO_ST('s', 16, 16, 0), \ } static struct iio_chan_spec ad7606_8_channels[] = { diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c index 4f0a6c9..eeedbdb 100644 --- a/drivers/staging/iio/adc/ad7780.c +++ b/drivers/staging/iio/adc/ad7780.c @@ -94,7 +94,7 @@ static int ad7780_read_raw(struct iio_dev *indio_dev, unsigned long scale_uv; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); ret = ad7780_read(st, &smpl); mutex_unlock(&indio_dev->mlock); @@ -130,7 +130,8 @@ static const struct ad7780_chip_info ad7780_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .scan_type = { .sign = 's', .realbits = 24, @@ -144,7 +145,8 @@ static const struct ad7780_chip_info ad7780_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .scan_type = { .sign = 's', .realbits = 20, diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index 84ecde1..9d21e39 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -630,7 +630,7 @@ static int ad7793_read_raw(struct iio_dev *indio_dev, bool unipolar = !!(st->conf & AD7793_CONF_UNIPOLAR); switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); if (iio_buffer_enabled(indio_dev)) ret = -EBUSY; @@ -760,7 +760,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .channel = 0, .channel2 = 0, .address = AD7793_CH_AIN1P_AIN1M, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .scan_index = 0, .scan_type = IIO_ST('s', 24, 32, 0) }, @@ -771,7 +772,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .channel = 1, .channel2 = 1, .address = AD7793_CH_AIN2P_AIN2M, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .scan_index = 1, .scan_type = IIO_ST('s', 24, 32, 0) }, @@ -782,7 +784,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .channel = 2, .channel2 = 2, .address = AD7793_CH_AIN3P_AIN3M, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .scan_index = 2, .scan_type = IIO_ST('s', 24, 32, 0) }, @@ -794,7 +797,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .channel = 2, .channel2 = 2, .address = AD7793_CH_AIN1M_AIN1M, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .scan_index = 2, .scan_type = IIO_ST('s', 24, 32, 0) }, @@ -803,7 +807,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .indexed = 1, .channel = 0, .address = AD7793_CH_TEMP, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .scan_index = 4, .scan_type = IIO_ST('s', 24, 32, 0), }, @@ -813,7 +818,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .indexed = 1, .channel = 4, .address = AD7793_CH_AVDD_MONITOR, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .scan_index = 5, .scan_type = IIO_ST('s', 24, 32, 0), }, @@ -827,7 +833,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .channel = 0, .channel2 = 0, .address = AD7793_CH_AIN1P_AIN1M, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .scan_index = 0, .scan_type = IIO_ST('s', 16, 32, 0) }, @@ -838,7 +845,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .channel = 1, .channel2 = 1, .address = AD7793_CH_AIN2P_AIN2M, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .scan_index = 1, .scan_type = IIO_ST('s', 16, 32, 0) }, @@ -849,7 +857,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .channel = 2, .channel2 = 2, .address = AD7793_CH_AIN3P_AIN3M, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .scan_index = 2, .scan_type = IIO_ST('s', 16, 32, 0) }, @@ -861,7 +870,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .channel = 2, .channel2 = 2, .address = AD7793_CH_AIN1M_AIN1M, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .scan_index = 2, .scan_type = IIO_ST('s', 16, 32, 0) }, @@ -870,7 +880,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .indexed = 1, .channel = 0, .address = AD7793_CH_TEMP, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .scan_index = 4, .scan_type = IIO_ST('s', 16, 32, 0), }, @@ -880,7 +891,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .indexed = 1, .channel = 4, .address = AD7793_CH_AVDD_MONITOR, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .scan_index = 5, .scan_type = IIO_ST('s', 16, 32, 0), }, diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c index e9bbc3e..2cce09f 100644 --- a/drivers/staging/iio/adc/ad7887_core.c +++ b/drivers/staging/iio/adc/ad7887_core.c @@ -42,7 +42,7 @@ static int ad7887_read_raw(struct iio_dev *indio_dev, unsigned int scale_uv; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); if (iio_buffer_enabled(indio_dev)) ret = -EBUSY; @@ -75,7 +75,8 @@ static const struct ad7887_chip_info ad7887_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = 1, .scan_index = 1, .scan_type = IIO_ST('u', 12, 16, 0), @@ -84,7 +85,8 @@ static const struct ad7887_chip_info ad7887_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = 0, .scan_index = 0, .scan_type = IIO_ST('u', 12, 16, 0), diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c index a845866..429fb41 100644 --- a/drivers/staging/iio/adc/ad799x_core.c +++ b/drivers/staging/iio/adc/ad799x_core.c @@ -148,7 +148,7 @@ static int ad799x_read_raw(struct iio_dev *indio_dev, unsigned int scale_uv; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); if (iio_buffer_enabled(indio_dev)) ret = -EBUSY; @@ -454,6 +454,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 0, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -461,6 +462,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 1, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -468,6 +470,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 2, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -475,6 +478,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 3, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 3, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -490,6 +494,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 0, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -497,6 +502,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 1, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -504,6 +510,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 2, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -511,6 +518,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 3, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 3, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -526,6 +534,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 0, .scan_type = IIO_ST('u', 8, 16, 4), }, @@ -533,6 +542,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 1, .scan_type = IIO_ST('u', 8, 16, 4), }, @@ -540,6 +550,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 2, .scan_type = IIO_ST('u', 8, 16, 4), }, @@ -547,6 +558,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 3, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 3, .scan_type = IIO_ST('u', 8, 16, 4), }, @@ -562,6 +574,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 0, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -570,6 +583,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 1, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -587,6 +601,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 0, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, @@ -596,6 +611,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .indexed = 1, .channel = 1, .scan_index = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, }, @@ -603,6 +619,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 2, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, @@ -611,6 +628,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 3, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 3, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, @@ -628,6 +646,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 0, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -636,6 +655,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 1, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -644,6 +664,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 2, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -652,6 +673,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 3, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 3, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -669,6 +691,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 0, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, @@ -677,6 +700,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 1, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, @@ -685,6 +709,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 2, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, @@ -693,6 +718,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 3, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 3, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, @@ -701,6 +727,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 4, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 4, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -708,6 +735,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 5, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 5, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -715,6 +743,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 6, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 6, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -722,6 +751,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 7, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 7, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -738,6 +768,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 0, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -746,6 +777,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 1, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -754,6 +786,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 2, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -762,6 +795,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 3, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 3, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -770,6 +804,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 4, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 4, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -777,6 +812,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 5, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 5, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -784,6 +820,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 6, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 6, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -791,6 +828,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 7, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 7, .scan_type = IIO_ST('u', 12, 16, 0), }, diff --git a/drivers/staging/iio/adc/lpc32xx_adc.c b/drivers/staging/iio/adc/lpc32xx_adc.c index dfc9033..ce9320b 100644 --- a/drivers/staging/iio/adc/lpc32xx_adc.c +++ b/drivers/staging/iio/adc/lpc32xx_adc.c @@ -73,7 +73,7 @@ static int lpc32xx_read_raw(struct iio_dev *indio_dev, { struct lpc32xx_adc_info *info = iio_priv(indio_dev); - if (mask == 0) { + if (mask == IIO_CHAN_INFO_RAW) { mutex_lock(&indio_dev->mlock); clk_enable(info->clk); /* Measurement setup */ @@ -98,12 +98,13 @@ static const struct iio_info lpc32xx_adc_iio_info = { .driver_module = THIS_MODULE, }; -#define LPC32XX_ADC_CHANNEL(_index) { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .channel = _index, \ - .address = AD_IN * _index, \ - .scan_index = _index, \ +#define LPC32XX_ADC_CHANNEL(_index) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = _index, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ + .address = AD_IN * _index, \ + .scan_index = _index, \ } static struct iio_chan_spec lpc32xx_adc_iio_channels[] = { diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index 9d7db7f..1a7a027 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -249,7 +249,7 @@ static int max1363_read_raw(struct iio_dev *indio_dev, struct max1363_state *st = iio_priv(indio_dev); int ret; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: ret = max1363_read_single_chan(indio_dev, chan, val, m); if (ret < 0) return ret; @@ -282,7 +282,8 @@ static const enum max1363_modes max1363_mode_list[] = { #define MAX1363_EV_M \ (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) \ | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)) -#define MAX1363_INFO_MASK IIO_CHAN_INFO_SCALE_SHARED_BIT +#define MAX1363_INFO_MASK (IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT) #define MAX1363_CHAN_U(num, addr, si, bits, evmask) \ { \ .type = IIO_VOLTAGE, \ diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c index bea5778..3ca5cc9 100644 --- a/drivers/staging/iio/adc/spear_adc.c +++ b/drivers/staging/iio/adc/spear_adc.c @@ -150,7 +150,7 @@ static int spear_read_raw(struct iio_dev *indio_dev, u32 status; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); status = CHANNEL_NUM(chan->channel) | @@ -180,7 +180,8 @@ static int spear_read_raw(struct iio_dev *indio_dev, #define SPEAR_ADC_CHAN(idx) { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .channel = idx, \ .scan_type = { \ .sign = 'u', \ -- cgit v0.10.2 From 09f4eb404689bef8766f195d4476ebe98f851ce6 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 15 Apr 2012 17:41:19 +0100 Subject: staging:iio:dac Add IIO_CHAN_INFO_RAW entries to all drivers. Precursor to making value read / write attribute optional. No processed versions in DACs. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/dac/ad5064.c b/drivers/staging/iio/dac/ad5064.c index 06b1627..21893ed 100644 --- a/drivers/staging/iio/dac/ad5064.c +++ b/drivers/staging/iio/dac/ad5064.c @@ -235,7 +235,7 @@ static int ad5064_read_raw(struct iio_dev *indio_dev, int scale_uv; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: *val = st->dac_cache[chan->channel]; return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: @@ -260,7 +260,7 @@ static int ad5064_write_raw(struct iio_dev *indio_dev, int ret; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: if (val > (1 << chan->scan_type.realbits) || val < 0) return -EINVAL; @@ -308,7 +308,8 @@ static struct iio_chan_spec_ext_info ad5064_ext_info[] = { .indexed = 1, \ .output = 1, \ .channel = (chan), \ - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ .address = AD5064_ADDR_DAC(chan), \ .scan_type = IIO_ST('u', (bits), 16, 20 - (bits)), \ .ext_info = ad5064_ext_info, \ diff --git a/drivers/staging/iio/dac/ad5360.c b/drivers/staging/iio/dac/ad5360.c index cec3693..cb6160d 100644 --- a/drivers/staging/iio/dac/ad5360.c +++ b/drivers/staging/iio/dac/ad5360.c @@ -103,7 +103,8 @@ enum ad5360_type { .type = IIO_VOLTAGE, \ .indexed = 1, \ .output = 1, \ - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \ IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \ IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \ @@ -319,7 +320,7 @@ static int ad5360_write_raw(struct iio_dev *indio_dev, unsigned int ofs_index; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: if (val >= max_val || val < 0) return -EINVAL; @@ -376,7 +377,7 @@ static int ad5360_read_raw(struct iio_dev *indio_dev, int ret; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: ret = ad5360_read(indio_dev, AD5360_READBACK_X1A, chan->address); if (ret < 0) diff --git a/drivers/staging/iio/dac/ad5380.c b/drivers/staging/iio/dac/ad5380.c index 4c50716..1d384f0 100644 --- a/drivers/staging/iio/dac/ad5380.c +++ b/drivers/staging/iio/dac/ad5380.c @@ -85,7 +85,8 @@ enum ad5380_type { .type = IIO_VOLTAGE, \ .indexed = 1, \ .output = 1, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT | \ IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \ .scan_type = IIO_ST('u', (_bits), 16, 14 - (_bits)) \ @@ -292,7 +293,7 @@ static int ad5380_write_raw(struct iio_dev *indio_dev, struct ad5380_state *st = iio_priv(indio_dev); switch (info) { - case 0: + case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_CALIBSCALE: if (val >= max_val || val < 0) return -EINVAL; @@ -322,7 +323,7 @@ static int ad5380_read_raw(struct iio_dev *indio_dev, int ret; switch (info) { - case 0: + case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_CALIBSCALE: ret = regmap_read(st->regmap, ad5380_info_to_reg(chan, info), val); diff --git a/drivers/staging/iio/dac/ad5421.c b/drivers/staging/iio/dac/ad5421.c index 0b040b2..a8b5211 100644 --- a/drivers/staging/iio/dac/ad5421.c +++ b/drivers/staging/iio/dac/ad5421.c @@ -87,7 +87,8 @@ static const struct iio_chan_spec ad5421_channels[] = { .indexed = 1, .output = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_OFFSET_SHARED_BIT | IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, @@ -304,7 +305,7 @@ static int ad5421_read_raw(struct iio_dev *indio_dev, return -EINVAL; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: ret = ad5421_read(indio_dev, AD5421_REG_DAC_DATA); if (ret < 0) return ret; @@ -340,7 +341,7 @@ static int ad5421_write_raw(struct iio_dev *indio_dev, const unsigned int max_val = 1 << 16; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: if (val >= max_val || val < 0) return -EINVAL; diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index 633ffbb..ec6968b 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -158,7 +158,8 @@ static const struct attribute_group ad5446_attribute_group = { .indexed = 1, \ .output = 1, \ .channel = 0, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .scan_type = IIO_ST('u', (bits), (storage), (shift)) \ } @@ -274,7 +275,7 @@ static int ad5446_write_raw(struct iio_dev *indio_dev, int ret; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: if (val >= (1 << chan->scan_type.realbits) || val < 0) return -EINVAL; diff --git a/drivers/staging/iio/dac/ad5504.c b/drivers/staging/iio/dac/ad5504.c index bc17205..796691e 100644 --- a/drivers/staging/iio/dac/ad5504.c +++ b/drivers/staging/iio/dac/ad5504.c @@ -27,7 +27,8 @@ .indexed = 1, \ .output = 1, \ .channel = (_chan), \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .address = AD5504_ADDR_DAC(_chan), \ .scan_type = IIO_ST('u', 12, 16, 0), \ } @@ -81,7 +82,7 @@ static int ad5504_read_raw(struct iio_dev *indio_dev, int ret; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: ret = ad5504_spi_read(st->spi, chan->address); if (ret < 0) return ret; @@ -109,7 +110,7 @@ static int ad5504_write_raw(struct iio_dev *indio_dev, int ret; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: if (val >= (1 << chan->scan_type.realbits) || val < 0) return -EINVAL; diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c index 10c7484..74eb889 100644 --- a/drivers/staging/iio/dac/ad5624r_spi.c +++ b/drivers/staging/iio/dac/ad5624r_spi.c @@ -26,7 +26,8 @@ .indexed = 1, \ .output = 1, \ .channel = (_chan), \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .address = (_chan), \ .scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits)), \ } @@ -122,7 +123,7 @@ static int ad5624r_write_raw(struct iio_dev *indio_dev, int ret; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: if (val >= (1 << chan->scan_type.realbits) || val < 0) return -EINVAL; diff --git a/drivers/staging/iio/dac/ad5686.c b/drivers/staging/iio/dac/ad5686.c index 2415a6e..b8acd7e 100644 --- a/drivers/staging/iio/dac/ad5686.c +++ b/drivers/staging/iio/dac/ad5686.c @@ -98,7 +98,8 @@ enum ad5686_supported_device_ids { .indexed = 1, \ .output = 1, \ .channel = chan, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .address = AD5686_ADDR_DAC(chan), \ .scan_type = IIO_ST('u', bits, 16, shift) \ } @@ -296,7 +297,7 @@ static int ad5686_read_raw(struct iio_dev *indio_dev, int ret; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); ret = ad5686_spi_read(st, chan->address); mutex_unlock(&indio_dev->mlock); @@ -326,7 +327,7 @@ static int ad5686_write_raw(struct iio_dev *indio_dev, int ret; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: if (val > (1 << chan->scan_type.realbits) || val < 0) return -EINVAL; diff --git a/drivers/staging/iio/dac/ad5764.c b/drivers/staging/iio/dac/ad5764.c index f73a730..1c9ff4fc 100644 --- a/drivers/staging/iio/dac/ad5764.c +++ b/drivers/staging/iio/dac/ad5764.c @@ -79,7 +79,8 @@ enum ad5764_type { .output = 1, \ .channel = (_chan), \ .address = (_chan), \ - .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_OFFSET_SHARED_BIT | \ IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \ IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \ @@ -188,7 +189,7 @@ static int ad5764_write_raw(struct iio_dev *indio_dev, unsigned int reg; switch (info) { - case 0: + case IIO_CHAN_INFO_RAW: if (val >= max_val || val < 0) return -EINVAL; val <<= chan->scan_type.shift; @@ -228,7 +229,7 @@ static int ad5764_read_raw(struct iio_dev *indio_dev, int ret; switch (info) { - case 0: + case IIO_CHAN_INFO_RAW: reg = AD5764_REG_DATA(chan->address); ret = ad5764_read(indio_dev, reg, val); if (ret < 0) diff --git a/drivers/staging/iio/dac/ad5791.c b/drivers/staging/iio/dac/ad5791.c index ac45636..cdb7b10 100644 --- a/drivers/staging/iio/dac/ad5791.c +++ b/drivers/staging/iio/dac/ad5791.c @@ -78,7 +78,8 @@ static int ad5791_spi_read(struct spi_device *spi, u8 addr, u32 *val) .indexed = 1, \ .address = AD5791_ADDR_DAC0, \ .channel = 0, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT | \ IIO_CHAN_INFO_OFFSET_SHARED_BIT, \ .scan_type = IIO_ST('u', bits, 24, shift) \ } @@ -231,7 +232,7 @@ static int ad5791_read_raw(struct iio_dev *indio_dev, int ret; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: ret = ad5791_spi_read(st->spi, chan->address, val); if (ret) return ret; @@ -263,7 +264,7 @@ static int ad5791_write_raw(struct iio_dev *indio_dev, struct ad5791_state *st = iio_priv(indio_dev); switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: val &= AD5791_RES_MASK(chan->scan_type.realbits); val <<= chan->scan_type.shift; -- cgit v0.10.2 From fbaff213a3b5fd44fc13df573c2b5728ed5f73bd Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 15 Apr 2012 17:41:20 +0100 Subject: staging:iio:gyro Add IIO_CHAN_INFO_RAW entries to all drivers. Precursor to making value read / write attribute optional. No processed values in gyroscopes. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c index 02cc234..2f841cb 100644 --- a/drivers/staging/iio/gyro/adis16060_core.c +++ b/drivers/staging/iio/gyro/adis16060_core.c @@ -85,7 +85,7 @@ static int adis16060_read_raw(struct iio_dev *indio_dev, int ret; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: /* Take the iio_dev status lock */ mutex_lock(&indio_dev->mlock); ret = adis16060_spi_write(indio_dev, chan->address); @@ -120,22 +120,26 @@ static const struct iio_chan_spec adis16060_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = ADIS16060_GYRO, }, { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = ADIS16060_AIN1, }, { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = ADIS16060_AIN2, }, { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = ADIS16060_TEMP_OUT, } diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c index 1815490..608b93d 100644 --- a/drivers/staging/iio/gyro/adis16080_core.c +++ b/drivers/staging/iio/gyro/adis16080_core.c @@ -87,7 +87,7 @@ static int adis16080_read_raw(struct iio_dev *indio_dev, mutex_lock(&indio_dev->mlock); switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: ret = adis16080_spi_write(indio_dev, chan->address | ADIS16080_DIN_WRITE); @@ -110,21 +110,25 @@ static const struct iio_chan_spec adis16080_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = ADIS16080_DIN_GYRO, }, { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = ADIS16080_DIN_AIN1, }, { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = ADIS16080_DIN_AIN2, }, { .type = IIO_TEMP, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = ADIS16080_DIN_TEMP, } }; diff --git a/drivers/staging/iio/gyro/adis16130_core.c b/drivers/staging/iio/gyro/adis16130_core.c index 947eb86..257bdf2 100644 --- a/drivers/staging/iio/gyro/adis16130_core.c +++ b/drivers/staging/iio/gyro/adis16130_core.c @@ -100,11 +100,13 @@ static const struct iio_chan_spec adis16130_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = ADIS16130_RATEDATA, }, { .type = IIO_TEMP, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = ADIS16130_TEMPDATA, } }; diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index 92f024e..bb23018 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -393,7 +393,8 @@ enum adis16260_channel { .type = IIO_ANGL_VEL, \ .modified = 1, \ .channel2 = mod, \ - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \ IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ .address = gyro, \ @@ -407,6 +408,7 @@ enum adis16260_channel { .type = IIO_ANGL, \ .modified = 1, \ .channel2 = mod, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ .address = angle, \ .scan_index = ADIS16260_SCAN_ANGL, \ .scan_type = { \ @@ -418,7 +420,8 @@ enum adis16260_channel { .type = IIO_TEMP, \ .indexed = 1, \ .channel = 0, \ - .info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \ IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ .address = temp, \ .scan_index = ADIS16260_SCAN_TEMP, \ @@ -432,7 +435,8 @@ enum adis16260_channel { .indexed = 1, \ .channel = 0, \ .extend_name = "supply", \ - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ .address = in_supply, \ .scan_index = ADIS16260_SCAN_SUPPLY, \ .scan_type = { \ @@ -444,7 +448,8 @@ enum adis16260_channel { .type = IIO_VOLTAGE, \ .indexed = 1, \ .channel = 1, \ - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ .address = in_aux, \ .scan_index = ADIS16260_SCAN_AUX_ADC, \ .scan_type = { \ @@ -481,7 +486,7 @@ static int adis16260_read_raw(struct iio_dev *indio_dev, s16 val16; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); addr = adis16260_addresses[chan->address][0]; ret = adis16260_spi_read_reg_16(indio_dev, addr, &val16); diff --git a/drivers/staging/iio/gyro/adxrs450_core.c b/drivers/staging/iio/gyro/adxrs450_core.c index 15e2496..1293505 100644 --- a/drivers/staging/iio/gyro/adxrs450_core.c +++ b/drivers/staging/iio/gyro/adxrs450_core.c @@ -265,7 +265,7 @@ static int adxrs450_read_raw(struct iio_dev *indio_dev, s16 t; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: switch (chan->type) { case IIO_ANGL_VEL: ret = adxrs450_spi_sensor_data(indio_dev, &t); @@ -329,14 +329,16 @@ static const struct iio_chan_spec adxrs450_channels[2][2] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, }, { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, } }, [ID_ADXRS453] = { @@ -344,13 +346,15 @@ static const struct iio_chan_spec adxrs450_channels[2][2] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE_BIT, }, { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, } }, }; -- cgit v0.10.2 From a5d016d46630968fcf9c329f5cf522a7c03b3888 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 15 Apr 2012 17:41:21 +0100 Subject: staging:iio:imu Add IIO_CHAN_INFO_RAW entries to all drivers. Precursor to making value read / write attribute optional. No processed values in IMU. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index a027d6d..58a150c 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -545,7 +545,7 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, s16 val16; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); ret = adis16400_spi_read_reg_16(indio_dev, adis16400_addresses[chan->address][0], @@ -635,7 +635,8 @@ static struct iio_chan_spec adis16400_channels[] = { .indexed = 1, .channel = 0, .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_supply, .scan_index = ADIS16400_SCAN_SUPPLY, .scan_type = IIO_ST('u', 14, 16, 0) @@ -643,7 +644,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_x, @@ -653,7 +655,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_y, @@ -663,7 +666,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_z, @@ -673,7 +677,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_x, @@ -683,7 +688,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_y, @@ -693,7 +699,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_z, @@ -703,7 +710,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_MAGN, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = magn_x, .scan_index = ADIS16400_SCAN_MAGN_X, @@ -712,7 +720,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_MAGN, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = magn_y, .scan_index = ADIS16400_SCAN_MAGN_Y, @@ -721,7 +730,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_MAGN, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = magn_z, .scan_index = ADIS16400_SCAN_MAGN_Z, @@ -730,7 +740,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = temp, .scan_index = ADIS16400_SCAN_TEMP, @@ -739,7 +750,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in1, .scan_index = ADIS16400_SCAN_ADC_0, .scan_type = IIO_ST('s', 12, 16, 0), @@ -753,7 +765,8 @@ static struct iio_chan_spec adis16350_channels[] = { .indexed = 1, .channel = 0, .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_supply, .scan_index = ADIS16400_SCAN_SUPPLY, .scan_type = IIO_ST('u', 12, 16, 0) @@ -761,7 +774,8 @@ static struct iio_chan_spec adis16350_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_x, @@ -771,7 +785,8 @@ static struct iio_chan_spec adis16350_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_y, @@ -781,17 +796,19 @@ static struct iio_chan_spec adis16350_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_z, .scan_index = ADIS16400_SCAN_GYRO_Z, .scan_type = IIO_ST('s', 14, 16, 0), }, { - .type = IIO_ACCEL, + .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_x, @@ -801,7 +818,8 @@ static struct iio_chan_spec adis16350_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_y, @@ -811,7 +829,8 @@ static struct iio_chan_spec adis16350_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_z, @@ -822,7 +841,8 @@ static struct iio_chan_spec adis16350_channels[] = { .indexed = 1, .channel = 0, .extend_name = "x", - .info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = temp0, @@ -833,7 +853,8 @@ static struct iio_chan_spec adis16350_channels[] = { .indexed = 1, .channel = 1, .extend_name = "y", - .info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = temp1, @@ -844,7 +865,8 @@ static struct iio_chan_spec adis16350_channels[] = { .indexed = 1, .channel = 2, .extend_name = "z", - .info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = temp2, .scan_index = ADIS16350_SCAN_TEMP_Z, @@ -853,7 +875,8 @@ static struct iio_chan_spec adis16350_channels[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in1, .scan_index = ADIS16350_SCAN_ADC_0, .scan_type = IIO_ST('s', 12, 16, 0), @@ -867,7 +890,8 @@ static struct iio_chan_spec adis16300_channels[] = { .indexed = 1, .channel = 0, .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_supply, .scan_index = ADIS16400_SCAN_SUPPLY, .scan_type = IIO_ST('u', 12, 16, 0) @@ -875,7 +899,8 @@ static struct iio_chan_spec adis16300_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_x, @@ -885,7 +910,8 @@ static struct iio_chan_spec adis16300_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_x, @@ -895,7 +921,8 @@ static struct iio_chan_spec adis16300_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_y, @@ -905,7 +932,8 @@ static struct iio_chan_spec adis16300_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_z, @@ -915,7 +943,8 @@ static struct iio_chan_spec adis16300_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = temp, .scan_index = ADIS16400_SCAN_TEMP, @@ -924,7 +953,8 @@ static struct iio_chan_spec adis16300_channels[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in1, .scan_index = ADIS16350_SCAN_ADC_0, .scan_type = IIO_ST('s', 12, 16, 0), @@ -932,7 +962,8 @@ static struct iio_chan_spec adis16300_channels[] = { .type = IIO_INCLI, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = incli_x, .scan_index = ADIS16300_SCAN_INCLI_X, .scan_type = IIO_ST('s', 13, 16, 0), @@ -940,7 +971,8 @@ static struct iio_chan_spec adis16300_channels[] = { .type = IIO_INCLI, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = incli_y, .scan_index = ADIS16300_SCAN_INCLI_Y, .scan_type = IIO_ST('s', 13, 16, 0), @@ -953,7 +985,8 @@ static const struct iio_chan_spec adis16334_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_x, @@ -963,7 +996,8 @@ static const struct iio_chan_spec adis16334_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_y, @@ -973,7 +1007,8 @@ static const struct iio_chan_spec adis16334_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_z, @@ -983,7 +1018,8 @@ static const struct iio_chan_spec adis16334_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_x, @@ -993,7 +1029,8 @@ static const struct iio_chan_spec adis16334_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_y, @@ -1003,7 +1040,8 @@ static const struct iio_chan_spec adis16334_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_z, @@ -1013,7 +1051,8 @@ static const struct iio_chan_spec adis16334_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = accel_z, .scan_index = ADIS16400_SCAN_ACC_Z, -- cgit v0.10.2 From 90354d0038e9e3d82d5fee5442d48f7cafb96a0c Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 15 Apr 2012 17:41:22 +0100 Subject: staging:iio:light Add IIO_CHAN_INFO_RAW/PROCESSED entries to all drivers. Precursor to making value read / write attribute optional. Note that minimal change route taken here. The read_raw callbacks in both drivers could do fewer checks to identify the channel than they now do. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index 38ec52b6..350f12c 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -383,7 +383,8 @@ static int isl29018_read_raw(struct iio_dev *indio_dev, mutex_lock(&chip->lock); switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: + case IIO_CHAN_INFO_PROCESSED: switch (chan->type) { case IIO_LIGHT: ret = isl29018_read_lux(client, val); @@ -420,14 +421,17 @@ static const struct iio_chan_spec isl29018_channels[] = { .indexed = 1, .channel = 0, .processed_val = IIO_PROCESSED, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, }, { .type = IIO_INTENSITY, .modified = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .channel2 = IIO_MOD_LIGHT_IR, }, { /* Unindexed in current ABI. But perhaps it should be. */ .type = IIO_PROXIMITY, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, } }; diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c index beb51d71..a334a88 100644 --- a/drivers/staging/iio/light/tsl2563.c +++ b/drivers/staging/iio/light/tsl2563.c @@ -485,7 +485,8 @@ static int tsl2563_read_raw(struct iio_dev *indio_dev, mutex_lock(&chip->lock); switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: + case IIO_CHAN_INFO_PROCESSED: switch (chan->type) { case IIO_LIGHT: ret = tsl2563_get_adc(chip); @@ -535,12 +536,14 @@ static const struct iio_chan_spec tsl2563_channels[] = { .type = IIO_LIGHT, .indexed = 1, .processed_val = 1, + .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, .channel = 0, }, { .type = IIO_INTENSITY, .modified = 1, .channel2 = IIO_MOD_LIGHT_BOTH, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, .event_mask = (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | IIO_EV_BIT(IIO_EV_TYPE_THRESH, @@ -549,7 +552,8 @@ static const struct iio_chan_spec tsl2563_channels[] = { .type = IIO_INTENSITY, .modified = 1, .channel2 = IIO_MOD_LIGHT_IR, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, } }; -- cgit v0.10.2 From 4d9948b36386ead790fecc0aad932a009dc51c90 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 15 Apr 2012 17:41:23 +0100 Subject: staging:iio:magnetometer Add IIO_CHAN_INFO_RAW entries to all drivers. Precursor to making value read / write attribute optional. No processed values for magnetometers. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c index d5ddac3..000886f 100644 --- a/drivers/staging/iio/magnetometer/ak8975.c +++ b/drivers/staging/iio/magnetometer/ak8975.c @@ -429,7 +429,7 @@ static int ak8975_read_raw(struct iio_dev *indio_dev, struct ak8975_data *data = iio_priv(indio_dev); switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: return ak8975_read_axis(indio_dev, chan->address, val); case IIO_CHAN_INFO_SCALE: *val = data->raw_to_gauss[chan->address]; @@ -443,7 +443,8 @@ static int ak8975_read_raw(struct iio_dev *indio_dev, .type = IIO_MAGN, \ .modified = 1, \ .channel2 = IIO_MOD_##axis, \ - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ .address = index, \ } diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c index 91dd3da..27c2629 100644 --- a/drivers/staging/iio/magnetometer/hmc5843.c +++ b/drivers/staging/iio/magnetometer/hmc5843.c @@ -459,7 +459,7 @@ static int hmc5843_read_raw(struct iio_dev *indio_dev, struct hmc5843_data *data = iio_priv(indio_dev); switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: return hmc5843_read_measurement(indio_dev, chan->address, val); @@ -476,7 +476,8 @@ static int hmc5843_read_raw(struct iio_dev *indio_dev, .type = IIO_MAGN, \ .modified = 1, \ .channel2 = IIO_MOD_##axis, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .address = add \ } -- cgit v0.10.2 From 6246577071ac4b29579203e7c22a7f383cf4f9e8 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 15 Apr 2012 17:41:24 +0100 Subject: staging:iio:resolver Add IIO_CHAN_INFO_RAW entries to all drivers. Precursor to making value read / write attribute optional. No processed values in resolvers at the moment. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index d8ce854..0465e5d 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -85,10 +85,12 @@ static const struct iio_chan_spec ad2s1200_channels[] = { .type = IIO_ANGL, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, }, { .type = IIO_ANGL_VEL, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, } }; diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c index c439fcf..c6ced16 100644 --- a/drivers/staging/iio/resolver/ad2s1210.c +++ b/drivers/staging/iio/resolver/ad2s1210.c @@ -580,10 +580,12 @@ static struct iio_chan_spec ad2s1210_channels[] = { .type = IIO_ANGL, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, }, { .type = IIO_ANGL_VEL, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, } }; diff --git a/drivers/staging/iio/resolver/ad2s90.c b/drivers/staging/iio/resolver/ad2s90.c index 2a86f58..20ca529 100644 --- a/drivers/staging/iio/resolver/ad2s90.c +++ b/drivers/staging/iio/resolver/ad2s90.c @@ -55,6 +55,7 @@ static const struct iio_chan_spec ad2s90_chan = { .type = IIO_ANGL, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, }; static int __devinit ad2s90_probe(struct spi_device *spi) -- cgit v0.10.2 From 967d3fe0dc84ac26380e8c9d916d90e1977a75d8 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 15 Apr 2012 17:41:25 +0100 Subject: staging:iio:impedance Add IIO_CHAN_INFO_RAW/PROCESSED entries to all drivers. Precursor to making value read / write attribute optional. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 06b9fe2..9d5738a 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -114,6 +114,7 @@ static struct iio_chan_spec ad5933_channels[] = { .indexed = 1, .processed_val = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, .address = AD5933_REG_TEMP_DATA, .scan_type = { .sign = 's', @@ -125,7 +126,8 @@ static struct iio_chan_spec ad5933_channels[] = { .indexed = 1, .channel = 0, .extend_name = "real_raw", - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = AD5933_REG_REAL_DATA, .scan_index = 0, .scan_type = { @@ -138,7 +140,8 @@ static struct iio_chan_spec ad5933_channels[] = { .indexed = 1, .channel = 0, .extend_name = "imag_raw", - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = AD5933_REG_IMAG_DATA, .scan_index = 1, .scan_type = { @@ -524,7 +527,8 @@ static int ad5933_read_raw(struct iio_dev *indio_dev, mutex_lock(&indio_dev->mlock); switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: + case IIO_CHAN_INFO_PROCESSED: if (iio_buffer_enabled(indio_dev)) { ret = -EBUSY; goto out; -- cgit v0.10.2 From e33e0750826b73ca505244c79152bba1e37c85d0 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 15 Apr 2012 17:41:26 +0100 Subject: staging:iio:cdc Add IIO_CHAN_INFO_RAW/PROCESSED entries to all drivers. Precursor to making value read / write attribute optional. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/cdc/ad7150.c b/drivers/staging/iio/cdc/ad7150.c index e4a08dc..116e6c2 100644 --- a/drivers/staging/iio/cdc/ad7150.c +++ b/drivers/staging/iio/cdc/ad7150.c @@ -104,7 +104,7 @@ static int ad7150_read_raw(struct iio_dev *indio_dev, struct ad7150_chip_info *chip = iio_priv(indio_dev); switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: ret = i2c_smbus_read_word_data(chip->client, ad7150_addresses[chan->channel][0]); if (ret < 0) @@ -429,7 +429,8 @@ static const struct iio_chan_spec ad7150_channels[] = { .type = IIO_CAPACITANCE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT, .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) | @@ -441,7 +442,8 @@ static const struct iio_chan_spec ad7150_channels[] = { .type = IIO_CAPACITANCE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT, .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) | diff --git a/drivers/staging/iio/cdc/ad7152.c b/drivers/staging/iio/cdc/ad7152.c index fdb83c3..1067ce5 100644 --- a/drivers/staging/iio/cdc/ad7152.c +++ b/drivers/staging/iio/cdc/ad7152.c @@ -329,7 +329,7 @@ static int ad7152_read_raw(struct iio_dev *indio_dev, mutex_lock(&indio_dev->mlock); switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: /* First set whether in differential mode */ regval = chip->setup[chan->channel]; @@ -436,7 +436,8 @@ static const struct iio_chan_spec ad7152_channels[] = { .type = IIO_CAPACITANCE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, }, { @@ -445,14 +446,16 @@ static const struct iio_chan_spec ad7152_channels[] = { .indexed = 1, .channel = 0, .channel2 = 2, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, }, { .type = IIO_CAPACITANCE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, }, { @@ -461,7 +464,8 @@ static const struct iio_chan_spec ad7152_channels[] = { .indexed = 1, .channel = 1, .channel2 = 3, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, } diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c index 40b8512..6c75605 100644 --- a/drivers/staging/iio/cdc/ad7746.c +++ b/drivers/staging/iio/cdc/ad7746.c @@ -123,7 +123,8 @@ static const struct iio_chan_spec ad7746_channels[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = AD7746_REG_VT_DATA_HIGH << 8 | AD7746_VTSETUP_VTMD_EXT_VIN, }, @@ -132,7 +133,8 @@ static const struct iio_chan_spec ad7746_channels[] = { .indexed = 1, .channel = 1, .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = AD7746_REG_VT_DATA_HIGH << 8 | AD7746_VTSETUP_VTMD_VDD_MON, }, @@ -141,6 +143,7 @@ static const struct iio_chan_spec ad7746_channels[] = { .indexed = 1, .channel = 0, .processed_val = IIO_PROCESSED, + .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, .address = AD7746_REG_VT_DATA_HIGH << 8 | AD7746_VTSETUP_VTMD_INT_TEMP, }, @@ -149,6 +152,7 @@ static const struct iio_chan_spec ad7746_channels[] = { .indexed = 1, .channel = 1, .processed_val = IIO_PROCESSED, + .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, .address = AD7746_REG_VT_DATA_HIGH << 8 | AD7746_VTSETUP_VTMD_EXT_TEMP, }, @@ -156,7 +160,8 @@ static const struct iio_chan_spec ad7746_channels[] = { .type = IIO_CAPACITANCE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT | IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT, @@ -168,7 +173,8 @@ static const struct iio_chan_spec ad7746_channels[] = { .indexed = 1, .channel = 0, .channel2 = 2, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT | IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT, @@ -179,7 +185,8 @@ static const struct iio_chan_spec ad7746_channels[] = { .type = IIO_CAPACITANCE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT | IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT, @@ -192,7 +199,8 @@ static const struct iio_chan_spec ad7746_channels[] = { .indexed = 1, .channel = 1, .channel2 = 3, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT | IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT, @@ -572,7 +580,8 @@ static int ad7746_read_raw(struct iio_dev *indio_dev, mutex_lock(&indio_dev->mlock); switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: + case IIO_CHAN_INFO_PROCESSED: ret = ad7746_select_channel(indio_dev, chan); if (ret < 0) goto out; -- cgit v0.10.2 From 41fd935b1812b9d811911a85d5893493f5ec774a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 15 Apr 2012 17:41:27 +0100 Subject: staging:iio: Add IIO_CHAN_INFO_RAW entries to the dummy driver Precursor to making value read / write attribute optional. No processed values in resolvers at the moment. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c index e3a9457..dbeb04c 100644 --- a/drivers/staging/iio/iio_simple_dummy.c +++ b/drivers/staging/iio/iio_simple_dummy.c @@ -73,6 +73,12 @@ static struct iio_chan_spec iio_dummy_channels[] = { /* What other information is available? */ .info_mask = /* + * in_voltage0_raw + * Raw (unscaled no bias removal etc) measurement + * from the device. + */ + IIO_CHAN_INFO_RAW_SEPARATE_BIT | + /* * in_voltage0_offset * Offset for userspace to apply prior to scale * when converting to standard units (microvolts) @@ -114,6 +120,12 @@ static struct iio_chan_spec iio_dummy_channels[] = { .channel2 = 2, .info_mask = /* + * in_voltage1-voltage2_raw + * Raw (unscaled no bias removal etc) measurement + * from the device. + */ + IIO_CHAN_INFO_RAW_SEPARATE_BIT | + /* * in_voltage-voltage_scale * Shared version of scale - shared by differential * input channels of type IIO_VOLTAGE. @@ -135,6 +147,7 @@ static struct iio_chan_spec iio_dummy_channels[] = { .channel = 3, .channel2 = 4, .info_mask = + IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT, .scan_index = diffvoltage3m4, .scan_type = { @@ -154,6 +167,7 @@ static struct iio_chan_spec iio_dummy_channels[] = { /* Channel 2 is use for modifiers */ .channel2 = IIO_MOD_X, .info_mask = + IIO_CHAN_INFO_RAW_SEPARATE_BIT | /* * Internal bias correction value. Applied * by the hardware or driver prior to userspace @@ -177,6 +191,7 @@ static struct iio_chan_spec iio_dummy_channels[] = { /* DAC channel out_voltage0_raw */ { .type = IIO_VOLTAGE, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .output = 1, .indexed = 1, .channel = 0, @@ -203,7 +218,7 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev, mutex_lock(&st->lock); switch (mask) { - case 0: /* magic value - channel value read */ + case IIO_CHAN_INFO_RAW: /* magic value - channel value read */ switch (chan->type) { case IIO_VOLTAGE: if (chan->output) { @@ -290,7 +305,7 @@ static int iio_dummy_write_raw(struct iio_dev *indio_dev, struct iio_dummy_state *st = iio_priv(indio_dev); switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: if (chan->output == 0) return -EINVAL; -- cgit v0.10.2 From a74437e46b1513bf271ae333f81ffc238557d92d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 15 Apr 2012 17:41:28 +0100 Subject: staging:iio:meter Add IIO_CHAN_INFO_RAW entries to all drivers. Precursor to making value read / write attribute optional. No processed values in resolvers at the moment. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c index 4d6bffa..729c033 100644 --- a/drivers/staging/iio/meter/ade7758_core.c +++ b/drivers/staging/iio/meter/ade7758_core.c @@ -667,7 +667,8 @@ static struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 0, .extend_name = "raw", - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = AD7758_WT(AD7758_PHASE_A, AD7758_VOLTAGE), .scan_index = 0, .scan_type = { @@ -680,7 +681,8 @@ static struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 0, .extend_name = "raw", - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = AD7758_WT(AD7758_PHASE_A, AD7758_CURRENT), .scan_index = 1, .scan_type = { @@ -693,7 +695,8 @@ static struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 0, .extend_name = "apparent_raw", - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = AD7758_WT(AD7758_PHASE_A, AD7758_APP_PWR), .scan_index = 2, .scan_type = { @@ -706,7 +709,8 @@ static struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 0, .extend_name = "active_raw", - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = AD7758_WT(AD7758_PHASE_A, AD7758_ACT_PWR), .scan_index = 3, .scan_type = { @@ -719,7 +723,8 @@ static struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 0, .extend_name = "reactive_raw", - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = AD7758_WT(AD7758_PHASE_A, AD7758_REACT_PWR), .scan_index = 4, .scan_type = { @@ -732,7 +737,8 @@ static struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 1, .extend_name = "raw", - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = AD7758_WT(AD7758_PHASE_B, AD7758_VOLTAGE), .scan_index = 5, .scan_type = { @@ -745,7 +751,8 @@ static struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 1, .extend_name = "raw", - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = AD7758_WT(AD7758_PHASE_B, AD7758_CURRENT), .scan_index = 6, .scan_type = { @@ -758,7 +765,8 @@ static struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 1, .extend_name = "apparent_raw", - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = AD7758_WT(AD7758_PHASE_B, AD7758_APP_PWR), .scan_index = 7, .scan_type = { @@ -771,7 +779,8 @@ static struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 1, .extend_name = "active_raw", - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = AD7758_WT(AD7758_PHASE_B, AD7758_ACT_PWR), .scan_index = 8, .scan_type = { @@ -784,7 +793,8 @@ static struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 1, .extend_name = "reactive_raw", - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = AD7758_WT(AD7758_PHASE_B, AD7758_REACT_PWR), .scan_index = 9, .scan_type = { @@ -797,7 +807,8 @@ static struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 2, .extend_name = "raw", - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = AD7758_WT(AD7758_PHASE_C, AD7758_VOLTAGE), .scan_index = 10, .scan_type = { @@ -810,7 +821,8 @@ static struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 2, .extend_name = "raw", - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = AD7758_WT(AD7758_PHASE_C, AD7758_CURRENT), .scan_index = 11, .scan_type = { @@ -823,7 +835,8 @@ static struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 2, .extend_name = "apparent_raw", - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = AD7758_WT(AD7758_PHASE_C, AD7758_APP_PWR), .scan_index = 12, .scan_type = { @@ -836,7 +849,8 @@ static struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 2, .extend_name = "active_raw", - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = AD7758_WT(AD7758_PHASE_C, AD7758_ACT_PWR), .scan_index = 13, .scan_type = { @@ -849,7 +863,8 @@ static struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 2, .extend_name = "reactive_raw", - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = AD7758_WT(AD7758_PHASE_C, AD7758_REACT_PWR), .scan_index = 14, .scan_type = { -- cgit v0.10.2 From a8c0ed756574ba5a484cd8238892f88501ff400d Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 15 Apr 2012 17:41:29 +0100 Subject: staging:iio:isl29028 Add IIO_CHAN_INFO_RAW/PROCESSED entries Precursor to making value read / write attribute optional. This one stands along as it merged just before the series doing all the other drivers. Signed-off-by: Jonathan Cameron Acked-by: Laxman Dewangan Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c index 4e6ac24..11dc8a9 100644 --- a/drivers/staging/iio/light/isl29028.c +++ b/drivers/staging/iio/light/isl29028.c @@ -330,7 +330,8 @@ static int isl29028_read_raw(struct iio_dev *indio_dev, mutex_lock(&chip->lock); switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: + case IIO_CHAN_INFO_PROCESSED: switch (chan->type) { case IIO_LIGHT: ret = isl29028_als_get(chip, val); @@ -391,12 +392,15 @@ static const struct iio_chan_spec isl29028_channels[] = { { .type = IIO_LIGHT, .processed_val = 1, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, }, { .type = IIO_INTENSITY, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, }, { .type = IIO_PROXIMITY, - .info_mask = IIO_CHAN_INFO_SAMP_FREQ_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SAMP_FREQ_SEPARATE_BIT, } }; -- cgit v0.10.2 From 75a973c7546ffae3b3c3fdb22211f1f59c01b0fa Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 15 Apr 2012 17:41:30 +0100 Subject: staging:iio: Make read / write attributes for channel values optional. Until now all channels have had read/write attributes. This patch allows for channels where we can't actually read the value (or for output devices, write it!) v2 introduces separate elements for processed and raw thus removing some special case code from the core. Thanks to Lars-Peter for an excellent suggestion! Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index 817e3fa..3ad04de 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c @@ -80,6 +80,8 @@ static const char * const iio_modifier_names[] = { /* relies on pairs of these shared then separate */ static const char * const iio_chan_info_postfix[] = { + [IIO_CHAN_INFO_RAW] = "raw", + [IIO_CHAN_INFO_PROCESSED] = "input", [IIO_CHAN_INFO_SCALE] = "scale", [IIO_CHAN_INFO_OFFSET] = "offset", [IIO_CHAN_INFO_CALIBSCALE] = "calibscale", @@ -577,26 +579,12 @@ static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev, struct iio_chan_spec const *chan) { int ret, attrcount = 0; - int i = 4; + int i; const struct iio_chan_spec_ext_info *ext_info; if (chan->channel < 0) return 0; - - ret = __iio_add_chan_devattr(iio_data_type_name[chan->processed_val], - chan, - &iio_read_channel_info, - (chan->output ? - &iio_write_channel_info : NULL), - 0, - 0, - &indio_dev->dev, - &indio_dev->channel_attr_list); - if (ret) - goto error_ret; - attrcount++; - - for_each_set_bit_from(i, &chan->info_mask, sizeof(long)*8) { + for_each_set_bit(i, &chan->info_mask, sizeof(long)*8) { ret = __iio_add_chan_devattr(iio_chan_info_postfix[i/2], chan, &iio_read_channel_info, -- cgit v0.10.2 From 251640a74b086cb5b602870cdbaf72e6d3f1e714 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 15 Apr 2012 17:41:31 +0100 Subject: staging:iio: drop procesed_val element of chan_spec. There is no longer any need for this as we have separate info_mask elements for raw and processed value reads. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c index 6c75605..750bf4b 100644 --- a/drivers/staging/iio/cdc/ad7746.c +++ b/drivers/staging/iio/cdc/ad7746.c @@ -142,7 +142,6 @@ static const struct iio_chan_spec ad7746_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .processed_val = IIO_PROCESSED, .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, .address = AD7746_REG_VT_DATA_HIGH << 8 | AD7746_VTSETUP_VTMD_INT_TEMP, @@ -151,7 +150,6 @@ static const struct iio_chan_spec ad7746_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 1, - .processed_val = IIO_PROCESSED, .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, .address = AD7746_REG_VT_DATA_HIGH << 8 | AD7746_VTSETUP_VTMD_EXT_TEMP, diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h index dda1602..a562763 100644 --- a/drivers/staging/iio/iio.h +++ b/drivers/staging/iio/iio.h @@ -19,12 +19,6 @@ * Currently assumes nano seconds. */ -enum iio_data_type { - IIO_RAW, - IIO_PROCESSED, -}; - -/* Could add the raw attributes as well - allowing buffer only devices */ enum iio_chan_info_enum { IIO_CHAN_INFO_RAW = 0, IIO_CHAN_INFO_PROCESSED, @@ -146,8 +140,6 @@ struct iio_chan_spec_ext_info { * correspond to the first name that the channel is referred * to by in the datasheet (e.g. IND), or the nearest * possible compound name (e.g. IND-INC). - * @processed_val: Flag to specify the data access attribute should be - * *_input rather than *_raw. * @modified: Does a modifier apply to this channel. What these are * depends on the channel type. Modifier is set in * channel2. Examples are IIO_MOD_X for axial sensors about @@ -176,7 +168,6 @@ struct iio_chan_spec { const struct iio_chan_spec_ext_info *ext_info; const char *extend_name; const char *datasheet_name; - unsigned processed_val:1; unsigned modified:1; unsigned indexed:1; unsigned output:1; diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 9d5738a..93e5a71 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -112,7 +112,6 @@ static struct iio_chan_spec ad5933_channels[] = { { .type = IIO_TEMP, .indexed = 1, - .processed_val = 1, .channel = 0, .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, .address = AD5933_REG_TEMP_DATA, diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index 3ad04de..db55b81 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c @@ -42,11 +42,6 @@ EXPORT_SYMBOL(iio_bus_type); static struct dentry *iio_debugfs_dentry; -static const char * const iio_data_type_name[] = { - [IIO_RAW] = "raw", - [IIO_PROCESSED] = "input", -}; - static const char * const iio_direction[] = { [0] = "in", [1] = "out", diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index 350f12c..073e899 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -420,7 +420,6 @@ static const struct iio_chan_spec isl29018_channels[] = { .type = IIO_LIGHT, .indexed = 1, .channel = 0, - .processed_val = IIO_PROCESSED, .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT | IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, }, { diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c index 11dc8a9..4ac49aa 100644 --- a/drivers/staging/iio/light/isl29028.c +++ b/drivers/staging/iio/light/isl29028.c @@ -391,7 +391,6 @@ static const struct attribute_group isl29108_group = { static const struct iio_chan_spec isl29028_channels[] = { { .type = IIO_LIGHT, - .processed_val = 1, .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, }, { diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c index a334a88..a1e5cbe 100644 --- a/drivers/staging/iio/light/tsl2563.c +++ b/drivers/staging/iio/light/tsl2563.c @@ -535,7 +535,6 @@ static const struct iio_chan_spec tsl2563_channels[] = { { .type = IIO_LIGHT, .indexed = 1, - .processed_val = 1, .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, .channel = 0, }, { -- cgit v0.10.2 From ad220db422c778a30f83061e9e2458b5f0ee6704 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Tue, 17 Apr 2012 00:26:29 +0900 Subject: staging: Fix typo within android drivers. Fix spelling typo in comments within android drivers. Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c index 03efb34..1b618f3 100644 --- a/drivers/staging/android/alarm-dev.c +++ b/drivers/staging/android/alarm-dev.c @@ -54,7 +54,7 @@ module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); ANDROID_ALARM_RTC_WAKEUP_MASK | \ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK) -/* support old usespace code */ +/* support old userspace code */ #define ANDROID_ALARM_SET_OLD _IOW('a', 2, time_t) /* set alarm */ #define ANDROID_ALARM_SET_AND_WAIT_OLD _IOW('a', 3, time_t) diff --git a/drivers/staging/android/alarm.c b/drivers/staging/android/alarm.c index c68950b..d42a592 100644 --- a/drivers/staging/android/alarm.c +++ b/drivers/staging/android/alarm.c @@ -57,7 +57,7 @@ module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); ANDROID_ALARM_RTC_WAKEUP_MASK | \ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK) -/* support old usespace code */ +/* support old userspace code */ #define ANDROID_ALARM_SET_OLD _IOW('a', 2, time_t) /* set alarm */ #define ANDROID_ALARM_SET_AND_WAIT_OLD _IOW('a', 3, time_t) @@ -543,7 +543,7 @@ static int __init alarm_late_init(void) /* this needs to run after the rtc is read at boot */ spin_lock_irqsave(&alarm_slock, flags); - /* We read the current rtc and system time so we can later calulate + /* We read the current rtc and system time so we can later calculate * elasped realtime to be (boot_systemtime + rtc - boot_rtc) == * (rtc - (boot_rtc - boot_systemtime)) */ diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h index 6eecbde..e586cae 100644 --- a/drivers/staging/android/android_alarm.h +++ b/drivers/staging/android/android_alarm.h @@ -41,7 +41,7 @@ enum android_alarm_type { /* * The alarm interface is similar to the hrtimer interface but adds support * for wakeup from suspend. It also adds an elapsed realtime clock that can - * be used for periodic timers that need to keep runing while the system is + * be used for periodic timers that need to keep running while the system is * suspended and not be disrupted when the wall time is set. */ diff --git a/drivers/staging/android/binder.h b/drivers/staging/android/binder.h index 25ab6f2..6602474 100644 --- a/drivers/staging/android/binder.h +++ b/drivers/staging/android/binder.h @@ -63,7 +63,7 @@ struct flat_binder_object { /* * On 64-bit platforms where user code may run in 32-bits the driver must - * translate the buffer (and local binder) addresses apropriately. + * translate the buffer (and local binder) addresses appropriately. */ struct binder_write_read { -- cgit v0.10.2 From 15ecf29e1666ac0c18625ad276423c0291536543 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 16 Apr 2012 18:01:24 -0700 Subject: staging: fix android alarm.c printk format warnings Fix printk format warnings by using 't' modifier for ptrdiff_t. drivers/staging/android/alarm.c:344:2: warning: format '%ld' expects type 'long int', but argument 2 has type 'int' drivers/staging/android/alarm.c:367:3: warning: format '%ld' expects type 'long int', but argument 2 has type 'int' Signed-off-by: Randy Dunlap Cc: Brian Swetland Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/alarm.c b/drivers/staging/android/alarm.c index d42a592..0cae132 100644 --- a/drivers/staging/android/alarm.c +++ b/drivers/staging/android/alarm.c @@ -341,7 +341,7 @@ static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer) now = base->stopped ? base->stopped_time : hrtimer_cb_get_time(timer); now = ktime_sub(now, base->delta); - pr_alarm(INT, "alarm_timer_triggered type %ld at %lld\n", + pr_alarm(INT, "alarm_timer_triggered type %td at %lld\n", base - alarms, ktime_to_ns(now)); while (base->first) { @@ -364,7 +364,7 @@ static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer) spin_lock_irqsave(&alarm_slock, flags); } if (!base->first) - pr_alarm(FLOW, "no more alarms of type %ld\n", base - alarms); + pr_alarm(FLOW, "no more alarms of type %td\n", base - alarms); update_timer_locked(base, true); spin_unlock_irqrestore(&alarm_slock, flags); return HRTIMER_NORESTART; -- cgit v0.10.2 From ed2cb4f3b5ed96e4d10e054f981bbe58d0e3508e Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Tue, 17 Apr 2012 06:56:43 -0700 Subject: Staging: rtl8187se: Fix typos. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8187se/Makefile b/drivers/staging/rtl8187se/Makefile index 72db504..91d1aa2 100644 --- a/drivers/staging/rtl8187se/Makefile +++ b/drivers/staging/rtl8187se/Makefile @@ -10,7 +10,7 @@ ccflags-y += -DHIGH_POWER ccflags-y += -DSW_DIG ccflags-y += -DRATE_ADAPT -#enable it for legacy power save, disable it for leisure power save +#enable it for legacy power save, disable it for leisure power save ccflags-y += -DENABLE_LPS diff --git a/drivers/staging/rtl8187se/ieee80211/dot11d.c b/drivers/staging/rtl8187se/ieee80211/dot11d.c index 309bb8b..0e93eb0 100644 --- a/drivers/staging/rtl8187se/ieee80211/dot11d.c +++ b/drivers/staging/rtl8187se/ieee80211/dot11d.c @@ -55,7 +55,7 @@ Dot11d_Reset(struct ieee80211_device *ieee) // // Description: -// Update country IE from Beacon or Probe Resopnse +// Update country IE from Beacon or Probe Response // and configure PHY for operation in the regulatory domain. // // TODO: diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h index 40dd715..b94c48b 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h @@ -834,7 +834,7 @@ enum ieee80211_state { /* the association procedure is sending AUTH request*/ IEEE80211_ASSOCIATING_AUTHENTICATING, - /* the association procedure has successfully authentcated + /* the association procedure has successfully authenticated * and is sending association request */ IEEE80211_ASSOCIATING_AUTHENTICATED, @@ -934,7 +934,7 @@ struct ieee80211_device { * with RX of broad/multicast frames */ /* Fragmentation structures */ - // each streaming contain a entry + /* each stream contains an entry */ struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN]; unsigned int frag_next_idx[17]; u16 fts; /* Fragmentation Threshold */ @@ -972,7 +972,7 @@ struct ieee80211_device { int rate; /* current rate */ int basic_rate; - //FIXME: pleace callback, see if redundant with softmac_features + //FIXME: please callback, see if redundant with softmac_features short active_scan; /* this contains flags for selectively enable softmac support */ @@ -1106,7 +1106,7 @@ struct ieee80211_device { /* used instead of hard_start_xmit (not softmac_hard_start_xmit) * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data - * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set + * frames. If the option IEEE_SOFTMAC_SINGLE_QUEUE is also set * then also management frames are sent via this callback. * This function can't sleep. */ @@ -1124,7 +1124,7 @@ struct ieee80211_device { /* ask to the driver to retune the radio . * This function can sleep. the driver should ensure - * the radio has been swithced before return. + * the radio has been switched before return. */ void (*set_chan)(struct net_device *dev,short ch); @@ -1135,7 +1135,7 @@ struct ieee80211_device { * The syncro version is similar to the start_scan but * does not return until all channels has been scanned. * this is called in user context and should sleep, - * it is called in a work_queue when swithcing to ad-hoc mode + * it is called in a work_queue when switching to ad-hoc mode * or in behalf of iwlist scan when the card is associated * and root user ask for a scan. * the function stop_scan should stop both the syncro and @@ -1196,7 +1196,7 @@ struct ieee80211_device { /* Generate probe requests */ #define IEEE_SOFTMAC_PROBERQ (1<<4) -/* Generate respones to probe requests */ +/* Generate response to probe requests */ #define IEEE_SOFTMAC_PROBERS (1<<5) /* The ieee802.11 stack will manages the netif queue diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c index 0f909b7..8173240 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c @@ -42,7 +42,7 @@ short ieee80211_is_shortslot(const struct ieee80211_network *net) return net->capability & WLAN_CAPABILITY_SHORT_SLOT; } -/* returns the total length needed for pleacing the RATE MFIE +/* returns the total length needed for placing the RATE MFIE * tag and the EXTENDED RATE MFIE tag if needed. * It encludes two bytes per tag for the tag itself and its len */ @@ -60,7 +60,7 @@ unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee) return rate_len; } -/* pleace the MFIE rate, tag to the memory (double) poined. +/* place the MFIE rate, tag to the memory (double) poised. * Then it updates the pointer so that * it points after the new MFIE tag added. */ @@ -467,7 +467,7 @@ void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee) * So we switch to IEEE80211_LINKED_SCANNING to remember * that we are still logically linked (not interested in * new network events, despite for updating the net list, - * but we are temporarly 'unlinked' as the driver shall + * but we are temporarily 'unlinked' as the driver shall * not filter RX frames and the channel is changing. * So the only situation in witch are interested is to check * if the state become LINKED because of the #1 situation @@ -530,7 +530,7 @@ void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee) * So we switch to IEEE80211_LINKED_SCANNING to remember * that we are still logically linked (not interested in * new network events, despite for updating the net list, - * but we are temporarly 'unlinked' as the driver shall + * but we are temporarily 'unlinked' as the driver shall * not filter RX frames and the channel is changing. * So the only situation in witch are interested is to check * if the state become LINKED because of the #1 situation @@ -1140,7 +1140,7 @@ void ieee80211_associate_abort(struct ieee80211_device *ieee) ieee->associate_seq++; - /* don't scan, and avoid to have the RX path possibily + /* don't scan, and avoid to have the RX path possibly * try again to associate. Even do not react to AUTH or * ASSOC response. Just wait for the retry wq to be scheduled. * Here we will check if there are good nets to associate @@ -1346,14 +1346,14 @@ inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee //printk("apset=%d apmatch=%d ssidset=%d ssidbroad=%d ssidmatch=%d\n",apset,apmatch,ssidset,ssidbroad,ssidmatch); if ( /* if the user set the AP check if match. - * if the network does not broadcast essid we check the user supplyed ANY essid + * if the network does not broadcast essid we check the user supplied ANY essid * if the network does broadcast and the user does not set essid it is OK * if the network does broadcast and the user did set essid chech if essid match */ ( apset && apmatch && ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) || /* if the ap is not set, check that the user set the bssid - * and the network does bradcast and that those two bssid matches + * and the network does broadcast and that those two bssid matches */ (!apset && ssidset && ssidbroad && ssidmatch) ){ @@ -1821,7 +1821,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, while (left >= sizeof(struct ieee80211_info_element_hdr)) { if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) { - printk(KERN_WARNING "[re]associate reeponse error!"); + printk(KERN_WARNING "[re]associate response error!"); return 1; } switch (info_element->id) { @@ -2184,15 +2184,15 @@ void ieee80211_start_ibss_wq(struct work_struct *work) if(ieee->state == IEEE80211_NOLINK) ieee->current_network.channel = 10; - /* if not then the state is not linked. Maybe the user swithced to + /* if not then the state is not linked. Maybe the user switched to * ad-hoc mode just after being in monitor mode, or just after * being very few time in managed mode (so the card have had no * time to scan all the chans..) or we have just run up the iface * after setting ad-hoc mode. So we have to give another try.. * Here, in ibss mode, should be safe to do this without extra care - * (in bss mode we had to make sure no-one tryed to associate when + * (in bss mode we had to make sure no-one tried to associate when * we had just checked the ieee->state and we was going to start the - * scan) beacause in ibss mode the ieee80211_new_net function, when + * scan) because in ibss mode the ieee80211_new_net function, when * finds a good net, just set the ieee->state to IEEE80211_LINKED, * so, at worst, we waste a bit of time to initiate an unneeded syncro * scan, that will stop at the first round because it sees the state @@ -2342,7 +2342,7 @@ void ieee80211_associate_retry_wq(struct work_struct *work) goto exit; /* until we do not set the state to IEEE80211_NOLINK * there are no possibility to have someone else trying - * to start an association procdure (we get here with + * to start an association procedure (we get here with * ieee->state = IEEE80211_ASSOCIATING). * When we set the state to IEEE80211_NOLINK it is possible * that the RX path run an attempt to associate, but diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c index e46ff2f..5d20490 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c @@ -362,7 +362,7 @@ int ieee80211_wx_set_essid(struct ieee80211_device *ieee, ieee80211_stop_protocol(ieee); /* this is just to be sure that the GET wx callback - * has consisten infos. not needed otherwise + * has consistent infos. not needed otherwise */ spin_lock_irqsave(&ieee->lock, flags); diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c index 552115c..77bb068 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c @@ -328,7 +328,7 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, //printk(KERN_WARNING "upper layer packet!\n"); spin_lock_irqsave(&ieee->lock, flags); - /* If there is no driver handler to take the TXB, dont' bother + /* If there is no driver handler to take the TXB, don't bother * creating it... */ if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))|| ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) { diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c index ca414a9..c7917b2 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c @@ -363,7 +363,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee, (*crypt)->priv); sec.flags |= (1 << key); /* This ensures a key will be activated if no key is - * explicitely set */ + * explicitly set */ if (key == sec.active_key) sec.flags |= SEC_ACTIVE_KEY; ieee->tx_keyidx = key;//by wb 080312 diff --git a/drivers/staging/rtl8187se/r8180.h b/drivers/staging/rtl8187se/r8180.h index a2c46ae..2682afb 100644 --- a/drivers/staging/rtl8187se/r8180.h +++ b/drivers/staging/rtl8187se/r8180.h @@ -11,7 +11,7 @@ Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - We want to tanks the Authors of those projects and the Ndiswrapper + We want to thanks the Authors of those projects and the Ndiswrapper project Authors. */ @@ -514,12 +514,12 @@ typedef struct r8180_priv bool bDefaultAntenna1; u8 SignalStrength; long Stats_SignalStrength; - long LastSignalStrengthInPercent; // In percentange, used for smoothing, e.g. Moving Average. + long LastSignalStrengthInPercent; // In percentage, used for smoothing, e.g. Moving Average. u8 SignalQuality; // in 0-100 index. long Stats_SignalQuality; long RecvSignalPower; // in dBm. long Stats_RecvSignalPower; - u8 LastRxPktAntenna; // +by amy 080312 Antenn which received the lasted packet. 0: Aux, 1:Main. Added by Roger, 2008.01.25. + u8 LastRxPktAntenna; // +by amy 080312 Antenna which received the lasted packet. 0: Aux, 1:Main. Added by Roger, 2008.01.25. u32 AdRxOkCnt; long AdRxSignalStrength; u8 CurrAntennaIndex; // Index to current Antenna (both Tx and Rx). @@ -530,7 +530,7 @@ typedef struct r8180_priv long AdRxSsThreshold; // Signal strength threshold to switch antenna. long AdMaxRxSsThreshold; // Max value of AdRxSsThreshold. bool bAdSwitchedChecking; // TRUE if we shall shall check Rx signal strength for last time switching antenna. - long AdRxSsBeforeSwitched; // Rx signal strength before we swithed antenna. + long AdRxSsBeforeSwitched; // Rx signal strength before we switched antenna. struct timer_list SwAntennaDiversityTimer; //by amy for antenna //{by amy 080312 @@ -553,7 +553,7 @@ typedef struct r8180_priv bool bDigMechanism; // TRUE if DIG is enabled, FALSE ow. bool bRegHighPowerMechanism; // For High Power Mechanism. 061010, by rcnjko. u32 FalseAlarmRegValue; - u8 RegDigOfdmFaUpTh; // Upper threhold of OFDM false alarm, which is used in DIG. + u8 RegDigOfdmFaUpTh; // Upper threshold of OFDM false alarm, which is used in DIG. u8 DIG_NumberFallbackVote; u8 DIG_NumberUpgradeVote; // For HW antenna diversity, added by Roger, 2008.01.30. diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 4fe52f6..a513ec7 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -1329,7 +1329,7 @@ u16 N_DBPSOfRate(u16 DataRate) } /* - * For Netgear case, they want good-looking singal strength. + * For Netgear case, they want good-looking signal strength. */ long NetgearSignalStrengthTranslate(long LastSS, long CurrSS) { @@ -1380,7 +1380,7 @@ long TranslateToDbm8185(u8 SignalStrengthIndex) /* * Perform signal smoothing for dynamic mechanism. - * This is different with PerformSignalSmoothing8185 in smoothing fomula. + * This is different with PerformSignalSmoothing8185 in smoothing formula. * No dramatic adjustion is apply because dynamic mechanism need some degree * of correctness. Ported from 8187B. */ @@ -1535,7 +1535,7 @@ void rtl8180_rx(struct net_device *dev) /* HW is probably passing several buggy frames * without FD or LD flag set. * Throw this garbage away to prevent skb - * memory exausting + * memory exhausting */ if (!priv->rx_skb_complete) dev_kfree_skb_any(priv->rx_skb); @@ -1648,14 +1648,14 @@ void rtl8180_rx(struct net_device *dev) priv->Stats_SignalQuality = (long)(priv->Stats_SignalQuality * 5 + (long)priv->SignalQuality + 5) / 6; priv->Stats_RecvSignalPower = (long)(priv->Stats_RecvSignalPower * 5 + priv->RecvSignalPower - 1) / 6; - /* Figure out which antenna that received the lasted packet. */ + /* Figure out which antenna that received the last packet. */ priv->LastRxPktAntenna = Antenna ? 1 : 0; /* 0: aux, 1: main. */ SwAntennaDiversityRxOk8185(dev, priv->SignalStrength); } if (first) { if (!priv->rx_skb_complete) { - /* seems that HW sometimes fails to reiceve and + /* seems that HW sometimes fails to receive and doesn't provide the last descriptor */ dev_kfree_skb_any(priv->rx_skb); priv->stats.rxnolast++; @@ -1672,7 +1672,7 @@ void rtl8180_rx(struct net_device *dev) priv->rx_skb_complete = 0; priv->rx_skb->dev = dev; } else { - /* if we are here we should have already RXed + /* if we are here we should have already RXed * the first frame. * If we get here and the skb is not allocated then * we have just throw out garbage (skb not allocated) @@ -1821,15 +1821,15 @@ rate) { /* * This is a rough attempt to TX a frame * This is called by the ieee 80211 stack to TX management frames. - * If the ring is full packet are dropped (for data frame the queue + * If the ring is full packets are dropped (for data frame the queue * is stopped before this can happen). For this reason it is better * if the descriptors are larger than the largest management frame - * we intend to TX: i'm unsure what the HW does if it will not found + * we intend to TX: i'm unsure what the HW does if it will not find * the last fragment of a frame because it has been dropped... * Since queues for Management and Data frames are different we * might use a different lock than tx_lock (for example mgmt_tx_lock) */ -/* these function may loops if invoked with 0 descriptors or 0 len buffer */ +/* these function may loop if invoked with 0 descriptors or 0 len buffer */ int rtl8180_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); @@ -2378,7 +2378,7 @@ void rtl8180_wmm_param_update(struct work_struct *work) u8 u1bAIFS; u32 u4bAcParam; pAcParam = (PAC_PARAM)(&AcParam); - /* Retrive paramters to udpate. */ + /* Retrieve paramters to update. */ u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * (((mode&IEEE_G) == IEEE_G) ? 9 : 20) + aSifsTime; u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit))<f.Ecw.f.ECWmax))<f.AciAifsn.f.ACI; /* Mode G/A: slotTimeTimer = 9; Mode B: 20 */ u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * (((mode&IEEE_G) == IEEE_G) ? 9 : 20) + aSifsTime; @@ -2700,7 +2700,7 @@ short rtl8180_init(struct net_device *dev) priv->bTxPowerTrack = false; priv->ThermalMeter = 0; priv->FalseAlarmRegValue = 0; - priv->RegDigOfdmFaUpTh = 0xc; /* Upper threhold of OFDM false alarm, which is used in DIG. */ + priv->RegDigOfdmFaUpTh = 0xc; /* Upper threshold of OFDM false alarm, which is used in DIG. */ priv->DIG_NumberFallbackVote = 0; priv->DIG_NumberUpgradeVote = 0; priv->LastSignalStrengthInPercent = 0; @@ -2896,7 +2896,7 @@ short rtl8180_init(struct net_device *dev) priv->chtxpwr_ofdm[i+1] = (word & 0xff00) >> 8; } - /* 3Read crystal calibtration and thermal meter indication on 87SE. */ + /* 3Read crystal calibration and thermal meter indication on 87SE. */ eeprom_93cx6_read(&eeprom, EEPROM_RSV>>1, &tmpu16); /* Crystal calibration for Xin and Xout resp. */ @@ -3140,7 +3140,7 @@ void rtl8180_adapter_start(struct net_device *dev) /* * The following is very strange. seems to be that 1 means test mode, - * but we need to acknolwledges the nic when a packet is ready + * but we need to acknowledges the nic when a packet is ready * although we set it to 0 */ @@ -3971,7 +3971,7 @@ irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs) } if (inta == 0xffff) { - /* HW disappared */ + /* HW disappeared */ spin_unlock_irqrestore(&priv->irq_th_lock, flags); return IRQ_HANDLED; } diff --git a/drivers/staging/rtl8187se/r8180_dm.c b/drivers/staging/rtl8187se/r8180_dm.c index 4d7a595..b8f2ba0 100644 --- a/drivers/staging/rtl8187se/r8180_dm.c +++ b/drivers/staging/rtl8187se/r8180_dm.c @@ -2,7 +2,7 @@ #include "r8180_hw.h" #include "r8180_93cx6.h" - /* Return TRUE if we shall perform High Power Mecahnism, FALSE otherwise. */ + /* Return TRUE if we shall perform High Power Mechanism, FALSE otherwise. */ #define RATE_ADAPTIVE_TIMER_PERIOD 300 bool CheckHighPower(struct net_device *dev) @@ -105,7 +105,7 @@ void rtl8180_tx_pw_wq(struct work_struct *work) /* - * Return TRUE if we shall perform DIG Mecahnism, FALSE otherwise. + * Return TRUE if we shall perform DIG Mechanism, FALSE otherwise. */ bool CheckDig(struct net_device *dev) { @@ -507,7 +507,7 @@ void StaRateAdaptive87SE(struct net_device *dev) * and retry rate. * (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated * situation, Initial Gain Update is upon on DIG mechanism except CCK rate. - * (4) Add the mehanism of trying to upgrade tx rate. + * (4) Add the mechanism of trying to upgrade tx rate. * (5) Record the information of upping tx rate to avoid trying upping tx rate constantly. * */ @@ -528,7 +528,7 @@ void StaRateAdaptive87SE(struct net_device *dev) if (priv->bTryuping == true) { /* 2 For Test Upgrading mechanism * Note: - * Sometimes the throughput is upon on the capability bwtween the AP and NIC, + * Sometimes the throughput is upon on the capability between the AP and NIC, * thus the low data rate does not improve the performance. * We randomly upgrade the data rate and check if the retry rate is improved. */ @@ -704,7 +704,7 @@ void StaRateAdaptive87SE(struct net_device *dev) /* * The difference in throughput between 48Mbps and 36Mbps is 8M. - * So, we must be carefully in this rate scale. Isaiah 2008-02-15. + * So, we must be careful in this rate scale. Isaiah 2008-02-15. */ if (((priv->CurrentOperaRate == 72) || (priv->CurrentOperaRate == 48) || (priv->CurrentOperaRate == 36)) && (priv->FailTxRateCount > 2)) @@ -1009,7 +1009,7 @@ void SwAntennaDiversity(struct net_device *dev) if (priv->AdCheckPeriod > priv->AdMaxCheckPeriod) priv->AdCheckPeriod = priv->AdMaxCheckPeriod; - /* Wrong deceision => switch back. */ + /* Wrong decision => switch back. */ SwitchAntenna(dev); } else { /* Rx Signal Strength is improved. */ @@ -1057,7 +1057,7 @@ void SwAntennaDiversity(struct net_device *dev) } /* * We evaluate Rx signal strength ONLY when default antenna - * didn't changed by HW evaluation. + * didn't change by HW evaluation. * 2008.02.27. * * [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05 @@ -1098,7 +1098,7 @@ void SwAntennaDiversity(struct net_device *dev) priv->AdAuxAntennaRxOkCnt = 0; } - /* Return TRUE if we shall perform Tx Power Tracking Mecahnism, FALSE otherwise. */ + /* Return TRUE if we shall perform Tx Power Tracking Mechanism, FALSE otherwise. */ bool CheckTxPwrTracking(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); diff --git a/drivers/staging/rtl8187se/r8180_rtl8225z2.c b/drivers/staging/rtl8187se/r8180_rtl8225z2.c index ee5b867..d28c1d9 100644 --- a/drivers/staging/rtl8187se/r8180_rtl8225z2.c +++ b/drivers/staging/rtl8187se/r8180_rtl8225z2.c @@ -190,7 +190,7 @@ static void rtl8225_SetTXPowerLevel(struct net_device *dev, short ch) write_phy_cck(dev, 0x44 + i, power); } - /* FIXME Is this delay really needeed ? */ + /* FIXME Is this delay really needed ? */ force_pci_posting(dev); mdelay(1); @@ -479,7 +479,7 @@ s8 DbmToTxPwrIdx(struct r8180_priv *priv, WIRELESS_MODE WirelessMode, /* * TRUE if we want to use a default implementation. - * We shall set it to FALSE when we have exact translation formular + * We shall set it to FALSE when we have exact translation formula * for target IC. 070622, by rcnjko. */ if (bUseDefault) { diff --git a/drivers/staging/rtl8187se/r8180_wx.c b/drivers/staging/rtl8187se/r8180_wx.c index 303ec69..46ee6f4 100644 --- a/drivers/staging/rtl8187se/r8180_wx.c +++ b/drivers/staging/rtl8187se/r8180_wx.c @@ -13,7 +13,7 @@ Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. - We want to tanks the Authors of those projects and the Ndiswrapper + We want to thanks the Authors of those projects and the Ndiswrapper project Authors. */ @@ -1181,7 +1181,7 @@ static iw_handler r8180_wx_handlers[] = { r8180_wx_set_wap, /* SIOCSIWAP */ r8180_wx_get_wap, /* SIOCGIWAP */ r8180_wx_set_mlme, /* SIOCSIWMLME*/ - dummy, /* SIOCGIWAPLIST -- depricated */ + dummy, /* SIOCGIWAPLIST -- deprecated */ r8180_wx_set_scan, /* SIOCSIWSCAN */ r8180_wx_get_scan, /* SIOCGIWSCAN */ r8180_wx_set_essid, /* SIOCSIWESSID */ @@ -1369,7 +1369,7 @@ static inline int is_same_network(struct ieee80211_network *src, (dst->capability & WLAN_CAPABILITY_BSS))); } -/* WB modefied to show signal to GUI on 18-01-2008 */ +/* WB modified to show signal to GUI on 18-01-2008 */ static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev) { struct r8180_priv *priv = ieee80211_priv(dev); diff --git a/drivers/staging/rtl8187se/r8180_wx.h b/drivers/staging/rtl8187se/r8180_wx.h index 735d03d..4081914 100644 --- a/drivers/staging/rtl8187se/r8180_wx.h +++ b/drivers/staging/rtl8187se/r8180_wx.h @@ -7,7 +7,7 @@ Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - We want to tanks the Authors of such projects and the Ndiswrapper project Authors. + We want to thanks the Authors of such projects and the Ndiswrapper project Authors. */ /* this file (will) contains wireless extension handlers*/ diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c index af9be96..9144957 100644 --- a/drivers/staging/rtl8187se/r8185b_init.c +++ b/drivers/staging/rtl8187se/r8185b_init.c @@ -1008,7 +1008,7 @@ void ActUpdateChannelAccessSetting(struct net_device *dev, u8 u1bAIFS; u32 u4bAcParam; - /* Retrive paramters to udpate. */ + /* Retrieve paramters to update. */ eACI = pAcParam->f.AciAifsn.f.ACI; u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * ChnlAccessSetting->SlotTimeTimer + aSifsTime; u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) | @@ -1104,7 +1104,7 @@ void ActSetWirelessMode8185(struct net_device *dev, u8 btWirelessMode) return; } - /* 1. Assign wireless mode to swtich if necessary. */ + /* 1. Assign wireless mode to switch if necessary. */ if (btWirelessMode == WIRELESS_MODE_AUTO) { if ((btSupportedWirelessMode & WIRELESS_MODE_A)) { btWirelessMode = WIRELESS_MODE_A; @@ -1124,7 +1124,7 @@ void ActSetWirelessMode8185(struct net_device *dev, u8 btWirelessMode) * 2. Swtich band: RF or BB specific actions, * for example, refresh tables in omc8255, or change initial gain if necessary. * Nothing to do for Zebra to switch band. - * Update current wireless mode if we swtich to specified band successfully. + * Update current wireless mode if we switch to specified band successfully. */ ieee->mode = (WIRELESS_MODE)btWirelessMode; @@ -1242,7 +1242,7 @@ bool MgntDisconnect(struct net_device *dev, u8 asRsn) */ MgntDisconnectAP(dev, asRsn); } - /* Inidicate Disconnect, 2005.02.23, by rcnjko. */ + /* Indicate Disconnect, 2005.02.23, by rcnjko. */ } return true; } @@ -1416,7 +1416,7 @@ void IPSEnter(struct net_device *dev) * Do not enter IPS in the following conditions: * (1) RF is already OFF or Sleep * (2) bSwRfProcessing (indicates the IPS is still under going) - * (3) Connectted (only disconnected can trigger IPS) + * (3) Connected (only disconnected can trigger IPS) * (4) IBSS (send Beacon) * (5) AP mode (send Beacon) */ -- cgit v0.10.2 From f7738eda211091d8caf612b2bc1bac2fb52e48c6 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 17 Apr 2012 23:37:31 +0300 Subject: Staging: rtl8192u: fix some memory corruption When we received a command we incremented a stat counter depending on the type of message. The problem is there were 8 types of commands but there were only 4 counters allocated so it corrupted memory past the end of the rxcmdpkt[] array. The fix is just to remove the counters because they aren't used. Signed-off-by: Dan Carpenter ACKed-by: Larry Finger Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192u/r8192U.h b/drivers/staging/rtl8192u/r8192U.h index 9b81f26..43d459d 100644 --- a/drivers/staging/rtl8192u/r8192U.h +++ b/drivers/staging/rtl8192u/r8192U.h @@ -610,7 +610,6 @@ typedef struct Stats // unsigned long rxnopointer; unsigned long rxok; unsigned long rxframgment; - unsigned long rxcmdpkt[4]; //08/05/08 amy rx cmd element txfeedback/bcn report/cfg set/query unsigned long rxurberr; unsigned long rxstaterr; unsigned long received_rate_histogram[4][32]; //0: Total, 1:OK, 2:CRC, 3:ICV, 2007 07 03 cosa diff --git a/drivers/staging/rtl8192u/r819xU_cmdpkt.c b/drivers/staging/rtl8192u/r819xU_cmdpkt.c index 0cb28c7..9348f42 100644 --- a/drivers/staging/rtl8192u/r819xU_cmdpkt.c +++ b/drivers/staging/rtl8192u/r819xU_cmdpkt.c @@ -697,7 +697,6 @@ cmpk_message_handle_rx( struct ieee80211_rx_stats *pstats) { // u32 debug_level = DBG_LOUD; - struct r8192_priv *priv = ieee80211_priv(dev); int total_length; u8 cmd_length, exe_cnt = 0; u8 element_id; @@ -779,9 +778,6 @@ cmpk_message_handle_rx( // 2007/01/22 MH Add to display tx statistic. //cmpk_DisplayTxStatistic(pAdapter); - /* 2007/03/09 MH Collect sidderent cmd element pkt num. */ - priv->stats.rxcmdpkt[element_id]++; - total_length -= cmd_length; pcmd_buff += cmd_length; } /* while (total_length > 0) */ -- cgit v0.10.2 From 6b56d2459be6ce0e87b18a4276fef5d1bc265320 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 17 Apr 2012 09:45:59 +0300 Subject: Staging: rtl8192e: remove some dead code We don't use the rxcmdpkt[] counters at all and we can remove them. Signed-off-by: Dan Carpenter ACKed-by: Larry Finger Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c index 58d044e..ea91744 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c @@ -342,7 +342,6 @@ static void cmpk_handle_tx_rate_history(struct net_device *dev, u8 *pmsg) u32 cmpk_message_handle_rx(struct net_device *dev, struct rtllib_rx_stats *pstats) { - struct r8192_priv *priv = rtllib_priv(dev); int total_length; u8 cmd_length, exe_cnt = 0; u8 element_id; @@ -409,8 +408,6 @@ u32 cmpk_message_handle_rx(struct net_device *dev, return 1; } - priv->stats.rxcmdpkt[element_id]++; - total_length -= cmd_length; pcmd_buff += cmd_length; } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index 2a2519c..cebb748 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -353,7 +353,6 @@ struct rt_stats { unsigned long rxrdu; unsigned long rxok; unsigned long rxframgment; - unsigned long rxcmdpkt[8]; unsigned long rxurberr; unsigned long rxstaterr; unsigned long rxdatacrcerr; -- cgit v0.10.2 From e0e3daddad36f8303ca3bbeab558ced00f4e7d3e Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 16 Apr 2012 16:06:18 -0500 Subject: staging: r8192e: Fix possible error in configuration It is possible to misconfigure a kernel by selecting the rtllib crypto routines without enabling the underlying support from the crypto library. Signed-off-by: Larry Finger Acked-by: Sean MacLennan Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192e/Kconfig b/drivers/staging/rtl8192e/Kconfig index f87e211..4602a47 100644 --- a/drivers/staging/rtl8192e/Kconfig +++ b/drivers/staging/rtl8192e/Kconfig @@ -14,6 +14,7 @@ if RTLLIB config RTLLIB_CRYPTO_CCMP tristate "Support for rtllib CCMP crypto" depends on RTLLIB + select CRYPTO_AES default y ---help--- CCMP crypto driver for rtllib. @@ -23,6 +24,8 @@ config RTLLIB_CRYPTO_CCMP config RTLLIB_CRYPTO_TKIP tristate "Support for rtllib TKIP crypto" depends on RTLLIB + select CRYPTO_ARC4 + select CRYPTO_MICHAEL_MIC default y ---help--- TKIP crypto driver for rtllib. @@ -31,6 +34,7 @@ config RTLLIB_CRYPTO_TKIP config RTLLIB_CRYPTO_WEP tristate "Support for rtllib WEP crypto" + select CRYPTO_ARC4 depends on RTLLIB default y ---help--- -- cgit v0.10.2 From 1ae5062a33be13a72d37ec46808490d471b0c1d3 Mon Sep 17 00:00:00 2001 From: Benedikt Bergenthal Date: Mon, 16 Apr 2012 12:40:22 +0200 Subject: Drivers: Staging: Comedi: comedi_fops: Fixed a code style issue Fixed a code style issue. Signed-off-by: Benedikt Bergenthal Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 3222ac6..a0861fb 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -1566,7 +1566,7 @@ done: return retval; } -static unsigned int comedi_poll(struct file *file, poll_table * wait) +static unsigned int comedi_poll(struct file *file, poll_table *wait) { unsigned int mask = 0; const unsigned minor = iminor(file->f_dentry->d_inode); -- cgit v0.10.2 From fdf3480032fc900075c4bdb18271150aaa8a53a0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 17 Apr 2012 09:47:25 +0300 Subject: Staging: wlags49_h2: reading past the end of array The original code had some confusion about the dimensions of the array. It should have been an array of 2 element arrays but it was declared as an array of 50 element arrays. The limitter on the outside array should have been ARRAY_SIZE(chan_freq_list) or 26 but instead 50 was used. It meant that we read past the end. It's probably harmless but it's obviously worth fixing. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlags49_h2/wl_util.c b/drivers/staging/wlags49_h2/wl_util.c index f104e6f..404ec7d 100644 --- a/drivers/staging/wlags49_h2/wl_util.c +++ b/drivers/staging/wlags49_h2/wl_util.c @@ -98,8 +98,7 @@ ******************************************************************************/ /* A matrix which maps channels to frequencies */ -#define MAX_CHAN_FREQ_MAP_ENTRIES 50 -static const long chan_freq_list[][MAX_CHAN_FREQ_MAP_ENTRIES] = +static const long chan_freq_list[][2] = { {1,2412}, {2,2417}, @@ -846,7 +845,7 @@ int wl_is_a_valid_chan( int channel ) } /* Iterate through the matrix and retrieve the frequency */ - for( i = 0; i < MAX_CHAN_FREQ_MAP_ENTRIES; i++ ) { + for( i = 0; i < ARRAY_SIZE(chan_freq_list); i++ ) { if( chan_freq_list[i][0] == channel ) { return 1; } @@ -884,7 +883,7 @@ int wl_is_a_valid_freq( long frequency ) /* Iterate through the matrix and retrieve the channel */ - for( i = 0; i < MAX_CHAN_FREQ_MAP_ENTRIES; i++ ) { + for( i = 0; i < ARRAY_SIZE(chan_freq_list); i++ ) { if( chan_freq_list[i][1] == frequency ) { return 1; } @@ -927,7 +926,7 @@ long wl_get_freq_from_chan( int channel ) } /* Iterate through the matrix and retrieve the frequency */ - for( i = 0; i < MAX_CHAN_FREQ_MAP_ENTRIES; i++ ) { + for( i = 0; i < ARRAY_SIZE(chan_freq_list); i++ ) { if( chan_freq_list[i][0] == channel ) { return chan_freq_list[i][1]; } @@ -965,7 +964,7 @@ int wl_get_chan_from_freq( long frequency ) /* Iterate through the matrix and retrieve the channel */ - for( i = 0; i < MAX_CHAN_FREQ_MAP_ENTRIES; i++ ) { + for( i = 0; i < ARRAY_SIZE(chan_freq_list); i++ ) { if( chan_freq_list[i][1] == frequency ) { return chan_freq_list[i][0]; } -- cgit v0.10.2 From 51d7ff0215631bf9ffa148c9335aef391a277b84 Mon Sep 17 00:00:00 2001 From: Marcos Paulo de Souza Date: Wed, 18 Apr 2012 01:30:12 -0300 Subject: drivers: staging: vme: devices: Remove unneeded include version.h The output of "make versioncheck" told us that: drivers/staging/vme/devices/vme_pio2_core.c: 13 linux/version.h not needed. drivers/staging/vme/devices/vme_pio2_gpio.c: 13 linux/version.h not needed. If we take a look at these files, we will agree to remove it. Cc: Greg Kroah-Hartman Cc: Signed-off-by: Marcos Paulo de Souza Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vme/devices/vme_pio2_core.c b/drivers/staging/vme/devices/vme_pio2_core.c index 9fedc44..d476b2e 100644 --- a/drivers/staging/vme/devices/vme_pio2_core.c +++ b/drivers/staging/vme/devices/vme_pio2_core.c @@ -10,7 +10,6 @@ * option) any later version. */ -#include #include #include #include diff --git a/drivers/staging/vme/devices/vme_pio2_gpio.c b/drivers/staging/vme/devices/vme_pio2_gpio.c index c766d39..9c459c1 100644 --- a/drivers/staging/vme/devices/vme_pio2_gpio.c +++ b/drivers/staging/vme/devices/vme_pio2_gpio.c @@ -10,7 +10,6 @@ * option) any later version. */ -#include #include #include #include -- cgit v0.10.2 From 365d47a1ea7297c37d1d707c25e3203cd51ebb15 Mon Sep 17 00:00:00 2001 From: Marcos Paulo de Souza Date: Wed, 18 Apr 2012 01:30:10 -0300 Subject: drivers: staging: media: easycap: easycap_ioctl: Include version.h header The output of "make versioncheck" told us that: drivers/staging/media/easycap/easycap_ioctl.c: 2442: need linux/version.h If we take a look at the code, we will see the macro KERNEL_VERSION be used. So, we need this include. Cc: Mauro Carvalho Chehab Cc: Greg Kroah-Hartman Cc: Cc: Signed-off-by: Marcos Paulo de Souza Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/media/easycap/easycap_ioctl.c b/drivers/staging/media/easycap/easycap_ioctl.c index 9413b37..3cee3cd 100644 --- a/drivers/staging/media/easycap/easycap_ioctl.c +++ b/drivers/staging/media/easycap/easycap_ioctl.c @@ -26,6 +26,7 @@ /*****************************************************************************/ #include "easycap.h" +#include /*--------------------------------------------------------------------------*/ /* -- cgit v0.10.2 From 72b9b8c847c3590172a8caa718582370f8925137 Mon Sep 17 00:00:00 2001 From: Marcos Paulo de Souza Date: Wed, 18 Apr 2012 01:30:09 -0300 Subject: drivers: staging: media: as102: as102_usb_drv.h: Remove include of version.h The output of "make versioncheck" told us that: drivers/staging/media/as102/as102_usb_drv.h: 20 linux/version.h not needed. If we take a look at the code, we can agree to remove it. Cc: Mauro Carvalho Chehab Cc: Greg Kroah-Hartman Cc: Cc: Signed-off-by: Marcos Paulo de Souza Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/media/as102/as102_usb_drv.h b/drivers/staging/media/as102/as102_usb_drv.h index fc2884a..1ad1ec5 100644 --- a/drivers/staging/media/as102/as102_usb_drv.h +++ b/drivers/staging/media/as102/as102_usb_drv.h @@ -17,8 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include - #ifndef _AS102_USB_DRV_H_ #define _AS102_USB_DRV_H_ -- cgit v0.10.2 From 0d19cd36a5727962b3c000270857d4bf63522d63 Mon Sep 17 00:00:00 2001 From: Marcos Paulo de Souza Date: Wed, 18 Apr 2012 01:30:08 -0300 Subject: drivers: staging: media: as102: as102fe.c: Remove include of version.h The output of "make versioncheck" told us that: drivers/staging/media/as102/as102_fe.c: 20 linux/version.h not needed. If we take a look at the code, we can agree to remove this include. Cc: Mauro Carvalho Chehab Cc: Greg Kroah-Hartman Cc: Cc: Signed-off-by: Marcos Paulo de Souza Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/media/as102/as102_fe.c b/drivers/staging/media/as102/as102_fe.c index 5917657..9ce8c9d 100644 --- a/drivers/staging/media/as102/as102_fe.c +++ b/drivers/staging/media/as102/as102_fe.c @@ -17,8 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include - #include "as102_drv.h" #include "as10x_types.h" #include "as10x_cmd.h" -- cgit v0.10.2 From bb46f130a033ed812ccc24f5fd4f34648650d240 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 18 Apr 2012 09:48:59 +0300 Subject: Staging: wlan-ng: off by one in prism2mgmt_scan_results() Count is used to cap "req->bssindex.data" which is used as an offset into the hw->scanresults->info.hscanresult.result[] array. The array has only HFA384x_SCANRESULT_MAX (31) elements so the 32 is off by one. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c index c3bb05d..4efa9bc 100644 --- a/drivers/staging/wlan-ng/prism2mgmt.c +++ b/drivers/staging/wlan-ng/prism2mgmt.c @@ -380,8 +380,8 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp) } count = (hw->scanresults->framelen - 3) / 32; - if (count > 32) - count = 32; + if (count > HFA384x_SCANRESULT_MAX) + count = HFA384x_SCANRESULT_MAX; if (req->bssindex.data >= count) { pr_debug("requested index (%d) out of range (%d)\n", -- cgit v0.10.2 From b0d5c7988461e531b25d484438fd7c52cf1c3f45 Mon Sep 17 00:00:00 2001 From: Marcos Paulo de Souza Date: Wed, 18 Apr 2012 01:30:11 -0300 Subject: drivers: staging: rtl8172: Remove unneeded include of version.h The output of "make versioncheck" told us that: drivers/staging/rtl8712/osdep_service.h: 32 linux/version.h not needed. drivers/staging/rtl8712/rtl871x_ioctl_linux.c: 46 linux/version.h not needed. If we take a look at these files, we will agree to remove it. Cc: Larry Finger Cc: Florian Schilhabel Cc: Signed-off-by: Marcos Paulo de Souza ACKed-by: Larry Finger Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h index 9ba6033..cabf774 100644 --- a/drivers/staging/rtl8712/osdep_service.h +++ b/drivers/staging/rtl8712/osdep_service.h @@ -29,7 +29,6 @@ #define _SUCCESS 1 #define _FAIL 0 -#include #include #include diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index 299350c..3b23bef 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include -- cgit v0.10.2 From 35c81aaa56e3e1a8eb8f86837889ed979085b1bc Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Wed, 18 Apr 2012 21:30:27 -0400 Subject: staging: comedi: ni_tio_internal.h: checkpatch.pl line wrapping Signed-off-by: W. Trevor King Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h index c4ca537..f9295ec 100644 --- a/drivers/staging/comedi/drivers/ni_tio_internal.h +++ b/drivers/staging/comedi/drivers/ni_tio_internal.h @@ -362,8 +362,8 @@ static inline enum ni_gpct_register NITIO_Gi_ABZ_Reg(int counter_index) return 0; } -static inline enum ni_gpct_register NITIO_Gi_Interrupt_Acknowledge_Reg(int - counter_index) +static inline enum ni_gpct_register NITIO_Gi_Interrupt_Acknowledge_Reg( + int counter_index) { switch (counter_index) { case 0: @@ -407,8 +407,8 @@ static inline enum ni_gpct_register NITIO_Gi_Status_Reg(int counter_index) return 0; } -static inline enum ni_gpct_register NITIO_Gi_Interrupt_Enable_Reg(int - counter_index) +static inline enum ni_gpct_register NITIO_Gi_Interrupt_Enable_Reg( + int counter_index) { switch (counter_index) { case 0: @@ -472,15 +472,22 @@ enum Gi_Counting_Mode_Reg_Bits { Gi_Index_Phase_LowA_HighB = 0x1 << Gi_Index_Phase_Bitshift, Gi_Index_Phase_HighA_LowB = 0x2 << Gi_Index_Phase_Bitshift, Gi_Index_Phase_HighA_HighB = 0x3 << Gi_Index_Phase_Bitshift, - Gi_HW_Arm_Enable_Bit = 0x80, /* from m-series example code, not documented in 660x register level manual */ - Gi_660x_HW_Arm_Select_Mask = 0x7 << Gi_HW_Arm_Select_Shift, /* from m-series example code, not documented in 660x register level manual */ + /* from m-series example code, not documented in 660x register level + * manual */ + Gi_HW_Arm_Enable_Bit = 0x80, + /* from m-series example code, not documented in 660x register level + * manual */ + Gi_660x_HW_Arm_Select_Mask = 0x7 << Gi_HW_Arm_Select_Shift, Gi_660x_Prescale_X8_Bit = 0x1000, Gi_M_Series_Prescale_X8_Bit = 0x2000, Gi_M_Series_HW_Arm_Select_Mask = 0x1f << Gi_HW_Arm_Select_Shift, - /* must be set for clocks over 40MHz, which includes synchronous counting and quadrature modes */ + /* must be set for clocks over 40MHz, which includes synchronous + * counting and quadrature modes */ Gi_660x_Alternate_Sync_Bit = 0x2000, Gi_M_Series_Alternate_Sync_Bit = 0x4000, - Gi_660x_Prescale_X2_Bit = 0x4000, /* from m-series example code, not documented in 660x register level manual */ + /* from m-series example code, not documented in 660x register level + * manual */ + Gi_660x_Prescale_X2_Bit = 0x4000, Gi_M_Series_Prescale_X2_Bit = 0x8000, }; @@ -503,7 +510,8 @@ enum Gi_Mode_Bits { Gi_Level_Gating_Bits = 0x1, Gi_Rising_Edge_Gating_Bits = 0x2, Gi_Falling_Edge_Gating_Bits = 0x3, - Gi_Gate_On_Both_Edges_Bit = 0x4, /* used in conjunction with rising edge gating mode */ + Gi_Gate_On_Both_Edges_Bit = 0x4, /* used in conjunction with + * rising edge gating mode */ Gi_Trigger_Mode_for_Edge_Gate_Mask = 0x18, Gi_Edge_Gate_Starts_Stops_Bits = 0x0, Gi_Edge_Gate_Stops_Starts_Bits = 0x8, @@ -748,8 +756,9 @@ static inline void ni_tio_set_bits_transient(struct ni_gpct *counter, } /* ni_tio_set_bits( ) is for safely writing to registers whose bits may be -twiddled in interrupt context, or whose software copy may be read in interrupt context. -*/ + * twiddled in interrupt context, or whose software copy may be read in + * interrupt context. + */ static inline void ni_tio_set_bits(struct ni_gpct *counter, enum ni_gpct_register register_index, unsigned bit_mask, unsigned bit_values) -- cgit v0.10.2 From 933df6599382aa41742210e4008ec550076254ee Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Wed, 18 Apr 2012 21:30:28 -0400 Subject: staging: comedi: ni_tio_internal.h: checkpatch.pl cleanups * No braces for single statement blocks. Signed-off-by: W. Trevor King Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h index f9295ec..5e00212 100644 --- a/drivers/staging/comedi/drivers/ni_tio_internal.h +++ b/drivers/staging/comedi/drivers/ni_tio_internal.h @@ -694,11 +694,10 @@ static inline unsigned Gi_Gate_Interrupt_Enable_Bit(unsigned counter_index) { unsigned bit; - if (counter_index % 2) { + if (counter_index % 2) bit = G1_Gate_Interrupt_Enable_Bit; - } else { + else bit = G0_Gate_Interrupt_Enable_Bit; - } return bit; } -- cgit v0.10.2 From b9a62c650b41365cd1f6214496bc91f152c723a4 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Thu, 19 Apr 2012 14:29:34 +0530 Subject: staging: iio: light: convert multiple spaces to tab Using tab inplace of multiple spaces for indenting. Signed-off-by: Laxman Dewangan Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/light/Kconfig b/drivers/staging/iio/light/Kconfig index 53b49f7..bb633f6 100644 --- a/drivers/staging/iio/light/Kconfig +++ b/drivers/staging/iio/light/Kconfig @@ -4,15 +4,15 @@ menu "Light sensors" config SENSORS_ISL29018 - tristate "ISL 29018 light and proximity sensor" - depends on I2C - default n - help - If you say yes here you get support for ambient light sensing and - proximity infrared sensing from Intersil ISL29018. - This driver will provide the measurements of ambient light intensity - in lux, proximity infrared sensing and normal infrared sensing. - Data from sensor is accessible via sysfs. + tristate "ISL 29018 light and proximity sensor" + depends on I2C + default n + help + If you say yes here you get support for ambient light sensing and + proximity infrared sensing from Intersil ISL29018. + This driver will provide the measurements of ambient light intensity + in lux, proximity infrared sensing and normal infrared sensing. + Data from sensor is accessible via sysfs. config SENSORS_ISL29028 tristate "Intersil ISL29028 Concurrent Light and Proximity Sensor" -- cgit v0.10.2 From 3fb95e564e535a1614f7cea1ac194f312eb0d2b8 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 19 Apr 2012 13:03:58 +0200 Subject: drivers/staging/wlags49_h2/wl_pci.c: add missing wl_device_dealloc and wl_remove The need for wl_device_dealloc is motivated by the error-handling code for the failure of wl_adapter_insert. The need for wl_remove in the third case is motivated by the code in the definition of wl_pci_remove. Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlags49_h2/wl_pci.c b/drivers/staging/wlags49_h2/wl_pci.c index 3df990c..0b31b01 100644 --- a/drivers/staging/wlags49_h2/wl_pci.c +++ b/drivers/staging/wlags49_h2/wl_pci.c @@ -524,6 +524,7 @@ int wl_pci_setup( struct pci_dev *pdev ) /* Make sure that space was allocated for our private adapter struct */ if( dev->priv == NULL ) { DBG_ERROR( DbgInfo, "Private adapter struct was not allocated!!!\n" ); + wl_device_dealloc(dev); DBG_LEAVE( DbgInfo ); return -ENOMEM; } @@ -532,6 +533,7 @@ int wl_pci_setup( struct pci_dev *pdev ) /* Allocate DMA Descriptors */ if( wl_pci_dma_alloc( pdev, dev->priv ) < 0 ) { DBG_ERROR( DbgInfo, "Could not allocate DMA descriptor memory!!!\n" ); + wl_device_dealloc(dev); DBG_LEAVE( DbgInfo ); return -ENOMEM; } @@ -561,6 +563,8 @@ int wl_pci_setup( struct pci_dev *pdev ) result = request_irq(dev->irq, wl_isr, SA_SHIRQ, dev->name, dev); if( result ) { DBG_WARNING( DbgInfo, "Could not register ISR!!!\n" ); + wl_remove(dev); + wl_device_dealloc(dev); DBG_LEAVE( DbgInfo ); return result; } -- cgit v0.10.2 From 8f9064a8a3b9f0dfd53bb0dfb3bbbfb457dda4bb Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 20 Apr 2012 14:46:27 +0300 Subject: staging: comedi vmk80xx: lock held on error path If the user passes an invalid command, then we don't drop the lock before returning. The check for invalid commands doesn't need to be done under lock so I moved it forward a couple lines. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index 10ac58d..856d0ea 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -1020,12 +1020,12 @@ static int vmk80xx_cnt_cinsn(struct comedi_device *cdev, if (n) return n; - down(&dev->limit_sem); - insn_cmd = data[0]; if (insn_cmd != INSN_CONFIG_RESET && insn_cmd != GPCT_RESET) return -EINVAL; + down(&dev->limit_sem); + chan = CR_CHAN(insn->chanspec); if (dev->board.model == VMK8055_MODEL) { -- cgit v0.10.2 From e2d8ccef0a8e8aedaf401edca6ad54663b0da24b Mon Sep 17 00:00:00 2001 From: John Stultz Date: Fri, 20 Apr 2012 12:31:44 -0700 Subject: staging: android-alarm: Convert ALARM_ELAPSED_REALTIME to use CLOCK_BOOTTIME The ALARM_ELAPSED_REALTIME clock domain in Android pointed to the need for something similar in linux system-wide (instead of limited to just the alarm interface). Thus CLOCK_BOOTTIME was introduced into the upstream kernel in 2.6.39. This patch attempts to convert the android alarm timer to utilize the kernel's CLOCK_BOOTTIME clockid for ALARM_ELAPSED_REALTIME, instead of managing it itself. CC: Colin Cross CC: Thomas Gleixner CC: Android Kernel Team Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c index 1b618f3..3840ca2 100644 --- a/drivers/staging/android/alarm-dev.c +++ b/drivers/staging/android/alarm-dev.c @@ -179,8 +179,7 @@ from_old_alarm_set: break; case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: case ANDROID_ALARM_ELAPSED_REALTIME: - tmp_time = - ktime_to_timespec(alarm_get_elapsed_realtime()); + get_monotonic_boottime(&tmp_time); break; case ANDROID_ALARM_TYPE_COUNT: case ANDROID_ALARM_SYSTEMTIME: diff --git a/drivers/staging/android/alarm.c b/drivers/staging/android/alarm.c index 0cae132..22b18d1 100644 --- a/drivers/staging/android/alarm.c +++ b/drivers/staging/android/alarm.c @@ -65,7 +65,6 @@ struct alarm_queue { struct rb_root alarms; struct rb_node *first; struct hrtimer timer; - ktime_t delta; bool stopped; ktime_t stopped_time; }; @@ -107,8 +106,8 @@ static void update_timer_locked(struct alarm_queue *base, bool head_removed) } hrtimer_try_to_cancel(&base->timer); - base->timer.node.expires = ktime_add(base->delta, alarm->expires); - base->timer._softexpires = ktime_add(base->delta, alarm->softexpires); + base->timer.node.expires = alarm->expires; + base->timer._softexpires = alarm->softexpires; hrtimer_start_expires(&base->timer, HRTIMER_MODE_ABS); } @@ -279,10 +278,6 @@ int android_alarm_set_rtc(struct timespec new_time) alarms[i].stopped = true; alarms[i].stopped_time = timespec_to_ktime(tmp_time); } - alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].delta = - alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta = - ktime_sub(alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta, - timespec_to_ktime(timespec_sub(tmp_time, new_time))); spin_unlock_irqrestore(&alarm_slock, flags); ret = do_settimeofday(&new_time); spin_lock_irqsave(&alarm_slock, flags); @@ -310,24 +305,6 @@ err: return ret; } -/** - * alarm_get_elapsed_realtime - get the elapsed real time in ktime_t format - * - * returns the time in ktime_t format - */ -ktime_t alarm_get_elapsed_realtime(void) -{ - ktime_t now; - unsigned long flags; - struct alarm_queue *base = &alarms[ANDROID_ALARM_ELAPSED_REALTIME]; - - spin_lock_irqsave(&alarm_slock, flags); - now = base->stopped ? base->stopped_time : ktime_get_real(); - now = ktime_sub(now, base->delta); - spin_unlock_irqrestore(&alarm_slock, flags); - return now; -} - static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer) { struct alarm_queue *base; @@ -339,7 +316,6 @@ static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer) base = container_of(timer, struct alarm_queue, timer); now = base->stopped ? base->stopped_time : hrtimer_cb_get_time(timer); - now = ktime_sub(now, base->delta); pr_alarm(INT, "alarm_timer_triggered type %td at %lld\n", base - alarms, ktime_to_ns(now)); @@ -536,40 +512,25 @@ static struct platform_driver alarm_driver = { } }; -static int __init alarm_late_init(void) -{ - unsigned long flags; - struct timespec tmp_time, system_time; - - /* this needs to run after the rtc is read at boot */ - spin_lock_irqsave(&alarm_slock, flags); - /* We read the current rtc and system time so we can later calculate - * elasped realtime to be (boot_systemtime + rtc - boot_rtc) == - * (rtc - (boot_rtc - boot_systemtime)) - */ - getnstimeofday(&tmp_time); - ktime_get_ts(&system_time); - alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].delta = - alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta = - timespec_to_ktime(timespec_sub(tmp_time, system_time)); - - spin_unlock_irqrestore(&alarm_slock, flags); - return 0; -} - static int __init alarm_driver_init(void) { int err; int i; - for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { - hrtimer_init(&alarms[i].timer, - CLOCK_REALTIME, HRTIMER_MODE_ABS); - alarms[i].timer.function = alarm_timer_triggered; - } + hrtimer_init(&alarms[ANDROID_ALARM_RTC_WAKEUP].timer, + CLOCK_REALTIME, HRTIMER_MODE_ABS); + hrtimer_init(&alarms[ANDROID_ALARM_RTC].timer, + CLOCK_REALTIME, HRTIMER_MODE_ABS); + hrtimer_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].timer, + CLOCK_BOOTTIME, HRTIMER_MODE_ABS); + hrtimer_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME].timer, + CLOCK_BOOTTIME, HRTIMER_MODE_ABS); hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].timer, - CLOCK_MONOTONIC, HRTIMER_MODE_ABS); - alarms[ANDROID_ALARM_SYSTEMTIME].timer.function = alarm_timer_triggered; + CLOCK_MONOTONIC, HRTIMER_MODE_ABS); + + for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) + alarms[i].timer.function = alarm_timer_triggered; + err = platform_driver_register(&alarm_driver); if (err < 0) goto err1; @@ -595,7 +556,6 @@ static void __exit alarm_exit(void) platform_driver_unregister(&alarm_driver); } -late_initcall(alarm_late_init); module_init(alarm_driver_init); module_exit(alarm_exit); diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h index e586cae..a112177 100644 --- a/drivers/staging/android/android_alarm.h +++ b/drivers/staging/android/android_alarm.h @@ -37,6 +37,7 @@ enum android_alarm_type { #include #include +#include /* * The alarm interface is similar to the hrtimer interface but adds support @@ -71,7 +72,11 @@ void android_alarm_start_range(struct android_alarm *alarm, ktime_t start, ktime_t end); int android_alarm_try_to_cancel(struct android_alarm *alarm); int android_alarm_cancel(struct android_alarm *alarm); -ktime_t alarm_get_elapsed_realtime(void); + +static inline ktime_t alarm_get_elapsed_realtime(void) +{ + return ktime_get_boottime(); +} /* set rtc while preserving elapsed realtime */ int android_alarm_set_rtc(const struct timespec ts); -- cgit v0.10.2 From 57c498fa5df05e4bd410c101795368439fec7b4e Mon Sep 17 00:00:00 2001 From: John Stultz Date: Fri, 20 Apr 2012 12:31:45 -0700 Subject: alarmtimer: Provide accessor to alarmtimer rtc device The Android alarm interface provides a settime call that sets both the alarmtimer RTC device and CLOCK_REALTIME to the same value. Since there may be multiple rtc devices, provide a hook to access the one the alarmtimer infrastructure is using. CC: Colin Cross CC: Thomas Gleixner CC: Android Kernel Team Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman diff --git a/include/linux/alarmtimer.h b/include/linux/alarmtimer.h index 975009e..96c5c24 100644 --- a/include/linux/alarmtimer.h +++ b/include/linux/alarmtimer.h @@ -76,4 +76,7 @@ static inline int alarmtimer_callback_running(struct alarm *timer) } +/* Provide way to access the rtc device being used by alarmtimers */ +struct rtc_device *alarmtimer_get_rtcdev(void); + #endif diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 8a538c5..aa27d39 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -59,7 +59,7 @@ static DEFINE_SPINLOCK(rtcdev_lock); * If one has not already been chosen, it checks to see if a * functional rtc device is available. */ -static struct rtc_device *alarmtimer_get_rtcdev(void) +struct rtc_device *alarmtimer_get_rtcdev(void) { unsigned long flags; struct rtc_device *ret; @@ -115,7 +115,7 @@ static void alarmtimer_rtc_interface_remove(void) class_interface_unregister(&alarmtimer_rtc_interface); } #else -static inline struct rtc_device *alarmtimer_get_rtcdev(void) +struct rtc_device *alarmtimer_get_rtcdev(void) { return NULL; } -- cgit v0.10.2 From b8793260980b0fc356af3bf11abea82650b0d595 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Fri, 20 Apr 2012 12:31:46 -0700 Subject: staging: android-alarm: Rework alarm-dev.c to use upstreamed alarmtimers This reworks the alarm-dev.c to use the upstreamed alarmtimers interface. CC: Colin Cross CC: Thomas Gleixner CC: Android Kernel Team Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c index 3840ca2..04075b3 100644 --- a/drivers/staging/android/alarm-dev.c +++ b/drivers/staging/android/alarm-dev.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "android_alarm.h" /* XXX - Hack out wakelocks, while they are out of tree */ @@ -66,7 +67,53 @@ static uint32_t alarm_pending; static uint32_t alarm_enabled; static uint32_t wait_pending; -static struct android_alarm alarms[ANDROID_ALARM_TYPE_COUNT]; +struct devalarm { + union { + struct hrtimer hrt; + struct alarm alrm; + } u; + enum android_alarm_type type; +}; + +static struct devalarm alarms[ANDROID_ALARM_TYPE_COUNT]; + + +static int is_wakeup(enum android_alarm_type type) +{ + if (type == ANDROID_ALARM_RTC_WAKEUP || + type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP) + return 1; + return 0; +} + + +static void devalarm_start(struct devalarm *alrm, ktime_t exp) +{ + if (is_wakeup(alrm->type)) + alarm_start(&alrm->u.alrm, exp); + else + hrtimer_start(&alrm->u.hrt, exp, HRTIMER_MODE_ABS); +} + + +static int devalarm_try_to_cancel(struct devalarm *alrm) +{ + int ret; + if (is_wakeup(alrm->type)) + ret = alarm_try_to_cancel(&alrm->u.alrm); + else + ret = hrtimer_try_to_cancel(&alrm->u.hrt); + return ret; +} + +static void devalarm_cancel(struct devalarm *alrm) +{ + if (is_wakeup(alrm->type)) + alarm_cancel(&alrm->u.alrm); + else + hrtimer_cancel(&alrm->u.hrt); +} + static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -75,6 +122,8 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) struct timespec new_alarm_time; struct timespec new_rtc_time; struct timespec tmp_time; + struct rtc_time new_rtc_tm; + struct rtc_device *rtc_dev; enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); uint32_t alarm_type_mask = 1U << alarm_type; @@ -101,7 +150,7 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case ANDROID_ALARM_CLEAR(0): spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d clear\n", alarm_type); - android_alarm_try_to_cancel(&alarms[alarm_type]); + devalarm_try_to_cancel(&alarms[alarm_type]); if (alarm_pending) { alarm_pending &= ~alarm_type_mask; if (!alarm_pending && !wait_pending) @@ -132,8 +181,7 @@ from_old_alarm_set: pr_alarm(IO, "alarm %d set %ld.%09ld\n", alarm_type, new_alarm_time.tv_sec, new_alarm_time.tv_nsec); alarm_enabled |= alarm_type_mask; - android_alarm_start_range(&alarms[alarm_type], - timespec_to_ktime(new_alarm_time), + devalarm_start(&alarms[alarm_type], timespec_to_ktime(new_alarm_time)); spin_unlock_irqrestore(&alarm_slock, flags); if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0) @@ -163,7 +211,13 @@ from_old_alarm_set: rv = -EFAULT; goto err1; } - rv = android_alarm_set_rtc(new_rtc_time); + rtc_time_to_tm(new_rtc_time.tv_sec, &new_rtc_tm); + rtc_dev = alarmtimer_get_rtcdev(); + rv = do_settimeofday(&new_rtc_time); + if (rv < 0) + goto err1; + if (rtc_dev) + rv = rtc_set_time(rtc_dev, &new_rtc_tm); spin_lock_irqsave(&alarm_slock, flags); alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; wake_up(&alarm_wait_queue); @@ -223,7 +277,7 @@ static int alarm_release(struct inode *inode, struct file *file) alarm_enabled &= ~alarm_type_mask; } spin_unlock_irqrestore(&alarm_slock, flags); - android_alarm_cancel(&alarms[i]); + devalarm_cancel(&alarms[i]); spin_lock_irqsave(&alarm_slock, flags); } if (alarm_pending | wait_pending) { @@ -240,12 +294,12 @@ static int alarm_release(struct inode *inode, struct file *file) return 0; } -static void alarm_triggered(struct android_alarm *alarm) +static void devalarm_triggered(struct devalarm *alarm) { unsigned long flags; uint32_t alarm_type_mask = 1U << alarm->type; - pr_alarm(INT, "alarm_triggered type %d\n", alarm->type); + pr_alarm(INT, "devalarm_triggered type %d\n", alarm->type); spin_lock_irqsave(&alarm_slock, flags); if (alarm_enabled & alarm_type_mask) { wake_lock_timeout(&alarm_wake_lock, 5 * HZ); @@ -256,6 +310,25 @@ static void alarm_triggered(struct android_alarm *alarm) spin_unlock_irqrestore(&alarm_slock, flags); } + +static enum hrtimer_restart devalarm_hrthandler(struct hrtimer *hrt) +{ + struct devalarm *devalrm = container_of(hrt, struct devalarm, u.hrt); + + devalarm_triggered(devalrm); + return HRTIMER_NORESTART; +} + +static enum alarmtimer_restart devalarm_alarmhandler(struct alarm *alrm, + ktime_t now) +{ + struct devalarm *devalrm = container_of(alrm, struct devalarm, u.alrm); + + devalarm_triggered(devalrm); + return ALARMTIMER_NORESTART; +} + + static const struct file_operations alarm_fops = { .owner = THIS_MODULE, .unlocked_ioctl = alarm_ioctl, @@ -278,8 +351,23 @@ static int __init alarm_dev_init(void) if (err) return err; - for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) - android_alarm_init(&alarms[i], i, alarm_triggered); + alarm_init(&alarms[ANDROID_ALARM_RTC_WAKEUP].u.alrm, + ALARM_REALTIME, devalarm_alarmhandler); + hrtimer_init(&alarms[ANDROID_ALARM_RTC].u.hrt, + CLOCK_REALTIME, HRTIMER_MODE_ABS); + alarm_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].u.alrm, + ALARM_BOOTTIME, devalarm_alarmhandler); + hrtimer_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME].u.hrt, + CLOCK_BOOTTIME, HRTIMER_MODE_ABS); + hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].u.hrt, + CLOCK_MONOTONIC, HRTIMER_MODE_ABS); + + for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) { + alarms[i].type = i; + if (!is_wakeup(i)) + alarms[i].u.hrt.function = devalarm_hrthandler; + } + wake_lock_init(&alarm_wake_lock, WAKE_LOCK_SUSPEND, "alarm"); return 0; -- cgit v0.10.2 From ef2353d26bdc44c78713da1a6eb2325ba9dac6f7 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Fri, 20 Apr 2012 12:31:47 -0700 Subject: android-alarm: Remove unused android alarm in-kernel interfaces Now that alarm-dev.c uses the upstreamed alarmtimer interfaces, we can remove the otherwise unused in-kernel android alarm api. CC: Colin Cross CC: Thomas Gleixner CC: Android Kernel Team Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index 08a3b11..84ac619 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -54,31 +54,14 @@ config ANDROID_LOW_MEMORY_KILLER source "drivers/staging/android/switch/Kconfig" -config ANDROID_INTF_ALARM +config ANDROID_INTF_ALARM_DEV bool "Android alarm driver" depends on RTC_CLASS default n help Provides non-wakeup and rtc backed wakeup alarms based on rtc or elapsed realtime, and a non-wakeup alarm on the monotonic clock. - Also provides an interface to set the wall time which must be used - for elapsed realtime to work. - -config ANDROID_INTF_ALARM_DEV - bool "Android alarm device" - depends on ANDROID_INTF_ALARM - default y - help - Exports the alarm interface to user-space. - -config ANDROID_ALARM_OLDDRV_COMPAT - bool "Android Alarm compatability with old drivers" - depends on ANDROID_INTF_ALARM - default n - help - Provides preprocessor alias to aid compatability with - older out-of-tree drivers that use the Android Alarm - in-kernel API. This will be removed eventually. + Also exports the alarm interface to user-space. endif # if ANDROID diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile index 9b6c9ed..b4be69f 100644 --- a/drivers/staging/android/Makefile +++ b/drivers/staging/android/Makefile @@ -7,5 +7,4 @@ obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o obj-$(CONFIG_ANDROID_SWITCH) += switch/ -obj-$(CONFIG_ANDROID_INTF_ALARM) += alarm.o obj-$(CONFIG_ANDROID_INTF_ALARM_DEV) += alarm-dev.o diff --git a/drivers/staging/android/alarm.c b/drivers/staging/android/alarm.c deleted file mode 100644 index 22b18d1..0000000 --- a/drivers/staging/android/alarm.c +++ /dev/null @@ -1,561 +0,0 @@ -/* drivers/rtc/alarm.c - * - * Copyright (C) 2007-2009 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "android_alarm.h" - -/* XXX - Hack out wakelocks, while they are out of tree */ -struct wake_lock { - int i; -}; -#define wake_lock(x) -#define wake_lock_timeout(x, y) -#define wake_unlock(x) -#define WAKE_LOCK_SUSPEND 0 -#define wake_lock_init(x, y, z) ((x)->i = 1) -#define wake_lock_destroy(x) - -#define ANDROID_ALARM_PRINT_ERROR (1U << 0) -#define ANDROID_ALARM_PRINT_INIT_STATUS (1U << 1) -#define ANDROID_ALARM_PRINT_TSET (1U << 2) -#define ANDROID_ALARM_PRINT_CALL (1U << 3) -#define ANDROID_ALARM_PRINT_SUSPEND (1U << 4) -#define ANDROID_ALARM_PRINT_INT (1U << 5) -#define ANDROID_ALARM_PRINT_FLOW (1U << 6) - -static int debug_mask = ANDROID_ALARM_PRINT_ERROR | \ - ANDROID_ALARM_PRINT_INIT_STATUS; -module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); - -#define pr_alarm(debug_level_mask, args...) \ - do { \ - if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask) { \ - pr_info(args); \ - } \ - } while (0) - -#define ANDROID_ALARM_WAKEUP_MASK ( \ - ANDROID_ALARM_RTC_WAKEUP_MASK | \ - ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK) - -/* support old userspace code */ -#define ANDROID_ALARM_SET_OLD _IOW('a', 2, time_t) /* set alarm */ -#define ANDROID_ALARM_SET_AND_WAIT_OLD _IOW('a', 3, time_t) - -struct alarm_queue { - struct rb_root alarms; - struct rb_node *first; - struct hrtimer timer; - bool stopped; - ktime_t stopped_time; -}; - -static struct rtc_device *alarm_rtc_dev; -static DEFINE_SPINLOCK(alarm_slock); -static DEFINE_MUTEX(alarm_setrtc_mutex); -static struct wake_lock alarm_rtc_wake_lock; -static struct platform_device *alarm_platform_dev; -struct alarm_queue alarms[ANDROID_ALARM_TYPE_COUNT]; -static bool suspended; - -static void update_timer_locked(struct alarm_queue *base, bool head_removed) -{ - struct android_alarm *alarm; - bool is_wakeup = base == &alarms[ANDROID_ALARM_RTC_WAKEUP] || - base == &alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP]; - - if (base->stopped) { - pr_alarm(FLOW, "changed alarm while setting the wall time\n"); - return; - } - - if (is_wakeup && !suspended && head_removed) - wake_unlock(&alarm_rtc_wake_lock); - - if (!base->first) - return; - - alarm = container_of(base->first, struct android_alarm, node); - - pr_alarm(FLOW, "selected alarm, type %d, func %pF at %lld\n", - alarm->type, alarm->function, ktime_to_ns(alarm->expires)); - - if (is_wakeup && suspended) { - pr_alarm(FLOW, "changed alarm while suspened\n"); - wake_lock_timeout(&alarm_rtc_wake_lock, 1 * HZ); - return; - } - - hrtimer_try_to_cancel(&base->timer); - base->timer.node.expires = alarm->expires; - base->timer._softexpires = alarm->softexpires; - hrtimer_start_expires(&base->timer, HRTIMER_MODE_ABS); -} - -static void alarm_enqueue_locked(struct android_alarm *alarm) -{ - struct alarm_queue *base = &alarms[alarm->type]; - struct rb_node **link = &base->alarms.rb_node; - struct rb_node *parent = NULL; - struct android_alarm *entry; - int leftmost = 1; - bool was_first = false; - - pr_alarm(FLOW, "added alarm, type %d, func %pF at %lld\n", - alarm->type, alarm->function, ktime_to_ns(alarm->expires)); - - if (base->first == &alarm->node) { - base->first = rb_next(&alarm->node); - was_first = true; - } - if (!RB_EMPTY_NODE(&alarm->node)) { - rb_erase(&alarm->node, &base->alarms); - RB_CLEAR_NODE(&alarm->node); - } - - while (*link) { - parent = *link; - entry = rb_entry(parent, struct android_alarm, node); - /* - * We dont care about collisions. Nodes with - * the same expiry time stay together. - */ - if (alarm->expires.tv64 < entry->expires.tv64) { - link = &(*link)->rb_left; - } else { - link = &(*link)->rb_right; - leftmost = 0; - } - } - if (leftmost) - base->first = &alarm->node; - if (leftmost || was_first) - update_timer_locked(base, was_first); - - rb_link_node(&alarm->node, parent, link); - rb_insert_color(&alarm->node, &base->alarms); -} - -/** - * android_alarm_init - initialize an alarm - * @alarm: the alarm to be initialized - * @type: the alarm type to be used - * @function: alarm callback function - */ -void android_alarm_init(struct android_alarm *alarm, - enum android_alarm_type type, void (*function)(struct android_alarm *)) -{ - RB_CLEAR_NODE(&alarm->node); - alarm->type = type; - alarm->function = function; - - pr_alarm(FLOW, "created alarm, type %d, func %pF\n", type, function); -} - - -/** - * android_alarm_start_range - (re)start an alarm - * @alarm: the alarm to be added - * @start: earliest expiry time - * @end: expiry time - */ -void android_alarm_start_range(struct android_alarm *alarm, ktime_t start, - ktime_t end) -{ - unsigned long flags; - - spin_lock_irqsave(&alarm_slock, flags); - alarm->softexpires = start; - alarm->expires = end; - alarm_enqueue_locked(alarm); - spin_unlock_irqrestore(&alarm_slock, flags); -} - -/** - * android_alarm_try_to_cancel - try to deactivate an alarm - * @alarm: alarm to stop - * - * Returns: - * 0 when the alarm was not active - * 1 when the alarm was active - * -1 when the alarm may currently be excuting the callback function and - * cannot be stopped (it may also be inactive) - */ -int android_alarm_try_to_cancel(struct android_alarm *alarm) -{ - struct alarm_queue *base = &alarms[alarm->type]; - unsigned long flags; - bool first = false; - int ret = 0; - - spin_lock_irqsave(&alarm_slock, flags); - if (!RB_EMPTY_NODE(&alarm->node)) { - pr_alarm(FLOW, "canceled alarm, type %d, func %pF at %lld\n", - alarm->type, alarm->function, - ktime_to_ns(alarm->expires)); - ret = 1; - if (base->first == &alarm->node) { - base->first = rb_next(&alarm->node); - first = true; - } - rb_erase(&alarm->node, &base->alarms); - RB_CLEAR_NODE(&alarm->node); - if (first) - update_timer_locked(base, true); - } else - pr_alarm(FLOW, "tried to cancel alarm, type %d, func %pF\n", - alarm->type, alarm->function); - spin_unlock_irqrestore(&alarm_slock, flags); - if (!ret && hrtimer_callback_running(&base->timer)) - ret = -1; - return ret; -} - -/** - * android_alarm_cancel - cancel an alarm and wait for the handler to finish. - * @alarm: the alarm to be cancelled - * - * Returns: - * 0 when the alarm was not active - * 1 when the alarm was active - */ -int android_alarm_cancel(struct android_alarm *alarm) -{ - for (;;) { - int ret = android_alarm_try_to_cancel(alarm); - if (ret >= 0) - return ret; - cpu_relax(); - } -} - -/** - * alarm_set_rtc - set the kernel and rtc walltime - * @new_time: timespec value containing the new time - */ -int android_alarm_set_rtc(struct timespec new_time) -{ - int i; - int ret; - unsigned long flags; - struct rtc_time rtc_new_rtc_time; - struct timespec tmp_time; - - rtc_time_to_tm(new_time.tv_sec, &rtc_new_rtc_time); - - pr_alarm(TSET, "set rtc %ld %ld - rtc %02d:%02d:%02d %02d/%02d/%04d\n", - new_time.tv_sec, new_time.tv_nsec, - rtc_new_rtc_time.tm_hour, rtc_new_rtc_time.tm_min, - rtc_new_rtc_time.tm_sec, rtc_new_rtc_time.tm_mon + 1, - rtc_new_rtc_time.tm_mday, - rtc_new_rtc_time.tm_year + 1900); - - mutex_lock(&alarm_setrtc_mutex); - spin_lock_irqsave(&alarm_slock, flags); - wake_lock(&alarm_rtc_wake_lock); - getnstimeofday(&tmp_time); - for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { - hrtimer_try_to_cancel(&alarms[i].timer); - alarms[i].stopped = true; - alarms[i].stopped_time = timespec_to_ktime(tmp_time); - } - spin_unlock_irqrestore(&alarm_slock, flags); - ret = do_settimeofday(&new_time); - spin_lock_irqsave(&alarm_slock, flags); - for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { - alarms[i].stopped = false; - update_timer_locked(&alarms[i], false); - } - spin_unlock_irqrestore(&alarm_slock, flags); - if (ret < 0) { - pr_alarm(ERROR, "alarm_set_rtc: Failed to set time\n"); - goto err; - } - if (!alarm_rtc_dev) { - pr_alarm(ERROR, - "alarm_set_rtc: no RTC, time will be lost on reboot\n"); - goto err; - } - ret = rtc_set_time(alarm_rtc_dev, &rtc_new_rtc_time); - if (ret < 0) - pr_alarm(ERROR, "alarm_set_rtc: " - "Failed to set RTC, time will be lost on reboot\n"); -err: - wake_unlock(&alarm_rtc_wake_lock); - mutex_unlock(&alarm_setrtc_mutex); - return ret; -} - -static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer) -{ - struct alarm_queue *base; - struct android_alarm *alarm; - unsigned long flags; - ktime_t now; - - spin_lock_irqsave(&alarm_slock, flags); - - base = container_of(timer, struct alarm_queue, timer); - now = base->stopped ? base->stopped_time : hrtimer_cb_get_time(timer); - - pr_alarm(INT, "alarm_timer_triggered type %td at %lld\n", - base - alarms, ktime_to_ns(now)); - - while (base->first) { - alarm = container_of(base->first, struct android_alarm, node); - if (alarm->softexpires.tv64 > now.tv64) { - pr_alarm(FLOW, "don't call alarm, %pF, %lld (s %lld)\n", - alarm->function, ktime_to_ns(alarm->expires), - ktime_to_ns(alarm->softexpires)); - break; - } - base->first = rb_next(&alarm->node); - rb_erase(&alarm->node, &base->alarms); - RB_CLEAR_NODE(&alarm->node); - pr_alarm(CALL, "call alarm, type %d, func %pF, %lld (s %lld)\n", - alarm->type, alarm->function, - ktime_to_ns(alarm->expires), - ktime_to_ns(alarm->softexpires)); - spin_unlock_irqrestore(&alarm_slock, flags); - alarm->function(alarm); - spin_lock_irqsave(&alarm_slock, flags); - } - if (!base->first) - pr_alarm(FLOW, "no more alarms of type %td\n", base - alarms); - update_timer_locked(base, true); - spin_unlock_irqrestore(&alarm_slock, flags); - return HRTIMER_NORESTART; -} - -static void alarm_triggered_func(void *p) -{ - struct rtc_device *rtc = alarm_rtc_dev; - if (!(rtc->irq_data & RTC_AF)) - return; - pr_alarm(INT, "rtc alarm triggered\n"); - wake_lock_timeout(&alarm_rtc_wake_lock, 1 * HZ); -} - -static int alarm_suspend(struct platform_device *pdev, pm_message_t state) -{ - int err = 0; - unsigned long flags; - struct rtc_wkalrm rtc_alarm; - struct rtc_time rtc_current_rtc_time; - unsigned long rtc_current_time; - unsigned long rtc_alarm_time; - struct timespec rtc_delta; - struct timespec wall_time; - struct alarm_queue *wakeup_queue = NULL; - struct alarm_queue *tmp_queue = NULL; - - pr_alarm(SUSPEND, "alarm_suspend(%p, %d)\n", pdev, state.event); - - spin_lock_irqsave(&alarm_slock, flags); - suspended = true; - spin_unlock_irqrestore(&alarm_slock, flags); - - hrtimer_cancel(&alarms[ANDROID_ALARM_RTC_WAKEUP].timer); - hrtimer_cancel(&alarms[ - ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].timer); - - tmp_queue = &alarms[ANDROID_ALARM_RTC_WAKEUP]; - if (tmp_queue->first) - wakeup_queue = tmp_queue; - tmp_queue = &alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP]; - if (tmp_queue->first && (!wakeup_queue || - hrtimer_get_expires(&tmp_queue->timer).tv64 < - hrtimer_get_expires(&wakeup_queue->timer).tv64)) - wakeup_queue = tmp_queue; - if (wakeup_queue) { - rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time); - getnstimeofday(&wall_time); - rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_time); - set_normalized_timespec(&rtc_delta, - wall_time.tv_sec - rtc_current_time, - wall_time.tv_nsec); - - rtc_alarm_time = timespec_sub(ktime_to_timespec( - hrtimer_get_expires(&wakeup_queue->timer)), - rtc_delta).tv_sec; - - rtc_time_to_tm(rtc_alarm_time, &rtc_alarm.time); - rtc_alarm.enabled = 1; - rtc_set_alarm(alarm_rtc_dev, &rtc_alarm); - rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time); - rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_time); - pr_alarm(SUSPEND, - "rtc alarm set at %ld, now %ld, rtc delta %ld.%09ld\n", - rtc_alarm_time, rtc_current_time, - rtc_delta.tv_sec, rtc_delta.tv_nsec); - if (rtc_current_time + 1 >= rtc_alarm_time) { - pr_alarm(SUSPEND, "alarm about to go off\n"); - memset(&rtc_alarm, 0, sizeof(rtc_alarm)); - rtc_alarm.enabled = 0; - rtc_set_alarm(alarm_rtc_dev, &rtc_alarm); - - spin_lock_irqsave(&alarm_slock, flags); - suspended = false; - wake_lock_timeout(&alarm_rtc_wake_lock, 2 * HZ); - update_timer_locked(&alarms[ANDROID_ALARM_RTC_WAKEUP], - false); - update_timer_locked(&alarms[ - ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP], false); - err = -EBUSY; - spin_unlock_irqrestore(&alarm_slock, flags); - } - } - return err; -} - -static int alarm_resume(struct platform_device *pdev) -{ - struct rtc_wkalrm alarm; - unsigned long flags; - - pr_alarm(SUSPEND, "alarm_resume(%p)\n", pdev); - - memset(&alarm, 0, sizeof(alarm)); - alarm.enabled = 0; - rtc_set_alarm(alarm_rtc_dev, &alarm); - - spin_lock_irqsave(&alarm_slock, flags); - suspended = false; - update_timer_locked(&alarms[ANDROID_ALARM_RTC_WAKEUP], false); - update_timer_locked(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP], - false); - spin_unlock_irqrestore(&alarm_slock, flags); - - return 0; -} - -static struct rtc_task alarm_rtc_task = { - .func = alarm_triggered_func -}; - -static int rtc_alarm_add_device(struct device *dev, - struct class_interface *class_intf) -{ - int err; - struct rtc_device *rtc = to_rtc_device(dev); - - mutex_lock(&alarm_setrtc_mutex); - - if (alarm_rtc_dev) { - err = -EBUSY; - goto err1; - } - - alarm_platform_dev = - platform_device_register_simple("alarm", -1, NULL, 0); - if (IS_ERR(alarm_platform_dev)) { - err = PTR_ERR(alarm_platform_dev); - goto err2; - } - err = rtc_irq_register(rtc, &alarm_rtc_task); - if (err) - goto err3; - alarm_rtc_dev = rtc; - pr_alarm(INIT_STATUS, "using rtc device, %s, for alarms", rtc->name); - mutex_unlock(&alarm_setrtc_mutex); - - return 0; - -err3: - platform_device_unregister(alarm_platform_dev); -err2: -err1: - mutex_unlock(&alarm_setrtc_mutex); - return err; -} - -static void rtc_alarm_remove_device(struct device *dev, - struct class_interface *class_intf) -{ - if (dev == &alarm_rtc_dev->dev) { - pr_alarm(INIT_STATUS, "lost rtc device for alarms"); - rtc_irq_unregister(alarm_rtc_dev, &alarm_rtc_task); - platform_device_unregister(alarm_platform_dev); - alarm_rtc_dev = NULL; - } -} - -static struct class_interface rtc_alarm_interface = { - .add_dev = &rtc_alarm_add_device, - .remove_dev = &rtc_alarm_remove_device, -}; - -static struct platform_driver alarm_driver = { - .suspend = alarm_suspend, - .resume = alarm_resume, - .driver = { - .name = "alarm" - } -}; - -static int __init alarm_driver_init(void) -{ - int err; - int i; - - hrtimer_init(&alarms[ANDROID_ALARM_RTC_WAKEUP].timer, - CLOCK_REALTIME, HRTIMER_MODE_ABS); - hrtimer_init(&alarms[ANDROID_ALARM_RTC].timer, - CLOCK_REALTIME, HRTIMER_MODE_ABS); - hrtimer_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].timer, - CLOCK_BOOTTIME, HRTIMER_MODE_ABS); - hrtimer_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME].timer, - CLOCK_BOOTTIME, HRTIMER_MODE_ABS); - hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].timer, - CLOCK_MONOTONIC, HRTIMER_MODE_ABS); - - for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) - alarms[i].timer.function = alarm_timer_triggered; - - err = platform_driver_register(&alarm_driver); - if (err < 0) - goto err1; - wake_lock_init(&alarm_rtc_wake_lock, WAKE_LOCK_SUSPEND, "alarm_rtc"); - rtc_alarm_interface.class = rtc_class; - err = class_interface_register(&rtc_alarm_interface); - if (err < 0) - goto err2; - - return 0; - -err2: - wake_lock_destroy(&alarm_rtc_wake_lock); - platform_driver_unregister(&alarm_driver); -err1: - return err; -} - -static void __exit alarm_exit(void) -{ - class_interface_unregister(&rtc_alarm_interface); - wake_lock_destroy(&alarm_rtc_wake_lock); - platform_driver_unregister(&alarm_driver); -} - -module_init(alarm_driver_init); -module_exit(alarm_exit); - diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h index a112177..d0cafd6 100644 --- a/drivers/staging/android/android_alarm.h +++ b/drivers/staging/android/android_alarm.h @@ -33,70 +33,6 @@ enum android_alarm_type { /* ANDROID_ALARM_TIME_CHANGE = 16 */ }; -#ifdef __KERNEL__ - -#include -#include -#include - -/* - * The alarm interface is similar to the hrtimer interface but adds support - * for wakeup from suspend. It also adds an elapsed realtime clock that can - * be used for periodic timers that need to keep running while the system is - * suspended and not be disrupted when the wall time is set. - */ - -/** - * struct alarm - the basic alarm structure - * @node: red black tree node for time ordered insertion - * @type: alarm type. rtc/elapsed-realtime/systemtime, wakeup/non-wakeup. - * @softexpires: the absolute earliest expiry time of the alarm. - * @expires: the absolute expiry time. - * @function: alarm expiry callback function - * - * The alarm structure must be initialized by alarm_init() - * - */ - -struct android_alarm { - struct rb_node node; - enum android_alarm_type type; - ktime_t softexpires; - ktime_t expires; - void (*function)(struct android_alarm *); -}; - -void android_alarm_init(struct android_alarm *alarm, - enum android_alarm_type type, void (*function)(struct android_alarm *)); -void android_alarm_start_range(struct android_alarm *alarm, ktime_t start, - ktime_t end); -int android_alarm_try_to_cancel(struct android_alarm *alarm); -int android_alarm_cancel(struct android_alarm *alarm); - -static inline ktime_t alarm_get_elapsed_realtime(void) -{ - return ktime_get_boottime(); -} - -/* set rtc while preserving elapsed realtime */ -int android_alarm_set_rtc(const struct timespec ts); - -#ifdef CONFIG_ANDROID_ALARM_OLDDRV_COMPAT -/* - * Some older drivers depend on the old API, - * so provide compatability macros for now. - */ -#define alarm android_alarm -#define alarm_init(x, y, z) android_alarm_init(x, y, z) -#define alarm_start_range(x, y, z) android_alarm_start_range(x, y, z) -#define alarm_try_to_cancel(x) android_alarm_try_to_cancel(x) -#define alarm_cancel(x) android_alarm_cancel(x) -#define alarm_set_rtc(x) android_alarm_set_rtc(x) -#endif - - -#endif - enum android_alarm_return_flags { ANDROID_ALARM_RTC_WAKEUP_MASK = 1U << ANDROID_ALARM_RTC_WAKEUP, ANDROID_ALARM_RTC_MASK = 1U << ANDROID_ALARM_RTC, -- cgit v0.10.2 From ea9f10f2fd207bb70a730ee3b356f75bc00ff41d Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 20 Apr 2012 14:45:37 -0500 Subject: staging: r8192e_pci: Change memcpy to memcmp Routine rtllib_MlmeDisassociateRequest() has a comparison of memcpy() with NULL, which makes no sense. Analysis of the code suggests that memcmp() was intended. Reported-by: Dan Carpenter Signed-off-by: Larry Finger Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index c5a15db..ec98ed7 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -3679,8 +3679,7 @@ void rtllib_MlmeDisassociateRequest(struct rtllib_device *rtllib, u8 *asSta, RemovePeerTS(rtllib, asSta); - - if (memcpy(rtllib->current_network.bssid, asSta, 6) == NULL) { + if (memcmp(rtllib->current_network.bssid, asSta, 6) == 0) { rtllib->state = RTLLIB_NOLINK; for (i = 0; i < 6; i++) -- cgit v0.10.2 From 542038f4df5a9d5d806a4af8725d2d21c4423a15 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 20 Apr 2012 12:05:04 -0700 Subject: staging: comedi: use ARRAY_SIZE instead of custom n_boardtypes macros The n_boardtypes macros are simply open-coded versions of the kernels ARRAY_SIZE macro. Use the kernel provided macro. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/acl7225b.c b/drivers/staging/comedi/drivers/acl7225b.c index 9def225..f4a301a 100644 --- a/drivers/staging/comedi/drivers/acl7225b.c +++ b/drivers/staging/comedi/drivers/acl7225b.c @@ -36,7 +36,6 @@ static const struct boardtype boardtypes[] = { {"p16r16dio", P16R16DIO_SIZE,}, }; -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype)) #define this_board ((const struct boardtype *)dev->board_ptr) static struct comedi_driver driver_acl7225b = { @@ -45,7 +44,7 @@ static struct comedi_driver driver_acl7225b = { .attach = acl7225b_attach, .detach = acl7225b_detach, .board_name = &boardtypes[0].name, - .num_names = n_boardtypes, + .num_names = ARRAY_SIZE(boardtypes), .offset = sizeof(struct boardtype), }; diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 2f341a3..5b5dae4 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -2528,14 +2528,12 @@ static const struct addi_board boardtypes[] = { #endif }; -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct addi_board)) - static struct comedi_driver driver_addi = { .driver_name = ADDIDATA_DRIVER_NAME, .module = THIS_MODULE, .attach = i_ADDI_Attach, .detach = i_ADDI_Detach, - .num_names = n_boardtypes, + .num_names = ARRAY_SIZE(boardtypes), .board_name = &boardtypes[0].pc_DriverName, .offset = sizeof(struct addi_board), }; diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index cfe164a..5b84573 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -277,14 +277,12 @@ static const struct boardtype boardtypes[] = { 10000, 40, 512}, }; -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype)) - static struct comedi_driver driver_pci9118 = { .driver_name = "adl_pci9118", .module = THIS_MODULE, .attach = pci9118_attach, .detach = pci9118_detach, - .num_names = n_boardtypes, + .num_names = ARRAY_SIZE(boardtypes), .board_name = &boardtypes[0].name, .offset = sizeof(struct boardtype), }; diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index dc6fe3d..dc762e7 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -264,14 +264,12 @@ static const struct boardtype boardtypes[] = { {.name = DRV_NAME}, }; -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype)) - static struct comedi_driver driver_pci1710 = { .driver_name = DRV_NAME, .module = THIS_MODULE, .attach = pci1710_attach, .detach = pci1710_detach, - .num_names = n_boardtypes, + .num_names = ARRAY_SIZE(boardtypes), .board_name = &boardtypes[0].name, .offset = sizeof(struct boardtype), }; @@ -1398,13 +1396,13 @@ static int pci1710_attach(struct comedi_device *dev, while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_ADVANTECH, PCI_ANY_ID, pcidev))) { if (strcmp(this_board->name, DRV_NAME) == 0) { - for (i = 0; i < n_boardtypes; ++i) { + for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { if (pcidev->device == boardtypes[i].device_id) { board_index = i; break; } } - if (i == n_boardtypes) + if (i == ARRAY_SIZE(boardtypes)) continue; } else { if (pcidev->device != boardtypes[board_index].device_id) diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index eb49c87..4a4ae5f 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -171,8 +171,6 @@ static int pci1723_attach(struct comedi_device *dev, struct comedi_devconfig *it); static int pci1723_detach(struct comedi_device *dev); -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pci1723_board)) - static struct comedi_driver driver_pci1723 = { .driver_name = "adv_pci1723", .module = THIS_MODULE, diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 491df0c..7d920fe 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -406,8 +406,6 @@ static const struct dio_boardtype boardtypes[] = { IO_16b} }; -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct dio_boardtype)) - static struct comedi_driver driver_pci_dio = { .driver_name = "adv_pci_dio", .module = THIS_MODULE, @@ -1134,7 +1132,7 @@ static int pci_dio_attach(struct comedi_device *dev, for_each_pci_dev(pcidev) { /* loop through cards supported by this driver */ - for (i = 0; i < n_boardtypes; ++i) { + for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { if (boardtypes[i].vendor_id != pcidev->vendor) continue; if (boardtypes[i].device_id != pcidev->device) diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 70731972..952b081 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -321,7 +321,6 @@ static const struct daq200_boardtype boardtypes[] = { {"ids4", DAQBOARD2000_SUBSYSTEM_IDS4}, }; -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct daq200_boardtype)) #define this_board ((const struct daq200_boardtype *)dev->board_ptr) static DEFINE_PCI_DEVICE_TABLE(daqboard2000_pci_table) = { @@ -761,7 +760,7 @@ static int daqboard2000_attach(struct comedi_device *dev, devpriv->pci_dev = card; id = ((u32) card-> subsystem_device << 16) | card->subsystem_vendor; - for (i = 0; i < n_boardtypes; i++) { + for (i = 0; i < ARRAY_SIZE(boardtypes); i++) { if (boardtypes[i].id == id) { dev_dbg(dev->hw_dev, "%s\n", boardtypes[i].name); diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index 95ebc26..210b3f0 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -350,7 +350,6 @@ static const struct dt282x_board boardtypes[] = { }, }; -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct dt282x_board)) #define this_board ((const struct dt282x_board *)dev->board_ptr) struct dt282x_private { @@ -420,7 +419,7 @@ static struct comedi_driver driver_dt282x = { .attach = dt282x_attach, .detach = dt282x_detach, .board_name = &boardtypes[0].name, - .num_names = n_boardtypes, + .num_names = ARRAY_SIZE(boardtypes), .offset = sizeof(struct dt282x_board), }; diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 126550f..67b6f5a 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -173,14 +173,12 @@ static const struct boardtype boardtypes[] = { &range_analog}, /* Rangelist for D/A */ }; -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype)) - static struct comedi_driver driver_icp_multi = { .driver_name = "icp_multi", .module = THIS_MODULE, .attach = icp_multi_attach, .detach = icp_multi_detach, - .num_names = n_boardtypes, + .num_names = ARRAY_SIZE(boardtypes), .board_name = &boardtypes[0].name, .offset = sizeof(struct boardtype), }; diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c index b44386a..ce6e514 100644 --- a/drivers/staging/comedi/drivers/pcl711.c +++ b/drivers/staging/comedi/drivers/pcl711.c @@ -155,7 +155,6 @@ static const struct pcl711_board boardtypes[] = { {"acl8112dg", 0, 1, 1, 9, 16, 2, 15, &range_acl8112dg_ai}, }; -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl711_board)) #define this_board ((const struct pcl711_board *)dev->board_ptr) static int pcl711_attach(struct comedi_device *dev, @@ -167,7 +166,7 @@ static struct comedi_driver driver_pcl711 = { .attach = pcl711_attach, .detach = pcl711_detach, .board_name = &boardtypes[0].name, - .num_names = n_boardtypes, + .num_names = ARRAY_SIZE(boardtypes), .offset = sizeof(struct pcl711_board), }; diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c index 61b075d..20715d1 100644 --- a/drivers/staging/comedi/drivers/pcl724.c +++ b/drivers/staging/comedi/drivers/pcl724.c @@ -80,7 +80,6 @@ static const struct pcl724_board boardtypes[] = { {"pet48dio", 48, 2, 0x9eb8, PET48_SIZE, 0, 1,}, }; -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl724_board)) #define this_board ((const struct pcl724_board *)dev->board_ptr) static struct comedi_driver driver_pcl724 = { @@ -89,7 +88,7 @@ static struct comedi_driver driver_pcl724 = { .attach = pcl724_attach, .detach = pcl724_detach, .board_name = &boardtypes[0].name, - .num_names = n_boardtypes, + .num_names = ARRAY_SIZE(boardtypes), .offset = sizeof(struct pcl724_board), }; diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c index 897cd80..a880ceb 100644 --- a/drivers/staging/comedi/drivers/pcl726.c +++ b/drivers/staging/comedi/drivers/pcl726.c @@ -149,7 +149,6 @@ static const struct pcl726_board boardtypes[] = { &rangelist_728[0],}, }; -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl726_board)) #define this_board ((const struct pcl726_board *)dev->board_ptr) static struct comedi_driver driver_pcl726 = { @@ -158,7 +157,7 @@ static struct comedi_driver driver_pcl726 = { .attach = pcl726_attach, .detach = pcl726_detach, .board_name = &boardtypes[0].name, - .num_names = n_boardtypes, + .num_names = ARRAY_SIZE(boardtypes), .offset = sizeof(struct pcl726_board), }; diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c index c9682d6..78c8e59 100644 --- a/drivers/staging/comedi/drivers/pcl730.c +++ b/drivers/staging/comedi/drivers/pcl730.c @@ -42,7 +42,6 @@ static const struct pcl730_board boardtypes[] = { {"acl7130", ACL7130_SIZE,}, }; -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl730_board)) #define this_board ((const struct pcl730_board *)dev->board_ptr) static struct comedi_driver driver_pcl730 = { @@ -51,7 +50,7 @@ static struct comedi_driver driver_pcl730 = { .attach = pcl730_attach, .detach = pcl730_detach, .board_name = &boardtypes[0].name, - .num_names = n_boardtypes, + .num_names = ARRAY_SIZE(boardtypes), .offset = sizeof(struct pcl730_board), }; diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 6fc7464..555d0df 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -397,7 +397,6 @@ static const struct pcl812_board boardtypes[] = { 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, }; -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl812_board)) #define this_board ((const struct pcl812_board *)dev->board_ptr) static struct comedi_driver driver_pcl812 = { @@ -406,7 +405,7 @@ static struct comedi_driver driver_pcl812 = { .attach = pcl812_attach, .detach = pcl812_detach, .board_name = &boardtypes[0].name, - .num_names = n_boardtypes, + .num_names = ARRAY_SIZE(boardtypes), .offset = sizeof(struct pcl812_board), }; diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 96cd7ec..bf7b262 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -146,7 +146,6 @@ static const struct pcl816_board boardtypes[] = { 100}, }; -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl816_board)) #define devpriv ((struct pcl816_private *)dev->private) #define this_board ((const struct pcl816_board *)dev->board_ptr) @@ -165,7 +164,7 @@ static struct comedi_driver driver_pcl816 = { .attach = pcl816_attach, .detach = pcl816_detach, .board_name = &boardtypes[0].name, - .num_names = n_boardtypes, + .num_names = ARRAY_SIZE(boardtypes), .offset = sizeof(struct pcl816_board), }; diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index 7344a53..0272491 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -302,15 +302,13 @@ static const struct pcl818_board boardtypes[] = { 0x0a, 0xfff, 0xfff, 0, 1 /* XXX ? */ }, }; -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl818_board)) - static struct comedi_driver driver_pcl818 = { .driver_name = "pcl818", .module = THIS_MODULE, .attach = pcl818_attach, .detach = pcl818_detach, .board_name = &boardtypes[0].name, - .num_names = n_boardtypes, + .num_names = ARRAY_SIZE(boardtypes), .offset = sizeof(struct pcl818_board), }; diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c index f5c0bd1..4601703 100644 --- a/drivers/staging/comedi/drivers/pcm3724.c +++ b/drivers/staging/comedi/drivers/pcm3724.c @@ -84,7 +84,6 @@ static const struct pcm3724_board boardtypes[] = { {"pcm3724", 48, 2, 0x00fc, PCM3724_SIZE,}, }; -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcm3724_board)) #define this_board ((const struct pcm3724_board *)dev->board_ptr) static struct comedi_driver driver_pcm3724 = { @@ -93,7 +92,7 @@ static struct comedi_driver driver_pcm3724 = { .attach = pcm3724_attach, .detach = pcm3724_detach, .board_name = &boardtypes[0].name, - .num_names = n_boardtypes, + .num_names = ARRAY_SIZE(boardtypes), .offset = sizeof(struct pcm3724_board), }; -- cgit v0.10.2 From 305b8766a9833491b388ac98d57ce38a8106a1e0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 23 Apr 2012 15:59:17 -0700 Subject: Staging: line6: remove unneeded initialization Static variables are initialized to NULL, no need to do it again in the module_init function. CC: Markus Grabner CC: Stefan Hajnoczi CC: Julia Lawall CC: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index e8023af..312905a 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -1297,13 +1297,10 @@ static struct usb_driver line6_driver = { */ static int __init line6_init(void) { - int i, retval; + int retval; printk(KERN_INFO "%s driver version %s\n", DRIVER_NAME, DRIVER_VERSION); - for (i = LINE6_MAX_DEVICES; i--;) - line6_devices[i] = NULL; - retval = usb_register(&line6_driver); if (retval) { -- cgit v0.10.2 From c46b8a6567fb6e0119cb22819aa65faf8d101a2f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 23 Apr 2012 16:09:56 -0700 Subject: Staging: line6: only allocate a buffer if it is needed Only allocate the version request buffer if it is needed, not when the module starts up. This will let us make the module_init path much smaller. CC: Markus Grabner CC: Stefan Hajnoczi CC: Julia Lawall CC: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index 312905a..351e860 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -92,15 +92,10 @@ const unsigned char line6_midi_id[] = { Code to request version of POD, Variax interface (and maybe other devices). */ -static const char line6_request_version0[] = { +static const char line6_request_version[] = { 0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7 }; -/* - Copy of version request code with GFP_KERNEL flag for use in URB. -*/ -static const char *line6_request_version; - struct usb_line6 *line6_devices[LINE6_MAX_DEVICES]; /** @@ -336,8 +331,21 @@ int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer, */ int line6_version_request_async(struct usb_line6 *line6) { - return line6_send_raw_message_async(line6, line6_request_version, - sizeof(line6_request_version0)); + char *buffer; + int retval; + + buffer = kmalloc(sizeof(line6_request_version), GFP_ATOMIC); + if (buffer == NULL) { + dev_err(line6->ifcdev, "Out of memory"); + return -ENOMEM; + } + + memcpy(buffer, line6_request_version, sizeof(line6_request_version)); + + retval = line6_send_raw_message_async(line6, buffer, + sizeof(line6_request_version)); + kfree(buffer); + return retval; } /* @@ -1297,29 +1305,9 @@ static struct usb_driver line6_driver = { */ static int __init line6_init(void) { - int retval; - printk(KERN_INFO "%s driver version %s\n", DRIVER_NAME, DRIVER_VERSION); - retval = usb_register(&line6_driver); - - if (retval) { - err("usb_register failed. Error number %d", retval); - return retval; - } - - line6_request_version = kmalloc(sizeof(line6_request_version0), - GFP_KERNEL); - - if (line6_request_version == NULL) { - err("Out of memory"); - return -ENOMEM; - } - - memcpy((char *)line6_request_version, line6_request_version0, - sizeof(line6_request_version0)); - - return retval; + return usb_register(&line6_driver); } /* @@ -1347,7 +1335,6 @@ static void __exit line6_exit(void) } usb_deregister(&line6_driver); - kfree(line6_request_version); } module_init(line6_init); -- cgit v0.10.2 From 15a89dc83bad5c22a02bd292cf87d72dacb7dcb3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 23 Apr 2012 16:11:26 -0700 Subject: Staging: line6: remove teardown code from module_exit path These pcm values should all be stopped properly when the device is removed from the system (i.e. when disconnect is called), so there's no need to duplicate this when the module is unloaded as well. CC: Markus Grabner CC: Stefan Hajnoczi CC: Julia Lawall CC: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index 351e860..c476fcc3 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -1315,25 +1315,6 @@ static int __init line6_init(void) */ static void __exit line6_exit(void) { - int i; - struct usb_line6 *line6; - struct snd_line6_pcm *line6pcm; - - /* stop all PCM channels */ - for (i = LINE6_MAX_DEVICES; i--;) { - line6 = line6_devices[i]; - - if (line6 == NULL) - continue; - - line6pcm = line6->line6pcm; - - if (line6pcm == NULL) - continue; - - line6_pcm_release(line6pcm, ~0); - } - usb_deregister(&line6_driver); } -- cgit v0.10.2 From 4a6313644c3188f4aa1a6b4403896375baa2e09a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 23 Apr 2012 16:13:19 -0700 Subject: Staging: line6: use module_usb_driver() Now that our module_init/exit path is just registering and unregistering the usb driver, we can use module_usb_driver() instead. This also has the nice side affect of removing the unneeded printk for the module version number. CC: Markus Grabner CC: Stefan Hajnoczi CC: Julia Lawall CC: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index c476fcc3..4513f78 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -1300,26 +1300,7 @@ static struct usb_driver line6_driver = { .id_table = line6_id_table, }; -/* - Module initialization. -*/ -static int __init line6_init(void) -{ - printk(KERN_INFO "%s driver version %s\n", DRIVER_NAME, DRIVER_VERSION); - - return usb_register(&line6_driver); -} - -/* - Module cleanup. -*/ -static void __exit line6_exit(void) -{ - usb_deregister(&line6_driver); -} - -module_init(line6_init); -module_exit(line6_exit); +module_usb_driver(line6_driver); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); -- cgit v0.10.2 From 8d0572504802742ae21f1aaa499478c4e23bd4ef Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 23 Apr 2012 16:33:52 -0700 Subject: Staging: media: go7007: use module_usb_driver() There is no need to initialize a static array to NULL at startup, so we can use the module_usb_driver() call for the go7007 module. Cc: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/media/go7007/s2250-loader.c b/drivers/staging/media/go7007/s2250-loader.c index 4e13251..7c5af4f 100644 --- a/drivers/staging/media/go7007/s2250-loader.c +++ b/drivers/staging/media/go7007/s2250-loader.c @@ -160,31 +160,7 @@ static struct usb_driver s2250loader_driver = { .id_table = s2250loader_ids, }; -static int __init s2250loader_init(void) -{ - int r; - unsigned i = 0; - - for (i = 0; i < MAX_DEVICES; i++) - s2250_dev_table[i] = NULL; - - r = usb_register(&s2250loader_driver); - if (r) { - printk(KERN_ERR "usb_register failed. Error number %d\n", r); - return -1; - } - - printk(KERN_INFO "s2250loader_init: driver registered\n"); - return 0; -} -module_init(s2250loader_init); - -static void __exit s2250loader_cleanup(void) -{ - printk(KERN_INFO "s2250loader_cleanup\n"); - usb_deregister(&s2250loader_driver); -} -module_exit(s2250loader_cleanup); +module_usb_driver(s2250loader_driver); MODULE_AUTHOR(""); MODULE_DESCRIPTION("firmware loader for Sensoray 2250/2251"); -- cgit v0.10.2 From 2682dee3158ef140320d6e1c5467a481dc954154 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 20 Apr 2012 16:53:17 -0700 Subject: staging: asus_oled.c: remove err() usage err() was a very old USB-specific macro that I thought had gone away. This patch removes it from being used in the driver and uses dev_err() instead. CC: Jakub Schmidtke CC: Pekka Paalanen CC: Peter Huewe CC: "Ken O'Brien" Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c index 83549d9..510d796 100644 --- a/drivers/staging/asus_oled/asus_oled.c +++ b/drivers/staging/asus_oled/asus_oled.c @@ -782,20 +782,20 @@ static int __init asus_oled_init(void) oled_class = class_create(THIS_MODULE, ASUS_OLED_UNDERSCORE_NAME); if (IS_ERR(oled_class)) { - err("Error creating " ASUS_OLED_UNDERSCORE_NAME " class"); + printk(KERN_ERR "Error creating " ASUS_OLED_UNDERSCORE_NAME " class\n"); return PTR_ERR(oled_class); } retval = class_create_file(oled_class, &class_attr_version.attr); if (retval) { - err("Error creating class version file"); + printk(KERN_ERR "Error creating class version file\n"); goto error; } retval = usb_register(&oled_driver); if (retval) { - err("usb_register failed. Error number %d", retval); + printk(KERN_ERR "usb_register failed. Error number %d\n", retval); goto error; } -- cgit v0.10.2 From aa8f827a4d7dbea98a9076a4f85b1317391dc031 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 20 Apr 2012 16:53:32 -0700 Subject: staging: line6: toneport.c: remove err() usage err() was a very old USB-specific macro that I thought had gone away. This patch removes it from being used in the driver and uses dev_err() instead. CC: Markus Grabner CC: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c index b754f69..31b624b 100644 --- a/drivers/staging/line6/toneport.c +++ b/drivers/staging/line6/toneport.c @@ -168,7 +168,7 @@ static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2) cmd1, cmd2, NULL, 0, LINE6_TIMEOUT * HZ); if (ret < 0) { - err("send failed (error %d)\n", ret); + dev_err(&usbdev->dev, "send failed (error %d)\n", ret); return ret; } -- cgit v0.10.2 From aec238825f448706dd886ac8df46e9c25a883dec Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 20 Apr 2012 16:53:27 -0700 Subject: staging: frontier: tranzport.c: remove err() usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit err() was a very old USB-specific macro that I thought had gone away. This patch removes it from being used in the driver and uses dev_err() instead. CC: "David Täht" CC: Hitoshi Nakamori CC: "Ken O'Brien" Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c index 29e99bb..376706f 100644 --- a/drivers/staging/frontier/tranzport.c +++ b/drivers/staging/frontier/tranzport.c @@ -353,7 +353,7 @@ static int usb_tranzport_open(struct inode *inode, struct file *file) interface = usb_find_interface(&usb_tranzport_driver, subminor); if (!interface) { - err("%s - error, can't find device for minor %d\n", + printk(KERN_ERR "%s - error, can't find device for minor %d\n", __func__, subminor); retval = -ENODEV; goto unlock_disconnect_exit; @@ -517,9 +517,11 @@ static ssize_t usb_tranzport_read(struct file *file, char __user *buffer, goto exit; } - /* verify that the device wasn't unplugged */ if (dev->intf == NULL) { + /* verify that the device wasn't unplugged */ + if (dev->intf == NULL) { retval = -ENODEV; - err("No device or device unplugged %d\n", retval); + printk(KERN_ERR "%s: No device or device unplugged %d\n", + __func__, retval); goto unlock_exit; } @@ -691,7 +693,8 @@ static ssize_t usb_tranzport_write(struct file *file, /* verify that the device wasn't unplugged */ if (dev->intf == NULL) { retval = -ENODEV; - err("No device or device unplugged %d\n", retval); + printk(KERN_ERR "%s: No device or device unplugged %d\n", + __func__, retval); goto unlock_exit; } @@ -726,7 +729,7 @@ static ssize_t usb_tranzport_write(struct file *file, } if (dev->interrupt_out_endpoint == NULL) { - err("Endpoint should not be be null!\n"); + dev_err(&dev->intf->dev, "Endpoint should not be be null!\n"); goto unlock_exit; } @@ -746,7 +749,8 @@ static ssize_t usb_tranzport_write(struct file *file, retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL); if (retval) { dev->interrupt_out_busy = 0; - err("Couldn't submit interrupt_out_urb %d\n", retval); + dev_err(&dev->intf->dev, + "Couldn't submit interrupt_out_urb %d\n", retval); goto unlock_exit; } retval = bytes_to_write; -- cgit v0.10.2 From f860b0cd8d185f18273921cc75543addf89f05ee Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 20 Apr 2012 16:53:24 -0700 Subject: staging: frontier: alphatrack.c: remove err() usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit err() was a very old USB-specific macro that I thought had gone away. This patch removes it from being used in the driver and uses dev_err() instead. CC: "David Täht" CC: Hitoshi Nakamori Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/frontier/alphatrack.c b/drivers/staging/frontier/alphatrack.c index 3bf0f40e..acbb2cc 100644 --- a/drivers/staging/frontier/alphatrack.c +++ b/drivers/staging/frontier/alphatrack.c @@ -333,8 +333,8 @@ static int usb_alphatrack_open(struct inode *inode, struct file *file) interface = usb_find_interface(&usb_alphatrack_driver, subminor); if (!interface) { - err("%s - error, can't find device for minor %d\n", - __func__, subminor); + printk(KERN_ERR "%s - error, can't find device for minor %d\n", + __func__, subminor); retval = -ENODEV; goto unlock_disconnect_exit; } @@ -494,7 +494,8 @@ static ssize_t usb_alphatrack_read(struct file *file, char __user *buffer, /* verify that the device wasn't unplugged */ if (dev->intf == NULL) { retval = -ENODEV; - err("No device or device unplugged %d\n", retval); + printk(KERN_ERR "%s: No device or device unplugged %d\n", + __func__, retval); goto unlock_exit; } @@ -564,7 +565,8 @@ static ssize_t usb_alphatrack_write(struct file *file, /* verify that the device wasn't unplugged */ if (dev->intf == NULL) { retval = -ENODEV; - err("No device or device unplugged %d\n", retval); + printk(KERN_ERR "%s: No device or device unplugged %d\n", + __func__, retval); goto unlock_exit; } @@ -599,7 +601,7 @@ static ssize_t usb_alphatrack_write(struct file *file, } if (dev->interrupt_out_endpoint == NULL) { - err("Endpoint should not be be null!\n"); + dev_err(&dev->intf->dev, "Endpoint should not be be null!\n"); goto unlock_exit; } @@ -619,7 +621,8 @@ static ssize_t usb_alphatrack_write(struct file *file, retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL); if (retval) { dev->interrupt_out_busy = 0; - err("Couldn't submit interrupt_out_urb %d\n", retval); + dev_err(&dev->intf->dev, + "Couldn't submit interrupt_out_urb %d\n", retval); atomic_dec(&dev->writes_pending); goto unlock_exit; } -- cgit v0.10.2 From 151373aaff439ab4b1ff7f43cff2cbdd9f4a94f5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 20 Apr 2012 16:53:22 -0700 Subject: staging: comedi: vmk80xx.c: remove err() usage err() was a very old USB-specific macro that I thought had gone away. This patch removes it from being used in the driver and uses dev_err() instead. CC: Ian Abbott CC: Mori Hess CC: "J. Ali Harlow" Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index 856d0ea..a7db686 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -297,7 +297,9 @@ resubmit: if (!usb_submit_urb(urb, GFP_KERNEL)) goto exit; - err("comedi#: vmk80xx: %s - submit urb failed\n", __func__); + dev_err(&urb->dev->dev, + "comedi#: vmk80xx: %s - submit urb failed\n", + __func__); usb_unanchor_urb(urb); } -- cgit v0.10.2 From 923faa6a8cc80ceff89214efbccce1497118ceed Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 20 Apr 2012 16:53:19 -0700 Subject: staging: comedi: dt9812.c: remove err() usage err() was a very old USB-specific macro that I thought had gone away. This patch removes it from being used in the driver and uses dev_err() instead. CC: Ian Abbott CC: Mori Hess CC: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index 53953c2..89a49dd 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -547,7 +547,7 @@ static void dt9812_configure_gain(struct usb_dt9812 *dev, rmw->or_value = F020_MASK_ADC0CF_AMP0GN2; break; default: - err("Illegal gain %d\n", gain); + dev_err(&dev->interface->dev, "Illegal gain %d\n", gain); } } @@ -715,7 +715,7 @@ static int dt9812_probe(struct usb_interface *interface, iface_desc = interface->cur_altsetting; if (iface_desc->desc.bNumEndpoints != 5) { - err("Wrong number of endpoints."); + dev_err(&interface->dev, "Wrong number of endpoints.\n"); retval = -ENODEV; goto error; } @@ -781,22 +781,22 @@ static int dt9812_probe(struct usb_interface *interface, } if (dt9812_read_info(dev, 1, &dev->vendor, sizeof(dev->vendor)) != 0) { - err("Failed to read vendor."); + dev_err(&interface->dev, "Failed to read vendor.\n"); retval = -ENODEV; goto error; } if (dt9812_read_info(dev, 3, &dev->product, sizeof(dev->product)) != 0) { - err("Failed to read product."); + dev_err(&interface->dev, "Failed to read product.\n"); retval = -ENODEV; goto error; } if (dt9812_read_info(dev, 5, &dev->device, sizeof(dev->device)) != 0) { - err("Failed to read device."); + dev_err(&interface->dev, "Failed to read device.\n"); retval = -ENODEV; goto error; } if (dt9812_read_info(dev, 7, &dev->serial, sizeof(dev->serial)) != 0) { - err("Failed to read serial."); + dev_err(&interface->dev, "Failed to read serial.\n"); retval = -ENODEV; goto error; } @@ -1146,7 +1146,9 @@ static int __init usb_dt9812_init(void) result = comedi_driver_register(&dt9812_comedi_driver); if (result) { usb_deregister(&dt9812_usb_driver); - err("comedi_driver_register failed. Error number %d", result); + printk(KERN_ERR KBUILD_MODNAME + ": comedi_driver_register failed. Error number %d\n", + result); } return result; -- cgit v0.10.2 From dfcf931a94f660c677c08f9cc23e0ffc7ccca4f3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 23 Apr 2012 17:13:54 -0700 Subject: Staging: media: easycap: remove err() usage err() was a very old USB-specific macro that I thought had gone away. This patch removes it from being used in the driver and uses dev_err() instead. Cc: Mauro Carvalho Chehab Cc: Tomas Winkler Cc: Jesper Juhl Cc: Ezequiel Garcia Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/media/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c index d0fe34a..6f83d36 100644 --- a/drivers/staging/media/easycap/easycap_main.c +++ b/drivers/staging/media/easycap/easycap_main.c @@ -3578,7 +3578,8 @@ static int easycap_usb_probe(struct usb_interface *intf, if (0 != (video_register_device(&(peasycap->video_device), VFL_TYPE_GRABBER, -1))) { - err("Not able to register with videodev"); + dev_err(&intf->dev, + "Not able to register with videodev\n"); videodev_release(&(peasycap->video_device)); return -ENODEV; } @@ -3822,7 +3823,8 @@ static int easycap_usb_probe(struct usb_interface *intf, rc = easycap_alsa_probe(peasycap); if (rc) { - err("easycap_alsa_probe() rc = %i\n", rc); + dev_err(&intf->dev, "easycap_alsa_probe() rc = %i\n", + rc); return -ENODEV; } -- cgit v0.10.2 From e0ebe945c598563db0b4d0033fbe3c419dfbe3aa Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 23 Apr 2012 17:14:54 -0700 Subject: Staging: media: lirc: lirc_imon: remove err() usage err() was a very old USB-specific macro that I thought had gone away. This patch removes it from being used in the driver and uses dev_err() instead. Cc: Jarod Wilson Cc: Mauro Carvalho Chehab Cc: Dan Carpenter Cc: Alexey Khoroshilov Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c index 5f7f8cd..d7cf5ef 100644 --- a/drivers/staging/media/lirc/lirc_imon.c +++ b/drivers/staging/media/lirc/lirc_imon.c @@ -209,8 +209,9 @@ static void deregister_from_lirc(struct imon_context *context) retval = lirc_unregister_driver(minor); if (retval) - err("%s: unable to deregister from lirc(%d)", - __func__, retval); + printk(KERN_ERR KBUILD_MODNAME + ": %s: unable to deregister from lirc(%d)", + __func__, retval); else printk(KERN_INFO MOD_NAME ": Deregistered iMON driver " "(minor:%d)\n", minor); @@ -234,16 +235,18 @@ static int display_open(struct inode *inode, struct file *file) subminor = iminor(inode); interface = usb_find_interface(&imon_driver, subminor); if (!interface) { - err("%s: could not find interface for minor %d", - __func__, subminor); + printk(KERN_ERR KBUILD_MODNAME + ": %s: could not find interface for minor %d\n", + __func__, subminor); retval = -ENODEV; goto exit; } context = usb_get_intfdata(interface); if (!context) { - err("%s: no context found for minor %d", - __func__, subminor); + dev_err(&interface->dev, + "%s: no context found for minor %d\n", + __func__, subminor); retval = -ENODEV; goto exit; } @@ -251,10 +254,12 @@ static int display_open(struct inode *inode, struct file *file) mutex_lock(&context->ctx_lock); if (!context->display) { - err("%s: display not supported by device", __func__); + dev_err(&interface->dev, + "%s: display not supported by device\n", __func__); retval = -ENODEV; } else if (context->display_isopen) { - err("%s: display port is already open", __func__); + dev_err(&interface->dev, + "%s: display port is already open\n", __func__); retval = -EBUSY; } else { context->display_isopen = 1; @@ -281,17 +286,20 @@ static int display_close(struct inode *inode, struct file *file) context = file->private_data; if (!context) { - err("%s: no context for device", __func__); + printk(KERN_ERR KBUILD_MODNAME + "%s: no context for device\n", __func__); return -ENODEV; } mutex_lock(&context->ctx_lock); if (!context->display) { - err("%s: display not supported by device", __func__); + dev_err(&context->usbdev->dev, + "%s: display not supported by device\n", __func__); retval = -ENODEV; } else if (!context->display_isopen) { - err("%s: display is not open", __func__); + dev_err(&context->usbdev->dev, + "%s: display is not open\n", __func__); retval = -EIO; } else { context->display_isopen = 0; @@ -340,19 +348,23 @@ static int send_packet(struct imon_context *context) retval = usb_submit_urb(context->tx_urb, GFP_KERNEL); if (retval) { atomic_set(&(context->tx.busy), 0); - err("%s: error submitting urb(%d)", __func__, retval); + dev_err(&context->usbdev->dev, + "%s: error submitting urb(%d)\n", __func__, retval); } else { /* Wait for transmission to complete (or abort) */ mutex_unlock(&context->ctx_lock); retval = wait_for_completion_interruptible( &context->tx.finished); if (retval) - err("%s: task interrupted", __func__); + dev_err(&context->usbdev->dev, + "%s: task interrupted\n", __func__); mutex_lock(&context->ctx_lock); retval = context->tx.status; if (retval) - err("%s: packet tx failed (%d)", __func__, retval); + dev_err(&context->usbdev->dev, + "%s: packet tx failed (%d)\n", + __func__, retval); } return retval; @@ -383,20 +395,23 @@ static ssize_t vfd_write(struct file *file, const char __user *buf, context = file->private_data; if (!context) { - err("%s: no context for device", __func__); + printk(KERN_ERR KBUILD_MODNAME + "%s: no context for device\n", __func__); return -ENODEV; } mutex_lock(&context->ctx_lock); if (!context->dev_present) { - err("%s: no iMON device present", __func__); + dev_err(&context->usbdev->dev, + "%s: no iMON device present\n", __func__); retval = -ENODEV; goto exit; } if (n_bytes <= 0 || n_bytes > IMON_DATA_BUF_SZ - 3) { - err("%s: invalid payload size", __func__); + dev_err(&context->usbdev->dev, + "%s: invalid payload size\n", __func__); retval = -EINVAL; goto exit; } @@ -425,8 +440,9 @@ static ssize_t vfd_write(struct file *file, const char __user *buf, retval = send_packet(context); if (retval) { - err("%s: send packet failed for packet #%d", - __func__, seq/2); + dev_err(&context->usbdev->dev, + "%s: send packet failed for packet #%d\n", + __func__, seq/2); goto exit; } else { seq += 2; @@ -441,7 +457,8 @@ static ssize_t vfd_write(struct file *file, const char __user *buf, context->usb_tx_buf[7] = (unsigned char) seq; retval = send_packet(context); if (retval) - err("%s: send packet failed for packet #%d", + dev_err(&context->usbdev->dev, + "%s: send packet failed for packet #%d\n", __func__, seq/2); } @@ -508,7 +525,8 @@ static void ir_close(void *data) context = (struct imon_context *)data; if (!context) { - err("%s: no context for device", __func__); + printk(KERN_ERR KBUILD_MODNAME + "%s: no context for device\n", __func__); return; } @@ -732,7 +750,7 @@ static int imon_probe(struct usb_interface *interface, context = kzalloc(sizeof(struct imon_context), GFP_KERNEL); if (!context) { - err("%s: kzalloc failed for context", __func__); + dev_err(dev, "%s: kzalloc failed for context\n", __func__); alloc_status = 1; goto alloc_status_switch; } @@ -797,7 +815,7 @@ static int imon_probe(struct usb_interface *interface, /* Input endpoint is mandatory */ if (!ir_ep_found) { - err("%s: no valid input (IR) endpoint found.", __func__); + dev_err(dev, "%s: no valid input (IR) endpoint found.\n", __func__); retval = -ENODEV; alloc_status = 2; goto alloc_status_switch; @@ -814,30 +832,30 @@ static int imon_probe(struct usb_interface *interface, driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL); if (!driver) { - err("%s: kzalloc failed for lirc_driver", __func__); + dev_err(dev, "%s: kzalloc failed for lirc_driver\n", __func__); alloc_status = 2; goto alloc_status_switch; } rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); if (!rbuf) { - err("%s: kmalloc failed for lirc_buffer", __func__); + dev_err(dev, "%s: kmalloc failed for lirc_buffer\n", __func__); alloc_status = 3; goto alloc_status_switch; } if (lirc_buffer_init(rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) { - err("%s: lirc_buffer_init failed", __func__); + dev_err(dev, "%s: lirc_buffer_init failed\n", __func__); alloc_status = 4; goto alloc_status_switch; } rx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!rx_urb) { - err("%s: usb_alloc_urb failed for IR urb", __func__); + dev_err(dev, "%s: usb_alloc_urb failed for IR urb\n", __func__); alloc_status = 5; goto alloc_status_switch; } tx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!tx_urb) { - err("%s: usb_alloc_urb failed for display urb", + dev_err(dev, "%s: usb_alloc_urb failed for display urb\n", __func__); alloc_status = 6; goto alloc_status_switch; @@ -865,7 +883,7 @@ static int imon_probe(struct usb_interface *interface, lirc_minor = lirc_register_driver(driver); if (lirc_minor < 0) { - err("%s: lirc_register_driver failed", __func__); + dev_err(dev, "%s: lirc_register_driver failed\n", __func__); alloc_status = 7; goto unlock; } else @@ -900,8 +918,8 @@ static int imon_probe(struct usb_interface *interface, retval = usb_submit_urb(context->rx_urb, GFP_KERNEL); if (retval) { - err("%s: usb_submit_urb failed for intf0 (%d)", - __func__, retval); + dev_err(dev, "%s: usb_submit_urb failed for intf0 (%d)\n", + __func__, retval); mutex_unlock(&context->ctx_lock); goto exit; } -- cgit v0.10.2 From 437c06cb4670faa3b22864ccf51a99ce198e4494 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 23 Apr 2012 17:27:48 -0700 Subject: Staging: media: lirc: lirc_sasem: remove err() usage err() was a very old USB-specific macro that I thought had gone away. This patch removes it from being used in the driver and uses dev_err() instead Cc: Jarod Wilson Cc: Mauro Carvalho Chehab Cc: Andrew Miller Cc: Alexey Khoroshilov Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/media/lirc/lirc_sasem.c b/drivers/staging/media/lirc/lirc_sasem.c index 7442104..352a202 100644 --- a/drivers/staging/media/lirc/lirc_sasem.c +++ b/drivers/staging/media/lirc/lirc_sasem.c @@ -185,7 +185,7 @@ static void deregister_from_lirc(struct sasem_context *context) retval = lirc_unregister_driver(minor); if (retval) - err("%s: unable to deregister from lirc (%d)", + printk(KERN_ERR "%s: unable to deregister from lirc (%d)\n", __func__, retval); else printk(KERN_INFO "Deregistered Sasem driver (minor:%d)\n", @@ -210,16 +210,18 @@ static int vfd_open(struct inode *inode, struct file *file) subminor = iminor(inode); interface = usb_find_interface(&sasem_driver, subminor); if (!interface) { - err("%s: could not find interface for minor %d", - __func__, subminor); + printk(KERN_ERR KBUILD_MODNAME + ": %s: could not find interface for minor %d\n", + __func__, subminor); retval = -ENODEV; goto exit; } context = usb_get_intfdata(interface); if (!context) { - err("%s: no context found for minor %d", - __func__, subminor); + dev_err(&interface->dev, + "%s: no context found for minor %d\n", + __func__, subminor); retval = -ENODEV; goto exit; } @@ -227,12 +229,13 @@ static int vfd_open(struct inode *inode, struct file *file) mutex_lock(&context->ctx_lock); if (context->vfd_isopen) { - err("%s: VFD port is already open", __func__); + dev_err(&interface->dev, + "%s: VFD port is already open", __func__); retval = -EBUSY; } else { context->vfd_isopen = 1; file->private_data = context; - printk(KERN_INFO "VFD port opened\n"); + dev_info(&interface->dev, "VFD port opened\n"); } mutex_unlock(&context->ctx_lock); @@ -253,7 +256,8 @@ static long vfd_ioctl(struct file *file, unsigned cmd, unsigned long arg) context = (struct sasem_context *) file->private_data; if (!context) { - err("%s: no context for device", __func__); + printk(KERN_ERR KBUILD_MODNAME + ": %s: no context for device\n", __func__); return -ENODEV; } @@ -287,14 +291,15 @@ static int vfd_close(struct inode *inode, struct file *file) context = (struct sasem_context *) file->private_data; if (!context) { - err("%s: no context for device", __func__); + printk(KERN_ERR KBUILD_MODNAME + ": %s: no context for device\n", __func__); return -ENODEV; } mutex_lock(&context->ctx_lock); if (!context->vfd_isopen) { - err("%s: VFD is not open", __func__); + dev_err(&context->dev->dev, "%s: VFD is not open\n", __func__); retval = -EIO; } else { context->vfd_isopen = 0; @@ -339,7 +344,8 @@ static int send_packet(struct sasem_context *context) retval = usb_submit_urb(context->tx_urb, GFP_KERNEL); if (retval) { atomic_set(&(context->tx.busy), 0); - err("%s: error submitting urb (%d)", __func__, retval); + dev_err(&context->dev->dev, "%s: error submitting urb (%d)\n", + __func__, retval); } else { /* Wait for transmission to complete (or abort) */ mutex_unlock(&context->ctx_lock); @@ -348,7 +354,9 @@ static int send_packet(struct sasem_context *context) retval = context->tx.status; if (retval) - err("%s: packet tx failed (%d)", __func__, retval); + dev_err(&context->dev->dev, + "%s: packet tx failed (%d)\n", + __func__, retval); } return retval; @@ -369,20 +377,23 @@ static ssize_t vfd_write(struct file *file, const char *buf, context = (struct sasem_context *) file->private_data; if (!context) { - err("%s: no context for device", __func__); + printk(KERN_ERR KBUILD_MODNAME + ": %s: no context for device\n", __func__); return -ENODEV; } mutex_lock(&context->ctx_lock); if (!context->dev_present) { - err("%s: no Sasem device present", __func__); + printk(KERN_ERR KBUILD_MODNAME + ": %s: no Sasem device present\n", __func__); retval = -ENODEV; goto exit; } if (n_bytes <= 0 || n_bytes > SASEM_DATA_BUF_SZ) { - err("%s: invalid payload size", __func__); + dev_err(&context->dev->dev, "%s: invalid payload size\n", + __func__); retval = -EINVAL; goto exit; } @@ -440,9 +451,9 @@ static ssize_t vfd_write(struct file *file, const char *buf, } retval = send_packet(context); if (retval) { - - err("%s: send packet failed for packet #%d", - __func__, i); + dev_err(&context->dev->dev, + "%s: send packet failed for packet #%d\n", + __func__, i); goto exit; } } @@ -492,7 +503,8 @@ static int ir_open(void *data) mutex_lock(&context->ctx_lock); if (context->ir_isopen) { - err("%s: IR port is already open", __func__); + dev_err(&context->dev->dev, "%s: IR port is already open\n", + __func__); retval = -EBUSY; goto exit; } @@ -506,8 +518,9 @@ static int ir_open(void *data) retval = usb_submit_urb(context->rx_urb, GFP_KERNEL); if (retval) - err("%s: usb_submit_urb failed for ir_open (%d)", - __func__, retval); + dev_err(&context->dev->dev, + "%s: usb_submit_urb failed for ir_open (%d)\n", + __func__, retval); else { context->ir_isopen = 1; printk(KERN_INFO "IR port opened\n"); @@ -529,7 +542,8 @@ static void ir_close(void *data) context = (struct sasem_context *)data; if (!context) { - err("%s: no context for device", __func__); + printk(KERN_ERR KBUILD_MODNAME + ": %s: no context for device\n", __func__); return; } @@ -687,7 +701,7 @@ static int sasem_probe(struct usb_interface *interface, struct sasem_context *context = NULL; int i; - printk(KERN_INFO "%s: found Sasem device\n", __func__); + dev_info(&interface->dev, "%s: found Sasem device\n", __func__); dev = usb_get_dev(interface_to_usbdev(interface)); @@ -719,8 +733,8 @@ static int sasem_probe(struct usb_interface *interface, rx_endpoint = ep; ir_ep_found = 1; if (debug) - printk(KERN_INFO "%s: found IR endpoint\n", - __func__); + dev_info(&interface->dev, + "%s: found IR endpoint\n", __func__); } else if (!vfd_ep_found && ep_dir == USB_DIR_OUT && @@ -729,22 +743,23 @@ static int sasem_probe(struct usb_interface *interface, tx_endpoint = ep; vfd_ep_found = 1; if (debug) - printk(KERN_INFO "%s: found VFD endpoint\n", - __func__); + dev_info(&interface->dev, + "%s: found VFD endpoint\n", __func__); } } /* Input endpoint is mandatory */ if (!ir_ep_found) { - - err("%s: no valid input (IR) endpoint found.", __func__); + dev_err(&interface->dev, + "%s: no valid input (IR) endpoint found.\n", __func__); retval = -ENODEV; goto exit; } if (!vfd_ep_found) - printk(KERN_INFO "%s: no valid output (VFD) endpoint found.\n", - __func__); + dev_info(&interface->dev, + "%s: no valid output (VFD) endpoint found.\n", + __func__); /* Allocate memory */ @@ -752,38 +767,44 @@ static int sasem_probe(struct usb_interface *interface, context = kzalloc(sizeof(struct sasem_context), GFP_KERNEL); if (!context) { - err("%s: kzalloc failed for context", __func__); + dev_err(&interface->dev, + "%s: kzalloc failed for context\n", __func__); alloc_status = 1; goto alloc_status_switch; } driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL); if (!driver) { - err("%s: kzalloc failed for lirc_driver", __func__); + dev_err(&interface->dev, + "%s: kzalloc failed for lirc_driver\n", __func__); alloc_status = 2; goto alloc_status_switch; } rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); if (!rbuf) { - err("%s: kmalloc failed for lirc_buffer", __func__); + dev_err(&interface->dev, + "%s: kmalloc failed for lirc_buffer\n", __func__); alloc_status = 3; goto alloc_status_switch; } if (lirc_buffer_init(rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) { - err("%s: lirc_buffer_init failed", __func__); + dev_err(&interface->dev, + "%s: lirc_buffer_init failed\n", __func__); alloc_status = 4; goto alloc_status_switch; } rx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!rx_urb) { - err("%s: usb_alloc_urb failed for IR urb", __func__); + dev_err(&interface->dev, + "%s: usb_alloc_urb failed for IR urb\n", __func__); alloc_status = 5; goto alloc_status_switch; } if (vfd_ep_found) { tx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!tx_urb) { - err("%s: usb_alloc_urb failed for VFD urb", - __func__); + dev_err(&interface->dev, + "%s: usb_alloc_urb failed for VFD urb", + __func__); alloc_status = 6; goto alloc_status_switch; } @@ -807,7 +828,8 @@ static int sasem_probe(struct usb_interface *interface, lirc_minor = lirc_register_driver(driver); if (lirc_minor < 0) { - err("%s: lirc_register_driver failed", __func__); + dev_err(&interface->dev, + "%s: lirc_register_driver failed\n", __func__); alloc_status = 7; retval = lirc_minor; goto unlock; -- cgit v0.10.2 From 9b33da165ba857cdfd004df56f58d5ca612d78d9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 24 Apr 2012 09:03:48 -0700 Subject: Staging: media: lirc: lirc_ttusbir: remove err() usage err() was a very old USB-specific macro that I thought had gone away. This patch removes it from being used in the driver and uses dev_err() instead Cc: Jarod Wilson Cc: Mauro Carvalho Chehab Cc: Jesper Juhl Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/media/lirc/lirc_ttusbir.c b/drivers/staging/media/lirc/lirc_ttusbir.c index 7950887..3bb865c 100644 --- a/drivers/staging/media/lirc/lirc_ttusbir.c +++ b/drivers/staging/media/lirc/lirc_ttusbir.c @@ -113,8 +113,9 @@ static int set_use_inc(void *data) for (i = 0; i < num_urbs; i++) { retval = usb_submit_urb(ttusbir->urb[i], GFP_KERNEL); if (retval) { - err("%s: usb_submit_urb failed on urb %d", - __func__, i); + dev_err(&ttusbir->interf->dev, + "%s: usb_submit_urb failed on urb %d\n", + __func__, i); return retval; } } @@ -278,7 +279,7 @@ static int probe(struct usb_interface *intf, const struct usb_device_id *id) if (ttusbir->alt_setting != -1) DPRINTK("alt setting: %d\n", ttusbir->alt_setting); else { - err("Could not find alternate setting\n"); + dev_err(&intf->dev, "Could not find alternate setting\n"); kfree(ttusbir); return -EINVAL; } @@ -291,7 +292,7 @@ static int probe(struct usb_interface *intf, const struct usb_device_id *id) /* Register as a LIRC driver */ if (lirc_buffer_init(&ttusbir->rbuf, sizeof(int), 256) < 0) { - err("Could not get memory for LIRC data buffer\n"); + dev_err(&intf->dev, "Could not get memory for LIRC data buffer\n"); usb_set_intfdata(intf, NULL); kfree(ttusbir); return -ENOMEM; @@ -310,7 +311,7 @@ static int probe(struct usb_interface *intf, const struct usb_device_id *id) ttusbir->driver.features = LIRC_CAN_REC_MODE2; ttusbir->minor = lirc_register_driver(&ttusbir->driver); if (ttusbir->minor < 0) { - err("Error registering as LIRC driver\n"); + dev_err(&intf->dev, "Error registering as LIRC driver\n"); usb_set_intfdata(intf, NULL); lirc_buffer_free(&ttusbir->rbuf); kfree(ttusbir); @@ -321,7 +322,7 @@ static int probe(struct usb_interface *intf, const struct usb_device_id *id) for (i = 0; i < num_urbs; i++) { ttusbir->urb[i] = usb_alloc_urb(8, GFP_KERNEL); if (!ttusbir->urb[i]) { - err("Could not allocate memory for the URB\n"); + dev_err(&intf->dev, "Could not allocate memory for the URB\n"); for (j = i - 1; j >= 0; j--) kfree(ttusbir->urb[j]); lirc_buffer_free(&ttusbir->rbuf); -- cgit v0.10.2 From c471bf65f78fc6841a2c59b1e9377b6b8d40965f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 24 Apr 2012 09:04:42 -0700 Subject: Staging: quatech_usb3: remove err() usage err() was a very old USB-specific macro that I thought had gone away. This patch removes it from being used in the driver and uses dev_err() instead Cc: Rusty Russell Cc: Alan Stern Cc: Mauro Carvalho Chehab Cc: Kautuk Consul Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/quatech_usb2/quatech_usb2.c b/drivers/staging/quatech_usb2/quatech_usb2.c index cb7d906..801b50d 100644 --- a/drivers/staging/quatech_usb2/quatech_usb2.c +++ b/drivers/staging/quatech_usb2/quatech_usb2.c @@ -541,7 +541,7 @@ int qt2_open(struct tty_struct *tty, struct usb_serial_port *port) dbg("port->write_urb == NULL, allocating one"); port->write_urb = usb_alloc_urb(0, GFP_KERNEL); if (!port->write_urb) { - err("Allocating write URB failed"); + dev_err(&port->dev, "Allocating write URB failed\n"); return -ENOMEM; } /* buffer same size as port0 */ @@ -549,7 +549,7 @@ int qt2_open(struct tty_struct *tty, struct usb_serial_port *port) port->bulk_out_buffer = kmalloc(port->bulk_out_size, GFP_KERNEL); if (!port->bulk_out_buffer) { - err("Couldn't allocate bulk_out_buffer"); + dev_err(&port->dev, "Couldn't allocate bulk_out_buffer\n"); return -ENOMEM; } } -- cgit v0.10.2 From 22fa2fe0a496b6a0c0a75df862cfa7269babcb74 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 24 Apr 2012 09:05:21 -0700 Subject: Staging: serqt_usb2: remove err() usage err() was a very old USB-specific macro that I thought had gone away. This patch removes it from being used in the driver and uses dev_err() instead. Cc: Bill Pemberton Cc: Rusty Russell Cc: Alan Stern Cc: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index ae1d815..0ec83aa 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -1559,8 +1559,9 @@ static void qt_unthrottle(struct tty_struct *tty) qt_read_bulk_callback, port); result = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (result) - err("%s - failed restarting read urb, error %d", - __func__, result); + dev_err(&port->dev, + "%s - failed restarting read urb, error %d\n", + __func__, result); } } mutex_unlock(&qt_port->lock); -- cgit v0.10.2 From a180c0d659f604568637336a00c0c3ca2f7b094a Mon Sep 17 00:00:00 2001 From: John Stultz Date: Tue, 24 Apr 2012 10:57:16 -0700 Subject: staging: android-alarm: Switch from wakelocks to wakeup sources MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In their current AOSP tree, the Android in-kernel wakelock infrastructure has been reimplemented in terms of wakeup sources: http://git.linaro.org/gitweb?p=people/jstultz/android.git;a=commitdiff;h=e9911f4efdc55af703b8b3bb8c839e6f5dd173bb The Android alarm driver currently has stubbed out calls to wakelock functionality. So this patch simply converts the stubbed out wakelock calls to wakeup source calls, and removes the empty wakelock macros Greg, would you mind queuing this in staging-next? CC: Colin Cross CC: Arve HjønnevÃ¥g CC: Greg KH CC: Android Kernel Team Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c index 04075b3..53ce6ec 100644 --- a/drivers/staging/android/alarm-dev.c +++ b/drivers/staging/android/alarm-dev.c @@ -25,17 +25,6 @@ #include #include "android_alarm.h" -/* XXX - Hack out wakelocks, while they are out of tree */ -struct wake_lock { - int i; -}; -#define wake_lock(x) -#define wake_lock_timeout(x, y) -#define wake_unlock(x) -#define WAKE_LOCK_SUSPEND 0 -#define wake_lock_init(x, y, z) ((x)->i = 1) -#define wake_lock_destroy(x) - #define ANDROID_ALARM_PRINT_INFO (1U << 0) #define ANDROID_ALARM_PRINT_IO (1U << 1) #define ANDROID_ALARM_PRINT_INT (1U << 2) @@ -61,7 +50,7 @@ module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); static int alarm_opened; static DEFINE_SPINLOCK(alarm_slock); -static struct wake_lock alarm_wake_lock; +static struct wakeup_source alarm_wake_lock; static DECLARE_WAIT_QUEUE_HEAD(alarm_wait_queue); static uint32_t alarm_pending; static uint32_t alarm_enabled; @@ -154,7 +143,7 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (alarm_pending) { alarm_pending &= ~alarm_type_mask; if (!alarm_pending && !wait_pending) - wake_unlock(&alarm_wake_lock); + __pm_relax(&alarm_wake_lock); } alarm_enabled &= ~alarm_type_mask; spin_unlock_irqrestore(&alarm_slock, flags); @@ -192,7 +181,7 @@ from_old_alarm_set: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm wait\n"); if (!alarm_pending && wait_pending) { - wake_unlock(&alarm_wake_lock); + __pm_relax(&alarm_wake_lock); wait_pending = 0; } spin_unlock_irqrestore(&alarm_slock, flags); @@ -284,7 +273,7 @@ static int alarm_release(struct inode *inode, struct file *file) if (alarm_pending) pr_alarm(INFO, "alarm_release: clear " "pending alarms %x\n", alarm_pending); - wake_unlock(&alarm_wake_lock); + __pm_relax(&alarm_wake_lock); wait_pending = 0; alarm_pending = 0; } @@ -302,7 +291,7 @@ static void devalarm_triggered(struct devalarm *alarm) pr_alarm(INT, "devalarm_triggered type %d\n", alarm->type); spin_lock_irqsave(&alarm_slock, flags); if (alarm_enabled & alarm_type_mask) { - wake_lock_timeout(&alarm_wake_lock, 5 * HZ); + __pm_wakeup_event(&alarm_wake_lock, 5000); /* 5secs */ alarm_enabled &= ~alarm_type_mask; alarm_pending |= alarm_type_mask; wake_up(&alarm_wait_queue); @@ -368,15 +357,14 @@ static int __init alarm_dev_init(void) alarms[i].u.hrt.function = devalarm_hrthandler; } - wake_lock_init(&alarm_wake_lock, WAKE_LOCK_SUSPEND, "alarm"); - + wakeup_source_init(&alarm_wake_lock, "alarm"); return 0; } static void __exit alarm_dev_exit(void) { misc_deregister(&alarm_device); - wake_lock_destroy(&alarm_wake_lock); + wakeup_source_trash(&alarm_wake_lock); } module_init(alarm_dev_init); -- cgit v0.10.2 From 78aee0fc9a2ee913ef8c524c380a72ee693dd6cb Mon Sep 17 00:00:00 2001 From: Emil Goode Date: Tue, 24 Apr 2012 00:36:29 +0200 Subject: staging: android: binder: fix sparse warnings Fix sparse warnings by adding __user annotation to stucts. This patch fixes the the following sparse warnings: drivers/staging/android/binder.c:1343:76: warning: incorrect type in argument 2 (different address spaces) drivers/staging/android/binder.c:1343:76: expected void [noderef] *ptr drivers/staging/android/binder.c:1343:76: got void *binder drivers/staging/android/binder.c:1567:57: warning: incorrect type in argument 2 (different address spaces) drivers/staging/android/binder.c:1567:57: expected void const [noderef] *from drivers/staging/android/binder.c:1567:57: got void const *buffer drivers/staging/android/binder.c:1573:46: warning: incorrect type in argument 2 (different address spaces) drivers/staging/android/binder.c:1573:46: expected void const [noderef] *from drivers/staging/android/binder.c:1573:46: got void const *offsets drivers/staging/android/binder.c:1603:76: warning: incorrect type in argument 2 (different address spaces) drivers/staging/android/binder.c:1603:76: expected void [noderef] *ptr drivers/staging/android/binder.c:1603:76: got void *binder drivers/staging/android/binder.c:1605:64: warning: incorrect type in argument 2 (different address spaces) drivers/staging/android/binder.c:1605:64: expected void [noderef] *ptr drivers/staging/android/binder.c:1605:64: got void *binder drivers/staging/android/binder.c:1605:76: warning: incorrect type in argument 3 (different address spaces) drivers/staging/android/binder.c:1605:76: expected void [noderef] *cookie drivers/staging/android/binder.c:1605:76: got void *cookie drivers/staging/android/binder.c:1613:40: error: incompatible types in comparison Signed-off-by: Emil Goode Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/binder.h b/drivers/staging/android/binder.h index 6602474..2f7d195 100644 --- a/drivers/staging/android/binder.h +++ b/drivers/staging/android/binder.h @@ -53,12 +53,12 @@ struct flat_binder_object { /* 8 bytes of data. */ union { - void *binder; /* local object */ + void __user *binder; /* local object */ signed long handle; /* remote object */ }; /* extra data associated with local object */ - void *cookie; + void __user *cookie; }; /* @@ -139,9 +139,9 @@ struct binder_transaction_data { union { struct { /* transaction data */ - const void *buffer; + const void __user *buffer; /* offsets from buffer to flat_binder_object structs */ - const void *offsets; + const void __user *offsets; } ptr; uint8_t buf[8]; } data; -- cgit v0.10.2 From 610202ddc6951453034475fdcf5c9caf14f050de Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Tue, 24 Apr 2012 11:41:38 +0530 Subject: staging: iio: light: of: Fix vendor prefix of isl29018/isl29028 ISL29018/ISL29028 is from Intersil Corporation and making the vendor prefix for this part as "isil" for OF compatibity. Signed-off-by: Laxman Dewangan Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index 073e899..1ec2dac 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -596,7 +596,7 @@ static const struct i2c_device_id isl29018_id[] = { MODULE_DEVICE_TABLE(i2c, isl29018_id); static const struct of_device_id isl29018_of_match[] = { - { .compatible = "invn,isl29018", }, + { .compatible = "isil,isl29018", }, { }, }; MODULE_DEVICE_TABLE(of, isl29018_of_match); diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c index 4ac49aa..7057d9b 100644 --- a/drivers/staging/iio/light/isl29028.c +++ b/drivers/staging/iio/light/isl29028.c @@ -542,7 +542,7 @@ static const struct i2c_device_id isl29028_id[] = { MODULE_DEVICE_TABLE(i2c, isl29028_id); static const struct of_device_id isl29028_of_match[] = { - { .compatible = "isl,isl29028", }, + { .compatible = "isil,isl29028", }, { }, }; MODULE_DEVICE_TABLE(of, isl29028_of_match); -- cgit v0.10.2 From 057340e3de29cc0664a4f97b17cfffd6b083d647 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 20 Apr 2012 12:57:38 +0530 Subject: staging: iio: light: isl29018: use regmap for register access Using regmap for accessing register through i2c bus. This will remove the code for caching registers, read-modify-write logics. Also it will provide the debugfs feature to dump register through regmap debugfs. Signed-off-by: Laxman Dewangan Reviewed-by: Grant Grundler Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/light/Kconfig b/drivers/staging/iio/light/Kconfig index bb633f6..fd39f72 100644 --- a/drivers/staging/iio/light/Kconfig +++ b/drivers/staging/iio/light/Kconfig @@ -6,6 +6,7 @@ menu "Light sensors" config SENSORS_ISL29018 tristate "ISL 29018 light and proximity sensor" depends on I2C + select REGMAP_I2C default n help If you say yes here you get support for ambient light sensing and diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index 1ec2dac..2c894a6 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -26,9 +26,11 @@ #include #include #include +#include #include #include "../iio.h" #include "../sysfs.h" + #define CONVERSION_TIME_MS 100 #define ISL29018_REG_ADD_COMMAND1 0x00 @@ -51,49 +53,22 @@ #define ISL29018_REG_ADD_DATA_LSB 0x02 #define ISL29018_REG_ADD_DATA_MSB 0x03 -#define ISL29018_MAX_REGS (ISL29018_REG_ADD_DATA_MSB+1) #define ISL29018_REG_TEST 0x08 #define ISL29018_TEST_SHIFT 0 #define ISL29018_TEST_MASK (0xFF << ISL29018_TEST_SHIFT) struct isl29018_chip { - struct i2c_client *client; + struct device *dev; + struct regmap *regmap; struct mutex lock; unsigned int lux_scale; unsigned int range; unsigned int adc_bit; int prox_scheme; - u8 reg_cache[ISL29018_MAX_REGS]; }; -static int isl29018_write_data(struct i2c_client *client, u8 reg, - u8 val, u8 mask, u8 shift) -{ - u8 regval = val; - int ret; - struct isl29018_chip *chip = iio_priv(i2c_get_clientdata(client)); - - /* don't cache or mask REG_TEST */ - if (reg < ISL29018_MAX_REGS) { - regval = chip->reg_cache[reg]; - regval &= ~mask; - regval |= val << shift; - } - - ret = i2c_smbus_write_byte_data(client, reg, regval); - if (ret) { - dev_err(&client->dev, "Write to device fails status %x\n", ret); - } else { - /* don't update cache on err */ - if (reg < ISL29018_MAX_REGS) - chip->reg_cache[reg] = regval; - } - - return ret; -} - -static int isl29018_set_range(struct i2c_client *client, unsigned long range, +static int isl29018_set_range(struct isl29018_chip *chip, unsigned long range, unsigned int *new_range) { static const unsigned long supp_ranges[] = {1000, 4000, 16000, 64000}; @@ -109,11 +84,11 @@ static int isl29018_set_range(struct i2c_client *client, unsigned long range, if (i >= ARRAY_SIZE(supp_ranges)) return -EINVAL; - return isl29018_write_data(client, ISL29018_REG_ADD_COMMANDII, - i, COMMANDII_RANGE_MASK, COMMANDII_RANGE_SHIFT); + return regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMANDII, + COMMANDII_RANGE_MASK, i << COMMANDII_RANGE_SHIFT); } -static int isl29018_set_resolution(struct i2c_client *client, +static int isl29018_set_resolution(struct isl29018_chip *chip, unsigned long adcbit, unsigned int *conf_adc_bit) { static const unsigned long supp_adcbit[] = {16, 12, 8, 4}; @@ -129,48 +104,49 @@ static int isl29018_set_resolution(struct i2c_client *client, if (i >= ARRAY_SIZE(supp_adcbit)) return -EINVAL; - return isl29018_write_data(client, ISL29018_REG_ADD_COMMANDII, - i, COMMANDII_RESOLUTION_MASK, - COMMANDII_RESOLUTION_SHIFT); + return regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMANDII, + COMMANDII_RESOLUTION_MASK, + i << COMMANDII_RESOLUTION_SHIFT); } -static int isl29018_read_sensor_input(struct i2c_client *client, int mode) +static int isl29018_read_sensor_input(struct isl29018_chip *chip, int mode) { int status; - int lsb; - int msb; + unsigned int lsb; + unsigned int msb; /* Set mode */ - status = isl29018_write_data(client, ISL29018_REG_ADD_COMMAND1, - mode, COMMMAND1_OPMODE_MASK, COMMMAND1_OPMODE_SHIFT); + status = regmap_write(chip->regmap, ISL29018_REG_ADD_COMMAND1, + mode << COMMMAND1_OPMODE_SHIFT); if (status) { - dev_err(&client->dev, "Error in setting operating mode\n"); + dev_err(chip->dev, + "Error in setting operating mode err %d\n", status); return status; } msleep(CONVERSION_TIME_MS); - lsb = i2c_smbus_read_byte_data(client, ISL29018_REG_ADD_DATA_LSB); - if (lsb < 0) { - dev_err(&client->dev, "Error in reading LSB DATA\n"); - return lsb; + status = regmap_read(chip->regmap, ISL29018_REG_ADD_DATA_LSB, &lsb); + if (status < 0) { + dev_err(chip->dev, + "Error in reading LSB DATA with err %d\n", status); + return status; } - msb = i2c_smbus_read_byte_data(client, ISL29018_REG_ADD_DATA_MSB); - if (msb < 0) { - dev_err(&client->dev, "Error in reading MSB DATA\n"); - return msb; + status = regmap_read(chip->regmap, ISL29018_REG_ADD_DATA_MSB, &msb); + if (status < 0) { + dev_err(chip->dev, + "Error in reading MSB DATA with error %d\n", status); + return status; } - dev_vdbg(&client->dev, "MSB 0x%x and LSB 0x%x\n", msb, lsb); + dev_vdbg(chip->dev, "MSB 0x%x and LSB 0x%x\n", msb, lsb); return (msb << 8) | lsb; } -static int isl29018_read_lux(struct i2c_client *client, int *lux) +static int isl29018_read_lux(struct isl29018_chip *chip, int *lux) { int lux_data; - struct isl29018_chip *chip = iio_priv(i2c_get_clientdata(client)); - lux_data = isl29018_read_sensor_input(client, - COMMMAND1_OPMODE_ALS_ONCE); + lux_data = isl29018_read_sensor_input(chip, COMMMAND1_OPMODE_ALS_ONCE); if (lux_data < 0) return lux_data; @@ -180,11 +156,11 @@ static int isl29018_read_lux(struct i2c_client *client, int *lux) return 0; } -static int isl29018_read_ir(struct i2c_client *client, int *ir) +static int isl29018_read_ir(struct isl29018_chip *chip, int *ir) { int ir_data; - ir_data = isl29018_read_sensor_input(client, COMMMAND1_OPMODE_IR_ONCE); + ir_data = isl29018_read_sensor_input(chip, COMMMAND1_OPMODE_IR_ONCE); if (ir_data < 0) return ir_data; @@ -194,7 +170,7 @@ static int isl29018_read_ir(struct i2c_client *client, int *ir) return 0; } -static int isl29018_read_proximity_ir(struct i2c_client *client, int scheme, +static int isl29018_read_proximity_ir(struct isl29018_chip *chip, int scheme, int *near_ir) { int status; @@ -202,14 +178,15 @@ static int isl29018_read_proximity_ir(struct i2c_client *client, int scheme, int ir_data = -1; /* Do proximity sensing with required scheme */ - status = isl29018_write_data(client, ISL29018_REG_ADD_COMMANDII, - scheme, COMMANDII_SCHEME_MASK, COMMANDII_SCHEME_SHIFT); + status = regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMANDII, + COMMANDII_SCHEME_MASK, + scheme << COMMANDII_SCHEME_SHIFT); if (status) { - dev_err(&client->dev, "Error in setting operating mode\n"); + dev_err(chip->dev, "Error in setting operating mode\n"); return status; } - prox_data = isl29018_read_sensor_input(client, + prox_data = isl29018_read_sensor_input(chip, COMMMAND1_OPMODE_PROX_ONCE); if (prox_data < 0) return prox_data; @@ -219,8 +196,7 @@ static int isl29018_read_proximity_ir(struct i2c_client *client, int scheme, return 0; } - ir_data = isl29018_read_sensor_input(client, - COMMMAND1_OPMODE_IR_ONCE); + ir_data = isl29018_read_sensor_input(chip, COMMMAND1_OPMODE_IR_ONCE); if (ir_data < 0) return ir_data; @@ -249,7 +225,6 @@ static ssize_t store_range(struct device *dev, { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct isl29018_chip *chip = iio_priv(indio_dev); - struct i2c_client *client = chip->client; int status; unsigned long lval; unsigned int new_range; @@ -264,10 +239,11 @@ static ssize_t store_range(struct device *dev, } mutex_lock(&chip->lock); - status = isl29018_set_range(client, lval, &new_range); + status = isl29018_set_range(chip, lval, &new_range); if (status < 0) { mutex_unlock(&chip->lock); - dev_err(dev, "Error in setting max range\n"); + dev_err(dev, + "Error in setting max range with err %d\n", status); return status; } chip->range = new_range; @@ -291,7 +267,6 @@ static ssize_t store_resolution(struct device *dev, { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct isl29018_chip *chip = iio_priv(indio_dev); - struct i2c_client *client = chip->client; int status; unsigned long lval; unsigned int new_adc_bit; @@ -304,7 +279,7 @@ static ssize_t store_resolution(struct device *dev, } mutex_lock(&chip->lock); - status = isl29018_set_resolution(client, lval, &new_adc_bit); + status = isl29018_set_resolution(chip, lval, &new_adc_bit); if (status < 0) { mutex_unlock(&chip->lock); dev_err(dev, "Error in setting resolution\n"); @@ -379,7 +354,6 @@ static int isl29018_read_raw(struct iio_dev *indio_dev, { int ret = -EINVAL; struct isl29018_chip *chip = iio_priv(indio_dev); - struct i2c_client *client = chip->client; mutex_lock(&chip->lock); switch (mask) { @@ -387,13 +361,13 @@ static int isl29018_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_PROCESSED: switch (chan->type) { case IIO_LIGHT: - ret = isl29018_read_lux(client, val); + ret = isl29018_read_lux(chip, val); break; case IIO_INTENSITY: - ret = isl29018_read_ir(client, val); + ret = isl29018_read_ir(chip, val); break; case IIO_PROXIMITY: - ret = isl29018_read_proximity_ir(client, + ret = isl29018_read_proximity_ir(chip, chip->prox_scheme, val); break; default: @@ -459,15 +433,12 @@ static const struct attribute_group isl29108_group = { .attrs = isl29018_attributes, }; -static int isl29018_chip_init(struct i2c_client *client) +static int isl29018_chip_init(struct isl29018_chip *chip) { - struct isl29018_chip *chip = iio_priv(i2c_get_clientdata(client)); int status; int new_adc_bit; unsigned int new_range; - memset(chip->reg_cache, 0, sizeof(chip->reg_cache)); - /* Code added per Intersil Application Note 1534: * When VDD sinks to approximately 1.8V or below, some of * the part's registers may change their state. When VDD @@ -488,10 +459,9 @@ static int isl29018_chip_init(struct i2c_client *client) * the same thing EXCEPT the data sheet asks for a 1ms delay after * writing the CMD1 register. */ - status = isl29018_write_data(client, ISL29018_REG_TEST, 0, - ISL29018_TEST_MASK, ISL29018_TEST_SHIFT); + status = regmap_write(chip->regmap, ISL29018_REG_TEST, 0x0); if (status < 0) { - dev_err(&client->dev, "Failed to clear isl29018 TEST reg." + dev_err(chip->dev, "Failed to clear isl29018 TEST reg." "(%d)\n", status); return status; } @@ -500,10 +470,9 @@ static int isl29018_chip_init(struct i2c_client *client) * "Operating Mode" (COMMAND1) register is reprogrammed when * data is read from the device. */ - status = isl29018_write_data(client, ISL29018_REG_ADD_COMMAND1, 0, - 0xff, 0); + status = regmap_write(chip->regmap, ISL29018_REG_ADD_COMMAND1, 0); if (status < 0) { - dev_err(&client->dev, "Failed to clear isl29018 CMD1 reg." + dev_err(chip->dev, "Failed to clear isl29018 CMD1 reg." "(%d)\n", status); return status; } @@ -511,13 +480,13 @@ static int isl29018_chip_init(struct i2c_client *client) msleep(1); /* per data sheet, page 10 */ /* set defaults */ - status = isl29018_set_range(client, chip->range, &new_range); + status = isl29018_set_range(chip, chip->range, &new_range); if (status < 0) { - dev_err(&client->dev, "Init of isl29018 fails\n"); + dev_err(chip->dev, "Init of isl29018 fails\n"); return status; } - status = isl29018_set_resolution(client, chip->adc_bit, + status = isl29018_set_resolution(chip, chip->adc_bit, &new_adc_bit); return 0; @@ -530,6 +499,32 @@ static const struct iio_info isl29108_info = { .write_raw = &isl29018_write_raw, }; +static bool is_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case ISL29018_REG_ADD_DATA_LSB: + case ISL29018_REG_ADD_DATA_MSB: + case ISL29018_REG_ADD_COMMAND1: + case ISL29018_REG_TEST: + return true; + default: + return false; + } +} + +/* + * isl29018_regmap_config: regmap configuration. + * Use RBTREE mechanism for caching. + */ +static const struct regmap_config isl29018_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .volatile_reg = is_volatile_reg, + .max_register = ISL29018_REG_TEST, + .num_reg_defaults_raw = ISL29018_REG_TEST + 1, + .cache_type = REGCACHE_RBTREE, +}; + static int __devinit isl29018_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -546,7 +541,7 @@ static int __devinit isl29018_probe(struct i2c_client *client, chip = iio_priv(indio_dev); i2c_set_clientdata(client, indio_dev); - chip->client = client; + chip->dev = &client->dev; mutex_init(&chip->lock); @@ -554,7 +549,14 @@ static int __devinit isl29018_probe(struct i2c_client *client, chip->range = 1000; chip->adc_bit = 16; - err = isl29018_chip_init(client); + chip->regmap = devm_regmap_init_i2c(client, &isl29018_regmap_config); + if (IS_ERR(chip->regmap)) { + err = PTR_ERR(chip->regmap); + dev_err(chip->dev, "regmap initialization failed: %d\n", err); + goto exit; + } + + err = isl29018_chip_init(chip); if (err) goto exit_iio_free; -- cgit v0.10.2 From 1f9e349460389963838aa5428425e7dc31000af6 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Sat, 21 Apr 2012 10:10:16 +0200 Subject: iio: Add device tree support to LPC32xx ADC This patch adds device tree support to the LPC32xx's ADC. Signed-off-by: Roland Stigge Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/devicetree/bindings/staging/iio/adc/lpc32xx-adc.txt b/Documentation/devicetree/bindings/staging/iio/adc/lpc32xx-adc.txt new file mode 100644 index 0000000..b3629d3 --- /dev/null +++ b/Documentation/devicetree/bindings/staging/iio/adc/lpc32xx-adc.txt @@ -0,0 +1,16 @@ +* NXP LPC32xx SoC ADC controller + +Required properties: +- compatible: must be "nxp,lpc3220-adc" +- reg: physical base address of the controller and length of memory mapped + region. +- interrupts: The ADC interrupt + +Example: + + adc@40048000 { + compatible = "nxp,lpc3220-adc"; + reg = <0x40048000 0x1000>; + interrupt-parent = <&mic>; + interrupts = <39 0>; + }; diff --git a/drivers/staging/iio/adc/lpc32xx_adc.c b/drivers/staging/iio/adc/lpc32xx_adc.c index ce9320b..d7f4fe4 100644 --- a/drivers/staging/iio/adc/lpc32xx_adc.c +++ b/drivers/staging/iio/adc/lpc32xx_adc.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "../iio.h" #include "../sysfs.h" @@ -222,12 +223,21 @@ static int __devexit lpc32xx_adc_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_OF +static const struct of_device_id lpc32xx_adc_match[] = { + { .compatible = "nxp,lpc3220-adc" }, + {}, +}; +MODULE_DEVICE_TABLE(of, lpc32xx_adc_match); +#endif + static struct platform_driver lpc32xx_adc_driver = { .probe = lpc32xx_adc_probe, .remove = __devexit_p(lpc32xx_adc_remove), .driver = { .name = MOD_NAME, .owner = THIS_MODULE, + .of_match_table = of_match_ptr(lpc32xx_adc_match), }, }; -- cgit v0.10.2 From a714af276f5002b44e97a2d6d03f85bdae627c41 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 21 Apr 2012 10:09:32 +0100 Subject: staging:iio:buffer trivial use of strtobool to remove dodgy equivalent. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/industrialio-buffer.c b/drivers/staging/iio/industrialio-buffer.c index 386ba76..59b0caf 100644 --- a/drivers/staging/iio/industrialio-buffer.c +++ b/drivers/staging/iio/industrialio-buffer.c @@ -124,13 +124,15 @@ static ssize_t iio_scan_el_store(struct device *dev, const char *buf, size_t len) { - int ret = 0; + int ret; bool state; struct iio_dev *indio_dev = dev_get_drvdata(dev); struct iio_buffer *buffer = indio_dev->buffer; struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - state = !(buf[0] == '0'); + ret = strtobool(buf, &state); + if (ret < 0) + return ret; mutex_lock(&indio_dev->mlock); if (iio_buffer_enabled(indio_dev)) { ret = -EBUSY; @@ -169,11 +171,14 @@ static ssize_t iio_scan_el_ts_store(struct device *dev, const char *buf, size_t len) { - int ret = 0; + int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); bool state; - state = !(buf[0] == '0'); + ret = strtobool(buf, &state); + if (ret < 0) + return ret; + mutex_lock(&indio_dev->mlock); if (iio_buffer_enabled(indio_dev)) { ret = -EBUSY; -- cgit v0.10.2 From 6b3b58ed15cdc27b1ded4487d74c1b7ae04aa162 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 21 Apr 2012 10:09:33 +0100 Subject: staging:iio:buffer: pull computation of scan length into a utility function. Principal reason is to make later patches more coherent and easier to review but this set in itself separates a logical entity out nicely wihin the code. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/industrialio-buffer.c b/drivers/staging/iio/industrialio-buffer.c index 59b0caf..389fe16 100644 --- a/drivers/staging/iio/industrialio-buffer.c +++ b/drivers/staging/iio/industrialio-buffer.c @@ -508,29 +508,41 @@ static const unsigned long *iio_scan_mask_match(const unsigned long *av_masks, return NULL; } -int iio_sw_buffer_preenable(struct iio_dev *indio_dev) +static int iio_compute_scan_bytes(struct iio_dev *indio_dev, const long *mask, + bool timestamp) { - struct iio_buffer *buffer = indio_dev->buffer; const struct iio_chan_spec *ch; unsigned bytes = 0; int length, i; - dev_dbg(&indio_dev->dev, "%s\n", __func__); /* How much space will the demuxed element take? */ - for_each_set_bit(i, buffer->scan_mask, + for_each_set_bit(i, mask, indio_dev->masklength) { ch = iio_find_channel_from_si(indio_dev, i); - length = ch->scan_type.storagebits/8; + length = ch->scan_type.storagebits / 8; bytes = ALIGN(bytes, length); bytes += length; } - if (buffer->scan_timestamp) { + if (timestamp) { ch = iio_find_channel_from_si(indio_dev, - buffer->scan_index_timestamp); - length = ch->scan_type.storagebits/8; + indio_dev + ->buffer->scan_index_timestamp); + length = ch->scan_type.storagebits / 8; bytes = ALIGN(bytes, length); bytes += length; } + return bytes; +} + +int iio_sw_buffer_preenable(struct iio_dev *indio_dev) +{ + struct iio_buffer *buffer = indio_dev->buffer; + unsigned bytes; + dev_dbg(&indio_dev->dev, "%s\n", __func__); + + /* How much space will the demuxed element take? */ + bytes = iio_compute_scan_bytes(indio_dev, buffer->scan_mask, + buffer->scan_timestamp); buffer->access->set_bytes_per_datum(buffer, bytes); /* What scan mask do we actually have ?*/ -- cgit v0.10.2 From f1264809eb7fe4227dc9fc47723b9bd44afc5641 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 21 Apr 2012 10:09:34 +0100 Subject: staging:iio: scan_index_timestamp move to iio_dev from buffer This is just a locally cached value that is device specific (rather than buffer specific.) Hence it wants to come out of the buffer before we add multiple buffer support. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/buffer.h b/drivers/staging/iio/buffer.h index df2046d..3d3ea9e 100644 --- a/drivers/staging/iio/buffer.h +++ b/drivers/staging/iio/buffer.h @@ -56,7 +56,6 @@ struct iio_buffer_access_funcs { * @scan_el_attrs: [DRIVER] control of scan elements if that scan mode * control method is used * @scan_mask: [INTERN] bitmask used in masking scan mode elements - * @scan_index_timestamp:[INTERN] cache of the index to the timestamp * @scan_timestamp: [INTERN] does the scan mode include a timestamp * @access: [DRIVER] buffer access functions associated with the * implementation. @@ -74,7 +73,6 @@ struct iio_buffer { struct attribute_group *scan_el_attrs; long *scan_mask; bool scan_timestamp; - unsigned scan_index_timestamp; const struct iio_buffer_access_funcs *access; struct list_head scan_el_dev_attr_list; struct attribute_group scan_el_group; diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h index a562763..6832c98 100644 --- a/drivers/staging/iio/iio.h +++ b/drivers/staging/iio/iio.h @@ -305,6 +305,7 @@ struct iio_buffer_setup_ops { * @masklength: [INTERN] the length of the mask established from * channels * @active_scan_mask: [INTERN] union of all scan masks requested by buffers + * @scan_index_timestamp:[INTERN] cache of the index to the timestamp * @trig: [INTERN] current device trigger (buffer modes) * @pollfunc: [DRIVER] function run on trigger being received * @channels: [DRIVER] channel specification structure table @@ -339,6 +340,7 @@ struct iio_dev { const unsigned long *available_scan_masks; unsigned masklength; const unsigned long *active_scan_mask; + unsigned scan_index_timestamp; struct iio_trigger *trig; struct iio_poll_func *pollfunc; diff --git a/drivers/staging/iio/industrialio-buffer.c b/drivers/staging/iio/industrialio-buffer.c index 389fe16..0359161 100644 --- a/drivers/staging/iio/industrialio-buffer.c +++ b/drivers/staging/iio/industrialio-buffer.c @@ -296,7 +296,7 @@ int iio_buffer_register(struct iio_dev *indio_dev, goto error_cleanup_dynamic; attrcount += ret; if (channels[i].type == IIO_TIMESTAMP) - buffer->scan_index_timestamp = + indio_dev->scan_index_timestamp = channels[i].scan_index; } if (indio_dev->masklength && buffer->scan_mask == NULL) { @@ -525,8 +525,7 @@ static int iio_compute_scan_bytes(struct iio_dev *indio_dev, const long *mask, } if (timestamp) { ch = iio_find_channel_from_si(indio_dev, - indio_dev - ->buffer->scan_index_timestamp); + indio_dev->scan_index_timestamp); length = ch->scan_type.storagebits / 8; bytes = ALIGN(bytes, length); bytes += length; @@ -721,7 +720,7 @@ int iio_update_demux(struct iio_dev *indio_dev) goto error_clear_mux_table; } ch = iio_find_channel_from_si(indio_dev, - buffer->scan_index_timestamp); + indio_dev->scan_index_timestamp); length = ch->scan_type.storagebits/8; if (out_loc % length) out_loc += length - out_loc % length; -- cgit v0.10.2 From 420fe2e9471518f57a551d2114a54a0aa0c12ea3 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 21 Apr 2012 10:09:35 +0100 Subject: staging:iio: add caching of the number of bytes in a scan. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c index 97f9e6b..1370e32 100644 --- a/drivers/staging/iio/accel/adis16201_ring.c +++ b/drivers/staging/iio/accel/adis16201_ring.c @@ -66,9 +66,8 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p) int i = 0; s16 *data; - size_t datasize = ring->access->get_bytes_per_datum(ring); - data = kmalloc(datasize, GFP_KERNEL); + data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); if (data == NULL) { dev_err(&st->us->dev, "memory alloc failed in ring bh"); return -ENOMEM; diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c index 6a8963d..86f4efb7 100644 --- a/drivers/staging/iio/accel/adis16203_ring.c +++ b/drivers/staging/iio/accel/adis16203_ring.c @@ -66,9 +66,8 @@ static irqreturn_t adis16203_trigger_handler(int irq, void *p) int i = 0; s16 *data; - size_t datasize = ring->access->get_bytes_per_datum(ring); - data = kmalloc(datasize, GFP_KERNEL); + data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); if (data == NULL) { dev_err(&st->us->dev, "memory alloc failed in ring bh"); return -ENOMEM; diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c index 5c8ab73..34ef11f 100644 --- a/drivers/staging/iio/accel/adis16204_ring.c +++ b/drivers/staging/iio/accel/adis16204_ring.c @@ -63,9 +63,8 @@ static irqreturn_t adis16204_trigger_handler(int irq, void *p) struct iio_buffer *ring = indio_dev->buffer; int i = 0; s16 *data; - size_t datasize = ring->access->get_bytes_per_datum(ring); - data = kmalloc(datasize, GFP_KERNEL); + data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); if (data == NULL) { dev_err(&st->us->dev, "memory alloc failed in ring bh"); return -ENOMEM; diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c index 57254b6b..1424d48 100644 --- a/drivers/staging/iio/accel/adis16209_ring.c +++ b/drivers/staging/iio/accel/adis16209_ring.c @@ -61,12 +61,10 @@ static irqreturn_t adis16209_trigger_handler(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct adis16209_state *st = iio_priv(indio_dev); struct iio_buffer *ring = indio_dev->buffer; - int i = 0; s16 *data; - size_t datasize = ring->access->get_bytes_per_datum(ring); - data = kmalloc(datasize , GFP_KERNEL); + data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); if (data == NULL) { dev_err(&st->us->dev, "memory alloc failed in ring bh"); return -ENOMEM; diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c index 43ba84e..9ff0634 100644 --- a/drivers/staging/iio/accel/adis16240_ring.c +++ b/drivers/staging/iio/accel/adis16240_ring.c @@ -61,9 +61,8 @@ static irqreturn_t adis16240_trigger_handler(int irq, void *p) int i = 0; s16 *data; - size_t datasize = ring->access->get_bytes_per_datum(ring); - data = kmalloc(datasize, GFP_KERNEL); + data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); if (data == NULL) { dev_err(&st->us->dev, "memory alloc failed in ring bh"); return -ENOMEM; diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 0fc3973..3bdc102 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -137,9 +137,9 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct iio_buffer *buffer = indio_dev->buffer; int len = 0; - size_t datasize = buffer->access->get_bytes_per_datum(buffer); - char *data = kmalloc(datasize, GFP_KERNEL); + char *data; + data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); if (data == NULL) { dev_err(indio_dev->dev.parent, "memory alloc failed in buffer bh"); diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c index 1ef9fbc..6cbf242 100644 --- a/drivers/staging/iio/adc/ad7606_ring.c +++ b/drivers/staging/iio/adc/ad7606_ring.c @@ -51,8 +51,7 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s) __u8 *buf; int ret; - buf = kzalloc(ring->access->get_bytes_per_datum(ring), - GFP_KERNEL); + buf = kzalloc(indio_dev->scan_bytes, GFP_KERNEL); if (buf == NULL) return; diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c index 711f151..18fc73c 100644 --- a/drivers/staging/iio/gyro/adis16260_ring.c +++ b/drivers/staging/iio/gyro/adis16260_ring.c @@ -66,9 +66,8 @@ static irqreturn_t adis16260_trigger_handler(int irq, void *p) struct iio_buffer *ring = indio_dev->buffer; int i = 0; s16 *data; - size_t datasize = ring->access->get_bytes_per_datum(ring); - data = kmalloc(datasize , GFP_KERNEL); + data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); if (data == NULL) { dev_err(&st->us->dev, "memory alloc failed in ring bh"); return -ENOMEM; diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h index 6832c98..7a10aed 100644 --- a/drivers/staging/iio/iio.h +++ b/drivers/staging/iio/iio.h @@ -299,6 +299,7 @@ struct iio_buffer_setup_ops { * and owner * @event_interface: [INTERN] event chrdevs associated with interrupt lines * @buffer: [DRIVER] any buffer present + * @scan_bytes: [INTERN] num bytes captured to be fed to buffer demux * @mlock: [INTERN] lock used to prevent simultaneous device state * changes * @available_scan_masks: [DRIVER] optional array of allowed bitmasks @@ -335,6 +336,7 @@ struct iio_dev { struct iio_event_interface *event_interface; struct iio_buffer *buffer; + int scan_bytes; struct mutex mlock; const unsigned long *available_scan_masks; diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c index bb4daf7..61a2622 100644 --- a/drivers/staging/iio/iio_simple_dummy_buffer.c +++ b/drivers/staging/iio/iio_simple_dummy_buffer.c @@ -48,12 +48,9 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct iio_buffer *buffer = indio_dev->buffer; int len = 0; - /* - * The datasize is obtained from the buffer. It was stored when - * the preenable setup function was called. - */ - size_t datasize = buffer->access->get_bytes_per_datum(buffer); - u16 *data = kmalloc(datasize, GFP_KERNEL); + u16 *data; + + data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); if (data == NULL) return -ENOMEM; diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c index 8daa038..d964004 100644 --- a/drivers/staging/iio/imu/adis16400_ring.c +++ b/drivers/staging/iio/imu/adis16400_ring.c @@ -119,12 +119,12 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p) struct iio_buffer *ring = indio_dev->buffer; int i = 0, j, ret = 0; s16 *data; - size_t datasize = ring->access->get_bytes_per_datum(ring); + /* Asumption that long is enough for maximum channels */ unsigned long mask = *indio_dev->active_scan_mask; int scan_count = bitmap_weight(indio_dev->active_scan_mask, indio_dev->masklength); - data = kmalloc(datasize , GFP_KERNEL); + data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); if (data == NULL) { dev_err(&st->us->dev, "memory alloc failed in ring bh"); return -ENOMEM; diff --git a/drivers/staging/iio/industrialio-buffer.c b/drivers/staging/iio/industrialio-buffer.c index 0359161..f6cb0ab 100644 --- a/drivers/staging/iio/industrialio-buffer.c +++ b/drivers/staging/iio/industrialio-buffer.c @@ -536,13 +536,13 @@ static int iio_compute_scan_bytes(struct iio_dev *indio_dev, const long *mask, int iio_sw_buffer_preenable(struct iio_dev *indio_dev) { struct iio_buffer *buffer = indio_dev->buffer; - unsigned bytes; dev_dbg(&indio_dev->dev, "%s\n", __func__); /* How much space will the demuxed element take? */ - bytes = iio_compute_scan_bytes(indio_dev, buffer->scan_mask, + indio_dev->scan_bytes = + iio_compute_scan_bytes(indio_dev, buffer->scan_mask, buffer->scan_timestamp); - buffer->access->set_bytes_per_datum(buffer, bytes); + buffer->access->set_bytes_per_datum(buffer, indio_dev->scan_bytes); /* What scan mask do we actually have ?*/ if (indio_dev->available_scan_masks) -- cgit v0.10.2 From 2150489ffbd1cd6f5d1091c1738b1adfbdf34a43 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 21 Apr 2012 10:09:36 +0100 Subject: staging:iio:adc:ad7192 make use of iio_sw_buffer_preenable. This is not a fast path, so although the original code was more consise use the generic case to cut down on code repitition. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index feb81f6..25ef3c3 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -456,31 +456,19 @@ out: static int ad7192_ring_preenable(struct iio_dev *indio_dev) { struct ad7192_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; - size_t d_size; unsigned channel; + int ret; if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) return -EINVAL; + ret = iio_sw_buffer_preenable(indio_dev); + if (ret < 0) + return ret; + channel = find_first_bit(indio_dev->active_scan_mask, indio_dev->masklength); - d_size = bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength) * - indio_dev->channels[0].scan_type.storagebits / 8; - - if (ring->scan_timestamp) { - d_size += sizeof(s64); - - if (d_size % sizeof(s64)) - d_size += sizeof(s64) - (d_size % sizeof(s64)); - } - - if (indio_dev->buffer->access->set_bytes_per_datum) - indio_dev->buffer->access-> - set_bytes_per_datum(indio_dev->buffer, d_size); - st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) | AD7192_MODE_SEL(AD7192_MODE_CONT); st->conf = (st->conf & ~AD7192_CONF_CHAN(-1)) | -- cgit v0.10.2 From 8f03aabc0fbaa795ed6253010b27065fa4159825 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 21 Apr 2012 10:09:37 +0100 Subject: staging:iio:adc:ad7298 use iio_sw_buffer_preenable to avoid code repitition. Here some addition elements are needed, but this generic function cuts down on the amount of code. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/adc/ad7298.h b/drivers/staging/iio/adc/ad7298.h index a0e5dea..5051a7e 100644 --- a/drivers/staging/iio/adc/ad7298.h +++ b/drivers/staging/iio/adc/ad7298.h @@ -38,7 +38,6 @@ struct ad7298_platform_data { struct ad7298_state { struct spi_device *spi; struct regulator *reg; - size_t d_size; u16 int_vref_mv; unsigned ext_ref; struct spi_transfer ring_xfer[10]; diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c index feeb0ee..5c13690 100644 --- a/drivers/staging/iio/adc/ad7298_ring.c +++ b/drivers/staging/iio/adc/ad7298_ring.c @@ -28,25 +28,17 @@ static int ad7298_ring_preenable(struct iio_dev *indio_dev) { struct ad7298_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; - size_t d_size; int i, m; unsigned short command; - int scan_count = bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength); - d_size = scan_count * (AD7298_STORAGE_BITS / 8); - - if (ring->scan_timestamp) { - d_size += sizeof(s64); - - if (d_size % sizeof(s64)) - d_size += sizeof(s64) - (d_size % sizeof(s64)); - } + int scan_count, ret; - if (ring->access->set_bytes_per_datum) - ring->access->set_bytes_per_datum(ring, d_size); + ret = iio_sw_buffer_preenable(indio_dev); + if (ret < 0) + return ret; - st->d_size = d_size; + /* Now compute overall size */ + scan_count = bitmap_weight(indio_dev->active_scan_mask, + indio_dev->masklength); command = AD7298_WRITE | st->ext_ref; @@ -102,7 +94,7 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p) if (ring->scan_timestamp) { time_ns = iio_get_time_ns(); - memcpy((u8 *)buf + st->d_size - sizeof(s64), + memcpy((u8 *)buf + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); } -- cgit v0.10.2 From 46df6378c8484eb3ae054938ffb17c2bea691f7b Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 21 Apr 2012 10:09:38 +0100 Subject: staging:iio:adc:ad7476 use iio_sw_buffer_preenable instead of local version. Now the generic version caches the scan size the version in this driver is redundant. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/adc/ad7476.h b/drivers/staging/iio/adc/ad7476.h index 27f696c..b1dd931 100644 --- a/drivers/staging/iio/adc/ad7476.h +++ b/drivers/staging/iio/adc/ad7476.h @@ -27,7 +27,6 @@ struct ad7476_state { struct spi_device *spi; const struct ad7476_chip_info *chip_info; struct regulator *reg; - size_t d_size; u16 int_vref_mv; struct spi_transfer xfer; struct spi_message msg; diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c index d6af6c0..a090bc3 100644 --- a/drivers/staging/iio/adc/ad7476_ring.c +++ b/drivers/staging/iio/adc/ad7476_ring.c @@ -20,36 +20,6 @@ #include "ad7476.h" -/** - * ad7476_ring_preenable() setup the parameters of the ring before enabling - * - * The complex nature of the setting of the number of bytes per datum is due - * to this driver currently ensuring that the timestamp is stored at an 8 - * byte boundary. - **/ -static int ad7476_ring_preenable(struct iio_dev *indio_dev) -{ - struct ad7476_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; - - st->d_size = bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength) * - st->chip_info->channel[0].scan_type.storagebits / 8; - - if (ring->scan_timestamp) { - st->d_size += sizeof(s64); - - if (st->d_size % sizeof(s64)) - st->d_size += sizeof(s64) - (st->d_size % sizeof(s64)); - } - - if (indio_dev->buffer->access->set_bytes_per_datum) - indio_dev->buffer->access-> - set_bytes_per_datum(indio_dev->buffer, st->d_size); - - return 0; -} - static irqreturn_t ad7476_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; @@ -59,7 +29,7 @@ static irqreturn_t ad7476_trigger_handler(int irq, void *p) __u8 *rxbuf; int b_sent; - rxbuf = kzalloc(st->d_size, GFP_KERNEL); + rxbuf = kzalloc(indio_dev->scan_bytes, GFP_KERNEL); if (rxbuf == NULL) return -ENOMEM; @@ -71,7 +41,7 @@ static irqreturn_t ad7476_trigger_handler(int irq, void *p) time_ns = iio_get_time_ns(); if (indio_dev->buffer->scan_timestamp) - memcpy(rxbuf + st->d_size - sizeof(s64), + memcpy(rxbuf + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); indio_dev->buffer->access->store_to(indio_dev->buffer, rxbuf, time_ns); @@ -83,7 +53,7 @@ done: } static const struct iio_buffer_setup_ops ad7476_ring_setup_ops = { - .preenable = &ad7476_ring_preenable, + .preenable = &iio_sw_buffer_preenable, .postenable = &iio_triggered_buffer_postenable, .predisable = &iio_triggered_buffer_predisable, }; -- cgit v0.10.2 From 81a4fc01217c12b42af8a992dcf7fa9cc8373297 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 21 Apr 2012 10:09:39 +0100 Subject: staging:iio:adc:ad7793 use iio_sw_buffer_preenable to avoid repitition. Now the generic function caches the scan size a lot of what was here was redundant and is removed. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index 9d21e39..2aeeaa2 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -319,31 +319,18 @@ out: static int ad7793_ring_preenable(struct iio_dev *indio_dev) { struct ad7793_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; - size_t d_size; unsigned channel; + int ret; if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) return -EINVAL; + ret = iio_sw_buffer_preenable(indio_dev); + if (ret < 0) + return ret; channel = find_first_bit(indio_dev->active_scan_mask, indio_dev->masklength); - d_size = bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength) * - indio_dev->channels[0].scan_type.storagebits / 8; - - if (ring->scan_timestamp) { - d_size += sizeof(s64); - - if (d_size % sizeof(s64)) - d_size += sizeof(s64) - (d_size % sizeof(s64)); - } - - if (indio_dev->buffer->access->set_bytes_per_datum) - indio_dev->buffer->access-> - set_bytes_per_datum(indio_dev->buffer, d_size); - st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | AD7793_MODE_SEL(AD7793_MODE_CONT); st->conf = (st->conf & ~AD7793_CONF_CHAN(-1)) | -- cgit v0.10.2 From a64c0634e561c7236f8da5782c8023ec05f8fb5a Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 21 Apr 2012 10:09:40 +0100 Subject: staging:iio:adc:ad7887 make use of iio_sw_buffer_preenable. Using this generic function cuts down on repeated code at the cost of some computation in a slow path. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/adc/ad7887.h b/drivers/staging/iio/adc/ad7887.h index bc53b65..2e09e54 100644 --- a/drivers/staging/iio/adc/ad7887.h +++ b/drivers/staging/iio/adc/ad7887.h @@ -63,7 +63,6 @@ struct ad7887_state { struct spi_device *spi; const struct ad7887_chip_info *chip_info; struct regulator *reg; - size_t d_size; u16 int_vref_mv; struct spi_transfer xfer[4]; struct spi_message msg[3]; diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c index d180907..442994e 100644 --- a/drivers/staging/iio/adc/ad7887_ring.c +++ b/drivers/staging/iio/adc/ad7887_ring.c @@ -29,22 +29,11 @@ static int ad7887_ring_preenable(struct iio_dev *indio_dev) { struct ad7887_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; - - st->d_size = bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength) * - st->chip_info->channel[0].scan_type.storagebits / 8; - - if (ring->scan_timestamp) { - st->d_size += sizeof(s64); - - if (st->d_size % sizeof(s64)) - st->d_size += sizeof(s64) - (st->d_size % sizeof(s64)); - } + int ret; - if (indio_dev->buffer->access->set_bytes_per_datum) - indio_dev->buffer->access-> - set_bytes_per_datum(indio_dev->buffer, st->d_size); + ret = iio_sw_buffer_preenable(indio_dev); + if (ret < 0) + return ret; /* We know this is a single long so can 'cheat' */ switch (*indio_dev->active_scan_mask) { @@ -92,7 +81,7 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p) indio_dev->masklength) * st->chip_info->channel[0].scan_type.storagebits / 8; - buf = kzalloc(st->d_size, GFP_KERNEL); + buf = kzalloc(indio_dev->scan_bytes, GFP_KERNEL); if (buf == NULL) return -ENOMEM; @@ -104,7 +93,7 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p) memcpy(buf, st->data, bytes); if (ring->scan_timestamp) - memcpy(buf + st->d_size - sizeof(s64), + memcpy(buf + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); indio_dev->buffer->access->store_to(indio_dev->buffer, buf, time_ns); -- cgit v0.10.2 From c1633187829aa11a475ab6e453f05d3f6a172aff Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 21 Apr 2012 10:09:41 +0100 Subject: staging:iio:adc:ad799x use iio_sw_buffer_preenable to avoid code repitiion Using this generic function cuts down on repeated code at the cost of a little overhead in a slow path. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/adc/ad799x.h b/drivers/staging/iio/adc/ad799x.h index 356f690..99f8abe 100644 --- a/drivers/staging/iio/adc/ad799x.h +++ b/drivers/staging/iio/adc/ad799x.h @@ -104,7 +104,6 @@ struct ad799x_chip_info { struct ad799x_state { struct i2c_client *client; const struct ad799x_chip_info *chip_info; - size_t d_size; struct iio_trigger *trig; struct regulator *reg; u16 int_vref_mv; diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c index 069765c..dfdbf92 100644 --- a/drivers/staging/iio/adc/ad799x_ring.c +++ b/drivers/staging/iio/adc/ad799x_ring.c @@ -32,9 +32,7 @@ **/ static int ad799x_ring_preenable(struct iio_dev *indio_dev) { - struct iio_buffer *ring = indio_dev->buffer; struct ad799x_state *st = iio_priv(indio_dev); - /* * Need to figure out the current mode based upon the requested * scan mask in iio_dev @@ -43,21 +41,7 @@ static int ad799x_ring_preenable(struct iio_dev *indio_dev) if (st->id == ad7997 || st->id == ad7998) ad7997_8_set_scan_mode(st, *indio_dev->active_scan_mask); - st->d_size = bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength) * 2; - - if (ring->scan_timestamp) { - st->d_size += sizeof(s64); - - if (st->d_size % sizeof(s64)) - st->d_size += sizeof(s64) - (st->d_size % sizeof(s64)); - } - - if (indio_dev->buffer->access->set_bytes_per_datum) - indio_dev->buffer->access-> - set_bytes_per_datum(indio_dev->buffer, st->d_size); - - return 0; + return iio_sw_buffer_preenable(indio_dev); } /** @@ -78,7 +62,7 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p) int b_sent; u8 cmd; - rxbuf = kmalloc(st->d_size, GFP_KERNEL); + rxbuf = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); if (rxbuf == NULL) goto out; @@ -112,7 +96,7 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p) time_ns = iio_get_time_ns(); if (ring->scan_timestamp) - memcpy(rxbuf + st->d_size - sizeof(s64), + memcpy(rxbuf + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); ring->access->store_to(indio_dev->buffer, rxbuf, time_ns); -- cgit v0.10.2 From c562ccbf584f8017a153bbd5c1039a189e1f8be8 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 21 Apr 2012 10:09:42 +0100 Subject: staging:iio:meter:ad7758 use iio_sw_buffer_preenable to avoid code repition Using this generic function adds a little overhead to a slow path but reduces the amount of code repitition in exchange. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c index c45b23b..3dfd788 100644 --- a/drivers/staging/iio/meter/ade7758_ring.c +++ b/drivers/staging/iio/meter/ade7758_ring.c @@ -92,29 +92,19 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p) static int ade7758_ring_preenable(struct iio_dev *indio_dev) { struct ade7758_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; - size_t d_size; unsigned channel; + int ret; if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) return -EINVAL; + ret = iio_sw_buffer_preenable(indio_dev); + if (ret < 0) + return ret; + channel = find_first_bit(indio_dev->active_scan_mask, indio_dev->masklength); - d_size = st->ade7758_ring_channels[channel].scan_type.storagebits / 8; - - if (ring->scan_timestamp) { - d_size += sizeof(s64); - - if (d_size % sizeof(s64)) - d_size += sizeof(s64) - (d_size % sizeof(s64)); - } - - if (indio_dev->buffer->access->set_bytes_per_datum) - indio_dev->buffer->access-> - set_bytes_per_datum(indio_dev->buffer, d_size); - ade7758_write_waveform_type(&indio_dev->dev, st->ade7758_ring_channels[channel].address); -- cgit v0.10.2 From f5ee7b807fc90756d6852690a3777db7093efe0d Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 21 Apr 2012 10:09:43 +0100 Subject: staging:iio:impedance-analyser make use of iio_sw_buffer_preenable This avoids some code duplication by using the generic form in a non performance critical place. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 93e5a71..8a0485e 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -569,19 +569,14 @@ static const struct iio_info ad5933_info = { static int ad5933_ring_preenable(struct iio_dev *indio_dev) { struct ad5933_state *st = iio_priv(indio_dev); - size_t d_size; int ret; if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) return -EINVAL; - d_size = bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength) * - ad5933_channels[1].scan_type.storagebits / 8; - - if (indio_dev->buffer->access->set_bytes_per_datum) - indio_dev->buffer->access-> - set_bytes_per_datum(indio_dev->buffer, d_size); + ret = iio_sw_buffer_preenable(indio_dev); + if (ret < 0) + return ret; ret = ad5933_reset(st); if (ret < 0) -- cgit v0.10.2 From fd6487f8439f7859acf17589f1d612285b5c0fa5 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 21 Apr 2012 10:09:44 +0100 Subject: staging:iio: Add caching of scan_timestamp to the core as well as buffers. This will be needed when multiple buffer support is added. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c index 1370e32..49912e2 100644 --- a/drivers/staging/iio/accel/adis16201_ring.c +++ b/drivers/staging/iio/accel/adis16201_ring.c @@ -80,7 +80,7 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p) data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); /* Guaranteed to be aligned with 8 byte boundary */ - if (ring->scan_timestamp) + if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; ring->access->store_to(ring, (u8 *)data, pf->timestamp); diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c index 86f4efb7..5c40f6c 100644 --- a/drivers/staging/iio/accel/adis16203_ring.c +++ b/drivers/staging/iio/accel/adis16203_ring.c @@ -80,7 +80,7 @@ static irqreturn_t adis16203_trigger_handler(int irq, void *p) data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); /* Guaranteed to be aligned with 8 byte boundary */ - if (ring->scan_timestamp) + if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; ring->access->store_to(ring, diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c index 34ef11f..bf5488e 100644 --- a/drivers/staging/iio/accel/adis16204_ring.c +++ b/drivers/staging/iio/accel/adis16204_ring.c @@ -77,7 +77,7 @@ static irqreturn_t adis16204_trigger_handler(int irq, void *p) data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); /* Guaranteed to be aligned with 8 byte boundary */ - if (ring->scan_timestamp) + if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; ring->access->store_to(ring, (u8 *)data, pf->timestamp); diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c index 1424d48..3101c53 100644 --- a/drivers/staging/iio/accel/adis16209_ring.c +++ b/drivers/staging/iio/accel/adis16209_ring.c @@ -77,7 +77,7 @@ static irqreturn_t adis16209_trigger_handler(int irq, void *p) data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); /* Guaranteed to be aligned with 8 byte boundary */ - if (ring->scan_timestamp) + if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; ring->access->store_to(ring, (u8 *)data, pf->timestamp); diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c index 9ff0634..c4459f7 100644 --- a/drivers/staging/iio/accel/adis16240_ring.c +++ b/drivers/staging/iio/accel/adis16240_ring.c @@ -75,7 +75,7 @@ static irqreturn_t adis16240_trigger_handler(int irq, void *p) data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); /* Guaranteed to be aligned with 8 byte boundary */ - if (ring->scan_timestamp) + if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; ring->access->store_to(ring, (u8 *)data, pf->timestamp); diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 3bdc102..ebd5b4d 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -150,7 +150,7 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p) len = lis3l02dq_get_buffer_element(indio_dev, data); /* Guaranteed to be aligned with 8 byte boundary */ - if (buffer->scan_timestamp) + if (indio_dev->scan_timestamp) *(s64 *)(((phys_addr_t)data + len + sizeof(s64) - 1) & ~(sizeof(s64) - 1)) = pf->timestamp; diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 25ef3c3..5d31685 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -521,7 +521,7 @@ static irqreturn_t ad7192_trigger_handler(int irq, void *p) indio_dev->channels[0].scan_type.realbits/8); /* Guaranteed to be aligned with 8 byte boundary */ - if (ring->scan_timestamp) + if (indio_dev->scan_timestamp) dat64[1] = pf->timestamp; ring->access->store_to(ring, (u8 *)dat64, pf->timestamp); diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c index 5c13690..538e3b3 100644 --- a/drivers/staging/iio/adc/ad7298_ring.c +++ b/drivers/staging/iio/adc/ad7298_ring.c @@ -92,7 +92,7 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p) if (b_sent) return b_sent; - if (ring->scan_timestamp) { + if (indio_dev->scan_timestamp) { time_ns = iio_get_time_ns(); memcpy((u8 *)buf + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c index a090bc3..8534f6b 100644 --- a/drivers/staging/iio/adc/ad7476_ring.c +++ b/drivers/staging/iio/adc/ad7476_ring.c @@ -40,7 +40,7 @@ static irqreturn_t ad7476_trigger_handler(int irq, void *p) time_ns = iio_get_time_ns(); - if (indio_dev->buffer->scan_timestamp) + if (indio_dev->scan_timestamp) memcpy(rxbuf + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c index 6cbf242..007b600 100644 --- a/drivers/staging/iio/adc/ad7606_ring.c +++ b/drivers/staging/iio/adc/ad7606_ring.c @@ -81,9 +81,8 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s) time_ns = iio_get_time_ns(); - if (ring->scan_timestamp) - *((s64 *)(buf + ring->access->get_bytes_per_datum(ring) - - sizeof(s64))) = time_ns; + if (indio_dev->scan_timestamp) + *((s64 *)(buf + indio_dev->scan_bytes - sizeof(s64))) = time_ns; ring->access->store_to(indio_dev->buffer, buf, time_ns); done: diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index 2aeeaa2..7f68c7c 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -386,7 +386,7 @@ static irqreturn_t ad7793_trigger_handler(int irq, void *p) indio_dev->channels[0].scan_type.realbits/8); /* Guaranteed to be aligned with 8 byte boundary */ - if (ring->scan_timestamp) + if (indio_dev->scan_timestamp) dat64[1] = pf->timestamp; ring->access->store_to(ring, (u8 *)dat64, pf->timestamp); diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c index 442994e..62681a8 100644 --- a/drivers/staging/iio/adc/ad7887_ring.c +++ b/drivers/staging/iio/adc/ad7887_ring.c @@ -72,7 +72,6 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct ad7887_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; s64 time_ns; __u8 *buf; int b_sent; @@ -92,7 +91,7 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p) time_ns = iio_get_time_ns(); memcpy(buf, st->data, bytes); - if (ring->scan_timestamp) + if (indio_dev->scan_timestamp) memcpy(buf + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c index dfdbf92..5190e50 100644 --- a/drivers/staging/iio/adc/ad799x_ring.c +++ b/drivers/staging/iio/adc/ad799x_ring.c @@ -95,7 +95,7 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p) time_ns = iio_get_time_ns(); - if (ring->scan_timestamp) + if (indio_dev->scan_timestamp) memcpy(rxbuf + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c index d0a60a3..8372e98 100644 --- a/drivers/staging/iio/adc/max1363_ring.c +++ b/drivers/staging/iio/adc/max1363_ring.c @@ -54,7 +54,7 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p) d_size = numvals*2; else d_size = numvals; - if (indio_dev->buffer->scan_timestamp) { + if (indio_dev->scan_timestamp) { d_size += sizeof(s64); if (d_size % sizeof(s64)) d_size += sizeof(s64) - (d_size % sizeof(s64)); @@ -78,7 +78,7 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p) time_ns = iio_get_time_ns(); - if (indio_dev->buffer->scan_timestamp) + if (indio_dev->scan_timestamp) memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns)); iio_push_to_buffer(indio_dev->buffer, rxbuf, time_ns); diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c index 18fc73c..046f84d 100644 --- a/drivers/staging/iio/gyro/adis16260_ring.c +++ b/drivers/staging/iio/gyro/adis16260_ring.c @@ -80,7 +80,7 @@ static irqreturn_t adis16260_trigger_handler(int irq, void *p) data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); /* Guaranteed to be aligned with 8 byte boundary */ - if (ring->scan_timestamp) + if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; ring->access->store_to(ring, (u8 *)data, pf->timestamp); diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h index 7a10aed..0770340 100644 --- a/drivers/staging/iio/iio.h +++ b/drivers/staging/iio/iio.h @@ -306,6 +306,7 @@ struct iio_buffer_setup_ops { * @masklength: [INTERN] the length of the mask established from * channels * @active_scan_mask: [INTERN] union of all scan masks requested by buffers + * @scan_timestamp: [INTERN] set if any buffers have requested timestamp * @scan_index_timestamp:[INTERN] cache of the index to the timestamp * @trig: [INTERN] current device trigger (buffer modes) * @pollfunc: [DRIVER] function run on trigger being received @@ -342,6 +343,7 @@ struct iio_dev { const unsigned long *available_scan_masks; unsigned masklength; const unsigned long *active_scan_mask; + bool scan_timestamp; unsigned scan_index_timestamp; struct iio_trigger *trig; struct iio_poll_func *pollfunc; diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c index 61a2622..49e7aa1 100644 --- a/drivers/staging/iio/iio_simple_dummy_buffer.c +++ b/drivers/staging/iio/iio_simple_dummy_buffer.c @@ -84,7 +84,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) } } /* Store a timestampe at an 8 byte boundary */ - if (buffer->scan_timestamp) + if (indio_dev->scan_timestamp) *(s64 *)(((phys_addr_t)data + len + sizeof(s64) - 1) & ~(sizeof(s64) - 1)) = iio_get_time_ns(); diff --git a/drivers/staging/iio/industrialio-buffer.c b/drivers/staging/iio/industrialio-buffer.c index f6cb0ab..6c329f95 100644 --- a/drivers/staging/iio/industrialio-buffer.c +++ b/drivers/staging/iio/industrialio-buffer.c @@ -185,6 +185,7 @@ static ssize_t iio_scan_el_ts_store(struct device *dev, goto error_ret; } indio_dev->buffer->scan_timestamp = state; + indio_dev->scan_timestamp = state; error_ret: mutex_unlock(&indio_dev->mlock); diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c index 3dfd788..b37bc98 100644 --- a/drivers/staging/iio/meter/ade7758_ring.c +++ b/drivers/staging/iio/meter/ade7758_ring.c @@ -72,7 +72,7 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p) *dat32 = get_unaligned_be32(&st->rx_buf[5]) & 0xFFFFFF; /* Guaranteed to be aligned with 8 byte boundary */ - if (ring->scan_timestamp) + if (indio_dev->scan_timestamp) dat64[1] = pf->timestamp; ring->access->store_to(ring, (u8 *)dat64, pf->timestamp); -- cgit v0.10.2 From 842cd100441e8542e2b0859a898220ee32cd566e Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 21 Apr 2012 10:09:45 +0100 Subject: staging:iio: pull out demux cleanup for a particular buffer. This will come in handy again when we move to multiple buffers so lets pull it out into a little utility function now. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/industrialio-buffer.c b/drivers/staging/iio/industrialio-buffer.c index 6c329f95..b409b95 100644 --- a/drivers/staging/iio/industrialio-buffer.c +++ b/drivers/staging/iio/industrialio-buffer.c @@ -655,19 +655,25 @@ int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data, } EXPORT_SYMBOL_GPL(iio_push_to_buffer); +static void iio_buffer_demux_free(struct iio_buffer *buffer) +{ + struct iio_demux_table *p, *q; + list_for_each_entry_safe(p, q, &buffer->demux_list, l) { + list_del(&p->l); + kfree(p); + } +} + int iio_update_demux(struct iio_dev *indio_dev) { const struct iio_chan_spec *ch; struct iio_buffer *buffer = indio_dev->buffer; int ret, in_ind = -1, out_ind, length; unsigned in_loc = 0, out_loc = 0; - struct iio_demux_table *p, *q; + struct iio_demux_table *p; /* Clear out any old demux */ - list_for_each_entry_safe(p, q, &buffer->demux_list, l) { - list_del(&p->l); - kfree(p); - } + iio_buffer_demux_free(buffer); kfree(buffer->demux_bounce); buffer->demux_bounce = NULL; @@ -742,10 +748,8 @@ int iio_update_demux(struct iio_dev *indio_dev) return 0; error_clear_mux_table: - list_for_each_entry_safe(p, q, &buffer->demux_list, l) { - list_del(&p->l); - kfree(p); - } + iio_buffer_demux_free(buffer); + return ret; } EXPORT_SYMBOL_GPL(iio_update_demux); -- cgit v0.10.2 From cd01712397ad428f443c05add5d7435e899c0ef1 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 23 Apr 2012 07:36:52 -0700 Subject: staging: rtl8192e: Fix typos. Signed-off-by: Justin P. Mattock ACKed-by: Larry Finger Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192e/rtl8192e/r819xE_phyreg.h b/drivers/staging/rtl8192e/rtl8192e/r819xE_phyreg.h index d5de279..970298b 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r819xE_phyreg.h +++ b/drivers/staging/rtl8192e/rtl8192e/r819xE_phyreg.h @@ -306,7 +306,7 @@ #define bRFStart 0x0000f000 #define bBBStart 0x000000f0 #define bBBCCKStart 0x0000000f -/* Reg)x814 */ +/* Reg x814 */ #define bPAEnd 0xf #define bTREnd 0x0f000000 #define bRFEnd 0x000f0000 @@ -844,7 +844,7 @@ #define bRTL8258_RxLPFBW 0xc00 #define bRTL8258_RSSILPFBW 0xc0 -/* byte endable for sb_write */ +/* byte enable for sb_write */ #define bByte0 0x1 #define bByte1 0x2 #define bByte2 0x4 diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 7c676c2..97a5f49 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -1025,7 +1025,7 @@ static int rtl8192_sta_down(struct net_device *dev, bool shutdownrf) break; } RT_TRACE(COMP_DBG, "===>%s():RF is in progress, need to wait " - "until rf chang is done.\n", __func__); + "until rf change is done.\n", __func__); mdelay(1); RFInProgressTimeOut++; spin_lock_irqsave(&priv->rf_ps_lock, flags); diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index f026b71..2dfb0f0 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -493,7 +493,7 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev) if (priv->bResetInProgress) { RT_TRACE(COMP_POWER_TRACKING, - "we are in slient reset progress, so return\n"); + "we are in silent reset progress, so return\n"); write_nic_byte(dev, Pw_Track_Flag, 0); write_nic_byte(dev, FW_Busy_Flag, 0); return; diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index e26aec8..d7460ae 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -169,7 +169,7 @@ struct cb_desc { u8 nStuckCount; - /* Tx Firmware Relaged flags (10-11)*/ + /* Tx Firmware Related flags (10-11)*/ u8 bCTSEnable:1; u8 bRTSEnable:1; u8 bUseShortGI:1; @@ -1690,7 +1690,7 @@ enum rtllib_state { /* the association procedure is sending AUTH request*/ RTLLIB_ASSOCIATING_AUTHENTICATING, - /* the association procedure has successfully authentcated + /* the association procedure has successfully authenticated * and is sending association request */ RTLLIB_ASSOCIATING_AUTHENTICATED, @@ -2409,7 +2409,7 @@ struct rtllib_device { /* used instead of hard_start_xmit (not softmac_hard_start_xmit) * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data - * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set + * frames. If the option IEEE_SOFTMAC_SINGLE_QUEUE is also set * then also management frames are sent via this callback. * This function can't sleep. */ @@ -2422,12 +2422,12 @@ struct rtllib_device { */ void (*data_hard_stop)(struct net_device *dev); - /* OK this is complementar to data_poll_hard_stop */ + /* OK this is complementing to data_poll_hard_stop */ void (*data_hard_resume)(struct net_device *dev); /* ask to the driver to retune the radio . * This function can sleep. the driver should ensure - * the radio has been swithced before return. + * the radio has been switched before return. */ void (*set_chan)(struct net_device *dev, short ch); @@ -2438,7 +2438,7 @@ struct rtllib_device { * The syncro version is similar to the start_scan but * does not return until all channels has been scanned. * this is called in user context and should sleep, - * it is called in a work_queue when swithcing to ad-hoc mode + * it is called in a work_queue when switching to ad-hoc mode * or in behalf of iwlist scan when the card is associated * and root user ask for a scan. * the fucntion stop_scan should stop both the syncro and @@ -2481,7 +2481,7 @@ struct rtllib_device { struct rtllib_network *network); - /* check whether Tx hw resouce available */ + /* check whether Tx hw resource available */ short (*check_nic_enough_desc)(struct net_device *dev, int queue_index); short (*get_nic_desc_num)(struct net_device *dev, int queue_index); void (*SetBWModeHandler)(struct net_device *dev, @@ -2543,10 +2543,10 @@ struct rtllib_device { /* Generate probe requests */ #define IEEE_SOFTMAC_PROBERQ (1<<4) -/* Generate respones to probe requests */ +/* Generate response to probe requests */ #define IEEE_SOFTMAC_PROBERS (1<<5) -/* The ieee802.11 stack will manages the netif queue +/* The ieee802.11 stack will manage the netif queue * wake/stop for the driver, taking care of 802.11 * fragmentation. See softmac.c for details. */ #define IEEE_SOFTMAC_TX_QUEUE (1<<7) diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index 13979b5..40a59c9 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -496,7 +496,7 @@ void rtllib_indicate_packets(struct rtllib_device *ieee, struct rtllib_rxb **prx memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN); } - /* Indicat the packets to upper layer */ + /* Indicate the packets to upper layer */ if (sub_skb) { stats->rx_packets++; stats->rx_bytes += sub_skb->len; @@ -1233,7 +1233,7 @@ static void rtllib_rx_indicate_pkt_legacy(struct rtllib_device *ieee, if (is_multicast_ether_addr(dst)) ieee->stats.multicast++; - /* Indicat the packets to upper layer */ + /* Indicate the packets to upper layer */ memset(sub_skb->cb, 0, sizeof(sub_skb->cb)); sub_skb->protocol = eth_type_trans(sub_skb, dev); sub_skb->dev = dev; diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index ec98ed7..a21b4d9 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -31,7 +31,7 @@ short rtllib_is_shortslot(const struct rtllib_network *net) return net->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME; } -/* returns the total length needed for pleacing the RATE MFIE +/* returns the total length needed for placing the RATE MFIE * tag and the EXTENDED RATE MFIE tag if needed. * It encludes two bytes per tag for the tag itself and its len */ @@ -49,7 +49,7 @@ static unsigned int rtllib_MFIE_rate_len(struct rtllib_device *ieee) return rate_len; } -/* pleace the MFIE rate, tag to the memory (double) poined. +/* place the MFIE rate, tag to the memory (double) pointed. * Then it updates the pointer so that * it points after the new MFIE tag added. */ @@ -557,7 +557,7 @@ void rtllib_softmac_scan_syncro(struct rtllib_device *ieee, u8 is_mesh) * new network events, despite for updating the net list, * but we are temporarly 'unlinked' as the driver shall * not filter RX frames and the channel is changing. - * So the only situation in witch are interested is to check + * So the only situation in which are interested is to check * if the state become LINKED because of the #1 situation */ @@ -1681,7 +1681,7 @@ inline void rtllib_softmac_new_net(struct rtllib_device *ieee, /* if the user set the AP check if match. * if the network does not broadcast essid we check the - * user supplyed ANY essid + * user supplied ANY essid * if the network does broadcast and the user does not set * essid it is OK * if the network does broadcast and the user did set essid @@ -2444,16 +2444,16 @@ inline int rtllib_rx_frame_softmac(struct rtllib_device *ieee, /* following are for a simplier TX queue management. * Instead of using netif_[stop/wake]_queue the driver - * will uses these two function (plus a reset one), that - * will internally uses the kernel netif_* and takes + * will use these two functions (plus a reset one), that + * will internally use the kernel netif_* and takes * care of the ieee802.11 fragmentation. * So the driver receives a fragment per time and might - * call the stop function when it want without take care - * to have enought room to TX an entire packet. - * This might be useful if each fragment need it's own + * call the stop function when it wants to not + * have enough room to TX an entire packet. + * This might be useful if each fragment needs it's own * descriptor, thus just keep a total free memory > than - * the max fragmentation treshold is not enought.. If the - * ieee802.11 stack passed a TXB struct then you needed + * the max fragmentation threshold is not enough.. If the + * ieee802.11 stack passed a TXB struct then you need * to keep N free descriptors where * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD * In this way you need just one and the 802.11 stack @@ -2696,15 +2696,15 @@ static void rtllib_start_ibss_wq(void *data) rtllib_softmac_check_all_nets(ieee); - /* if not then the state is not linked. Maybe the user swithced to + /* if not then the state is not linked. Maybe the user switched to * ad-hoc mode just after being in monitor mode, or just after * being very few time in managed mode (so the card have had no * time to scan all the chans..) or we have just run up the iface * after setting ad-hoc mode. So we have to give another try.. * Here, in ibss mode, should be safe to do this without extra care - * (in bss mode we had to make sure no-one tryed to associate when + * (in bss mode we had to make sure no-one tried to associate when * we had just checked the ieee->state and we was going to start the - * scan) beacause in ibss mode the rtllib_new_net function, when + * scan) because in ibss mode the rtllib_new_net function, when * finds a good net, just set the ieee->state to RTLLIB_LINKED, * so, at worst, we waste a bit of time to initiate an unneeded syncro * scan, that will stop at the first round because it sees the state @@ -2819,7 +2819,7 @@ void rtllib_start_bss(struct rtllib_device *ieee) /* ensure no-one start an associating process (thus setting * the ieee->state to rtllib_ASSOCIATING) while we - * have just cheked it and we are going to enable scan. + * have just checked it and we are going to enable scan. * The rtllib_new_net function is always called with * lock held (from both rtllib_softmac_check_all_nets and * the rx path), so we cannot be in the middle of such function @@ -2872,7 +2872,7 @@ static void rtllib_associate_retry_wq(void *data) /* until we do not set the state to RTLLIB_NOLINK * there are no possibility to have someone else trying - * to start an association procdure (we get here with + * to start an association procedure (we get here with * ieee->state = RTLLIB_ASSOCIATING). * When we set the state to RTLLIB_NOLINK it is possible * that the RX path run an attempt to associate, but diff --git a/drivers/staging/rtl8192e/rtllib_softmac_wx.c b/drivers/staging/rtl8192e/rtllib_softmac_wx.c index 1523bc7..1bb6b52e 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac_wx.c +++ b/drivers/staging/rtl8192e/rtllib_softmac_wx.c @@ -479,7 +479,7 @@ int rtllib_wx_set_essid(struct rtllib_device *ieee, /* this is just to be sure that the GET wx callback - * has consisten infos. not needed otherwise + * has consistent infos. not needed otherwise */ spin_lock_irqsave(&ieee->lock, flags); @@ -575,7 +575,7 @@ int rtllib_wx_set_power(struct rtllib_device *ieee, if ((!ieee->sta_wake_up) || (!ieee->enter_sleep_state) || (!ieee->ps_is_queue_empty)) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, "%s(): PS mode is tryied to be use " + RTLLIB_DEBUG(RTLLIB_DL_ERR, "%s(): PS mode is tried to be use " "but driver missed a callback\n\n", __func__); return -1; } diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c index f451bfc..f24aa00c 100644 --- a/drivers/staging/rtl8192e/rtllib_tx.c +++ b/drivers/staging/rtl8192e/rtllib_tx.c @@ -59,7 +59,7 @@ 802.11 Data Frame -802.11 frame_contorl for data frames - 2 bytes +802.11 frame_control for data frames - 2 bytes ,-----------------------------------------------------------------------------------------. bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------| @@ -576,7 +576,7 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) spin_lock_irqsave(&ieee->lock, flags); - /* If there is no driver handler to take the TXB, dont' bother + /* If there is no driver handler to take the TXB, don't bother * creating it... */ if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)) || @@ -738,7 +738,7 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS)) bytes_per_frag -= RTLLIB_FCS_LEN; - /* Each fragment may need to have room for encryptiong + /* Each fragment may need to have room for encrypting * pre/postfix */ if (encrypt) { bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len + diff --git a/drivers/staging/rtl8192e/rtllib_wx.c b/drivers/staging/rtl8192e/rtllib_wx.c index e5fe2e8..c7e8d4d8 100644 --- a/drivers/staging/rtl8192e/rtllib_wx.c +++ b/drivers/staging/rtl8192e/rtllib_wx.c @@ -408,7 +408,7 @@ int rtllib_wx_set_encode(struct rtllib_device *ieee, (*crypt)->priv); sec.flags |= (1 << key); /* This ensures a key will be activated if no key is - * explicitely set */ + * explicitly set */ if (key == sec.active_key) sec.flags |= SEC_ACTIVE_KEY; ieee->crypt_info.tx_keyidx = key; -- cgit v0.10.2 From bb75f7dc948eb92b1d0612b4ddba23d2ecd553c5 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Mon, 23 Apr 2012 01:47:45 +0900 Subject: staging, sep: Fix typo in sep Correct spelling typos in staging/sep. Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h index fa7c0d0..9d9fc7c 100644 --- a/drivers/staging/sep/sep_driver_config.h +++ b/drivers/staging/sep/sep_driver_config.h @@ -68,11 +68,11 @@ #define SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE 16 /* flag that signifies tah the lock is -currently held by the proccess (struct file) */ +currently held by the process (struct file) */ #define SEP_DRIVER_OWN_LOCK_FLAG 1 /* flag that signifies tah the lock is currently NOT -held by the proccess (struct file) */ +held by the process (struct file) */ #define SEP_DRIVER_DISOWN_LOCK_FLAG 0 /* indicates whether driver has mapped/unmapped shared area */ @@ -280,7 +280,7 @@ held by the proccess (struct file) */ /* * Used to limit number of concurrent processes - * allowed to allocte dynamic buffers in fastcall + * allowed to allocate dynamic buffers in fastcall * interface. */ #define SEP_DOUBLEBUF_USERS_LIMIT 3 diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c index ad54c2e..7c2e971 100644 --- a/drivers/staging/sep/sep_main.c +++ b/drivers/staging/sep/sep_main.c @@ -786,7 +786,7 @@ static unsigned int sep_poll(struct file *filp, poll_table *wait) "[PID%d] poll: send_ct is %lx reply ct is %lx\n", current->pid, sep->send_ct, sep->reply_ct); - /* Check if error occured during poll */ + /* Check if error occurred during poll */ retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); if ((retval2 != 0x0) && (retval2 != 0x8)) { dev_dbg(&sep->pdev->dev, "[PID%d] poll; poll error %x\n", @@ -1160,7 +1160,7 @@ static int sep_lock_kernel_pages(struct sep_device *sep, /* Put mapped kernel sg into kernel resource array */ - /* Set output params acording to the in_out flag */ + /* Set output params according to the in_out flag */ if (in_out_flag == SEP_DRIVER_IN_FLAG) { *lli_array_ptr = lli_array; dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages = @@ -1358,7 +1358,7 @@ static int sep_lock_user_pages(struct sep_device *sep, lli_array[num_pages - 1].block_size); } - /* Set output params acording to the in_out flag */ + /* Set output params according to the in_out flag */ if (in_out_flag == SEP_DRIVER_IN_FLAG) { *lli_array_ptr = lli_array; dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages = @@ -2038,7 +2038,7 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, /* * If this is not the last table - - * then allign it to the block size + * then align it to the block size */ if (!last_table_flag) table_data_size = @@ -3033,7 +3033,7 @@ static int sep_free_dcb_handler(struct sep_device *sep, * @cmd: command * @arg: pointer to argument structure * - * Implement the ioctl methods availble on the SEP device. + * Implement the ioctl methods available on the SEP device. */ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { @@ -4460,7 +4460,7 @@ static int sep_pm_runtime_suspend(struct device *dev) * @sep_pm_runtime_resume: resume- no communication with cpu & main memory * @sep_pm_runtime_suspend: suspend- no communication with cpu & main memory * @sep_pci_suspend: suspend - main memory is still ON - * @sep_pci_resume: resume - main meory is still ON + * @sep_pci_resume: resume - main memory is still ON */ static const struct dev_pm_ops sep_pm = { .runtime_resume = sep_pm_runtime_resume, -- cgit v0.10.2 From 89f5e7102a56bcd1b5b0691085d0839e92b3ca04 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 22 Apr 2012 14:02:13 +0200 Subject: drivers/staging/rtl8192u/ieee80211/ieee80211_module.c: add missing free_netdev Free dev on failure as done elsewhere in the function. Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c index e3d47bc..82d4bf6 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c @@ -161,7 +161,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv) if (ieee->pHTInfo == NULL) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n"); - return NULL; + goto failed; } HTUpdateDefaultSetting(ieee); HTInitializeHTInfo(ieee); //may move to other place. -- cgit v0.10.2 From 19f798ad009a1c9aebe6c248173e4a7ec694c680 Mon Sep 17 00:00:00 2001 From: Krzysztof Wilczynski Date: Tue, 24 Apr 2012 15:00:34 +0100 Subject: staging: wlan-ng: Release struct returned by cfg80211_inform_bss to avoid potential memory leak. Function cfg80211_inform_bss returns a pointer to a referenced struct cfg80211_bss but no information is needed from this struct in function prism2_scan and therefore we release it by calling cfg80211_put_bss. Signed-off-by: Krzysztof Wilczynski Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index 4cd3ba5..8bc562b 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c @@ -332,6 +332,7 @@ int prism2_scan(struct wiphy *wiphy, struct net_device *dev, wlandevice_t *wlandev = dev->ml_priv; struct p80211msg_dot11req_scan msg1; struct p80211msg_dot11req_scan_results msg2; + struct cfg80211_bss *bss; int result; int err = 0; int numbss = 0; @@ -401,7 +402,7 @@ int prism2_scan(struct wiphy *wiphy, struct net_device *dev, ie_buf[1] = msg2.ssid.data.len; ie_len = ie_buf[1] + 2; memcpy(&ie_buf[2], &(msg2.ssid.data.data), msg2.ssid.data.len); - cfg80211_inform_bss(wiphy, + bss = cfg80211_inform_bss(wiphy, ieee80211_get_channel(wiphy, ieee80211_dsss_chan_to_freq(msg2.dschannel.data)), (const u8 *) &(msg2.bssid.data.data), msg2.timestamp.data, msg2.capinfo.data, @@ -411,6 +412,13 @@ int prism2_scan(struct wiphy *wiphy, struct net_device *dev, (msg2.signal.data - 65536) * 100, /* Conversion to signed type */ GFP_KERNEL ); + + if (!bss) { + err = -ENOMEM; + goto exit; + } + + cfg80211_put_bss(bss); } if (result) -- cgit v0.10.2 From 332a81961303dccac8bd3cb5c68aff1b3a6daeb6 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sat, 21 Apr 2012 20:32:52 +0200 Subject: staging: olpc_dcon.c: strings printed with printk() put on a single line Quoted strings that were broken over multiple lines are put on a single line for easier grep'ability. Signed-off-by: Jesper Juhl Acked-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 3d91993..862dbb5 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -71,8 +71,8 @@ static int dcon_hw_init(struct dcon_priv *dcon, int is_init) ver = dcon_read(dcon, DCON_REG_ID); if ((ver >> 8) != 0xDC) { - printk(KERN_ERR "olpc-dcon: DCON ID not 0xDCxx: 0x%04x " - "instead.\n", ver); + printk(KERN_ERR "olpc-dcon: DCON ID not 0xDCxx: 0x%04x instead.\n", + ver); rc = -ENXIO; goto err; } @@ -136,8 +136,8 @@ power_up: x = 1; x = olpc_ec_cmd(0x26, (unsigned char *) &x, 1, NULL, 0); if (x) { - printk(KERN_WARNING "olpc-dcon: unable to force dcon " - "to power up: %d!\n", x); + printk(KERN_WARNING "olpc-dcon: unable to force dcon to power up: %d!\n", + x); return x; } msleep(10); /* we'll be conservative */ @@ -150,8 +150,7 @@ power_up: x = dcon_read(dcon, DCON_REG_ID); } if (x < 0) { - printk(KERN_ERR "olpc-dcon: unable to stabilize dcon's " - "smbus, reasserting power and praying.\n"); + printk(KERN_ERR "olpc-dcon: unable to stabilize dcon's smbus, reasserting power and praying.\n"); BUG_ON(olpc_board_at_least(olpc_board(0xc2))); x = 0; olpc_ec_cmd(0x26, (unsigned char *) &x, 1, NULL, 0); @@ -222,8 +221,8 @@ static void dcon_sleep(struct dcon_priv *dcon, bool sleep) x = 0; x = olpc_ec_cmd(0x26, (unsigned char *) &x, 1, NULL, 0); if (x) - printk(KERN_WARNING "olpc-dcon: unable to force dcon " - "to power down: %d!\n", x); + printk(KERN_WARNING "olpc-dcon: unable to force dcon to power down: %d!\n", + x); else dcon->asleep = sleep; } else { @@ -232,8 +231,8 @@ static void dcon_sleep(struct dcon_priv *dcon, bool sleep) dcon->disp_mode |= MODE_BL_ENABLE; x = dcon_bus_stabilize(dcon, 1); if (x) - printk(KERN_WARNING "olpc-dcon: unable to reinit dcon" - " hardware: %d!\n", x); + printk(KERN_WARNING "olpc-dcon: unable to reinit dcon hardware: %d!\n", + x); else dcon->asleep = sleep; -- cgit v0.10.2 From 5d2130862b1fbea27fb21b4d4be62f787f5d2898 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sat, 21 Apr 2012 20:33:07 +0200 Subject: staging: olpc_dcon.c: Add missing level to a printk() Signed-off-by: Jesper Juhl Acked-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 862dbb5..7fe6eb6 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -303,7 +303,7 @@ static void dcon_source_switch(struct work_struct *work) switch (source) { case DCON_SOURCE_CPU: - printk("dcon_source_switch to CPU\n"); + printk(KERN_INFO "dcon_source_switch to CPU\n"); /* Enable the scanline interrupt bit */ if (dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode | MODE_SCAN_INT)) -- cgit v0.10.2 From c25626871c082432ae265594d4b336ccbeec4120 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sat, 21 Apr 2012 20:33:15 +0200 Subject: staging: olpc_dcon.c: Remove a few spaces between casts and variables Just a trivial style cleanup. Signed-off-by: Jesper Juhl Acked-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 7fe6eb6..992275c 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -134,7 +134,7 @@ static int dcon_bus_stabilize(struct dcon_priv *dcon, int is_powered_down) power_up: if (is_powered_down) { x = 1; - x = olpc_ec_cmd(0x26, (unsigned char *) &x, 1, NULL, 0); + x = olpc_ec_cmd(0x26, (unsigned char *)&x, 1, NULL, 0); if (x) { printk(KERN_WARNING "olpc-dcon: unable to force dcon to power up: %d!\n", x); @@ -153,7 +153,7 @@ power_up: printk(KERN_ERR "olpc-dcon: unable to stabilize dcon's smbus, reasserting power and praying.\n"); BUG_ON(olpc_board_at_least(olpc_board(0xc2))); x = 0; - olpc_ec_cmd(0x26, (unsigned char *) &x, 1, NULL, 0); + olpc_ec_cmd(0x26, (unsigned char *)&x, 1, NULL, 0); msleep(100); is_powered_down = 1; goto power_up; /* argh, stupid hardware.. */ @@ -219,7 +219,7 @@ static void dcon_sleep(struct dcon_priv *dcon, bool sleep) if (sleep) { x = 0; - x = olpc_ec_cmd(0x26, (unsigned char *) &x, 1, NULL, 0); + x = olpc_ec_cmd(0x26, (unsigned char *)&x, 1, NULL, 0); if (x) printk(KERN_WARNING "olpc-dcon: unable to force dcon to power down: %d!\n", x); @@ -598,7 +598,7 @@ static int dcon_fb_notifier(struct notifier_block *self, struct fb_event *evdata = data; struct dcon_priv *dcon = container_of(self, struct dcon_priv, fbevent_nb); - int *blank = (int *) evdata->data; + int *blank = (int *)evdata->data; if (((event != FB_EVENT_BLANK) && (event != FB_EVENT_CONBLANK)) || dcon->ignore_fb_events) return 0; -- cgit v0.10.2 From 62ef30b5781d836aa756fb5fa6de4f660fd6f9a2 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sat, 21 Apr 2012 22:04:30 +0200 Subject: staging: vt6656: Remove redundant casts from ioctl.c Remove some unneeded explicit casts from drivers/staging/vt6656/ioctl.c Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6656/ioctl.c b/drivers/staging/vt6656/ioctl.c index 1463d76..d8b9f1d 100644 --- a/drivers/staging/vt6656/ioctl.c +++ b/drivers/staging/vt6656/ioctl.c @@ -90,18 +90,17 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) spin_lock_irq(&pDevice->lock); if (memcmp(pMgmt->abyCurrBSSID, &abyNullAddr[0], 6) == 0) - BSSvClearBSSList((void *)pDevice, FALSE); + BSSvClearBSSList(pDevice, FALSE); else - BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); + BSSvClearBSSList(pDevice, pDevice->bLinkPass); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_BSS_SCAN..begin\n"); if (pItemSSID->len != 0) - bScheduleCommand((void *)pDevice, - WLAN_CMD_BSSID_SCAN, + bScheduleCommand(pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); else - bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); + bScheduleCommand(pDevice, WLAN_CMD_BSSID_SCAN, NULL); spin_unlock_irq(&pDevice->lock); break; @@ -190,10 +189,9 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) netif_stop_queue(pDevice->dev); spin_lock_irq(&pDevice->lock); pMgmt->eCurrState = WMAC_STATE_IDLE; - bScheduleCommand((void *) pDevice, - WLAN_CMD_BSSID_SCAN, + bScheduleCommand(pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); + bScheduleCommand(pDevice, WLAN_CMD_SSID, NULL); spin_unlock_irq(&pDevice->lock); break; @@ -299,7 +297,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) result = -EINVAL; break; } - pList = (PSBSSIDList)kmalloc(sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)), (int)GFP_ATOMIC); + pList = kmalloc(sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)), GFP_ATOMIC); if (pList == NULL) { result = -ENOMEM; break; @@ -534,7 +532,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) netif_stop_queue(pDevice->dev); spin_lock_irq(&pDevice->lock); - bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL); + bScheduleCommand(pDevice, WLAN_CMD_RUN_AP, NULL); spin_unlock_irq(&pDevice->lock); break; @@ -565,7 +563,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) result = -ENOMEM; break; } - pNodeList = (PSNodeList)kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), (int)GFP_ATOMIC); + pNodeList = (PSNodeList)kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), GFP_ATOMIC); if (pNodeList == NULL) { result = -ENOMEM; break; -- cgit v0.10.2 From 3eb23422b2370fd22531cf0de40b57699c17f08e Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sat, 21 Apr 2012 22:04:45 +0200 Subject: staging: vt6656: trivial whitespace cleanups to ioctl.c This removes a space between a cast and the variable and makes the case statements in the switch stylewise consistent as to whether there's a blank line before each 'case' or not. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6656/ioctl.c b/drivers/staging/vt6656/ioctl.c index d8b9f1d..cc7357d 100644 --- a/drivers/staging/vt6656/ioctl.c +++ b/drivers/staging/vt6656/ioctl.c @@ -149,6 +149,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) } } break; + case WLAN_CMD_BSS_JOIN: if (copy_from_user(&sJoinCmd, pReq->data, sizeof(SCmdBSSJoin))) { result = -EFAULT; @@ -311,7 +312,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) pList->sBSSIDList[ii].wBeaconInterval = pBSS->wBeaconInterval; pList->sBSSIDList[ii].wCapInfo = pBSS->wCapInfo; RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm); - pList->sBSSIDList[ii].uRSSI = (unsigned int) ldBm; + pList->sBSSIDList[ii].uRSSI = (unsigned int)ldBm; /* pList->sBSSIDList[ii].uRSSI = pBSS->uRSSI; */ memcpy(pList->sBSSIDList[ii].abyBSSID, pBSS->abyBSSID, WLAN_BSSID_LEN); pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; @@ -354,6 +355,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) break; } break; + case WLAN_CMD_STOP_MAC: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_STOP_MAC\n"); /* Todo xxxxxx */ -- cgit v0.10.2 From abae41e6438b798e046d721b6ccdd55b4a398170 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 22 Apr 2012 13:37:09 +0200 Subject: drivers/staging/comedi/comedi_fops.c: add missing vfree aux_free is freed on all other exits from the function. By removing the return, we can benefit from the vfree already at the end of the function. Signed-off-by: Julia Lawall Cc: stable Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index a0861fb..06fc656 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -301,7 +301,7 @@ static int do_devconfig_ioctl(struct comedi_device *dev, if (ret == 0) { if (!try_module_get(dev->driver->module)) { comedi_device_detach(dev); - return -ENOSYS; + ret = -ENOSYS; } } -- cgit v0.10.2 From 771145262e9bbabb03bd71d34792546db0bd2813 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 23 Apr 2012 16:20:41 -0700 Subject: staging: comedi: refactor c6xdigio driver to remove forward declarations Move the struct comedi_driver variable to remove the need or the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c index 11cdaf2..5f75351 100644 --- a/drivers/staging/comedi/drivers/c6xdigio.c +++ b/drivers/staging/comedi/drivers/c6xdigio.c @@ -97,16 +97,6 @@ union encvaluetype { #define C6XDIGIO_TIME_OUT 20 -static int c6xdigio_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int c6xdigio_detach(struct comedi_device *dev); -struct comedi_driver driver_c6xdigio = { - .driver_name = "c6xdigio", - .module = THIS_MODULE, - .attach = c6xdigio_attach, - .detach = c6xdigio_detach, -}; - static void C6X_pwmInit(unsigned long baseAddr) { int timeout = 0; @@ -518,17 +508,23 @@ static int c6xdigio_detach(struct comedi_device *dev) return 0; } +struct comedi_driver driver_c6xdigio = { + .driver_name = "c6xdigio", + .module = THIS_MODULE, + .attach = c6xdigio_attach, + .detach = c6xdigio_detach, +}; + static int __init driver_c6xdigio_init_module(void) { return comedi_driver_register(&driver_c6xdigio); } +module_init(driver_c6xdigio_init_module); static void __exit driver_c6xdigio_cleanup_module(void) { comedi_driver_unregister(&driver_c6xdigio); } - -module_init(driver_c6xdigio_init_module); module_exit(driver_c6xdigio_cleanup_module); MODULE_AUTHOR("Comedi http://www.comedi.org"); -- cgit v0.10.2 From 6f97a28d6967df6d5b049510926671a8290a8acb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 23 Apr 2012 16:13:43 -0700 Subject: staging: comedi: refactor aio_iiro_16 driver to remove forward declarations Move the struct comedi_driver variable and the associated attach/detach routines to remove the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c index 160b0a0..763461a 100644 --- a/drivers/staging/comedi/drivers/aio_iiro_16.c +++ b/drivers/staging/comedi/drivers/aio_iiro_16.c @@ -67,30 +67,41 @@ struct aio_iiro_16_private { #define devpriv ((struct aio_iiro_16_private *) dev->private) -static int aio_iiro_16_attach(struct comedi_device *dev, - struct comedi_devconfig *it); +static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + if (insn->n != 2) + return -EINVAL; -static int aio_iiro_16_detach(struct comedi_device *dev); + if (data[0]) { + s->state &= ~data[0]; + s->state |= data[0] & data[1]; + outb(s->state & 0xff, dev->iobase + AIO_IIRO_16_RELAY_0_7); + outb((s->state >> 8) & 0xff, + dev->iobase + AIO_IIRO_16_RELAY_8_15); + } -static struct comedi_driver driver_aio_iiro_16 = { - .driver_name = "aio_iiro_16", - .module = THIS_MODULE, - .attach = aio_iiro_16_attach, - .detach = aio_iiro_16_detach, - .board_name = &aio_iiro_16_boards[0].name, - .offset = sizeof(struct aio_iiro_16_board), - .num_names = ARRAY_SIZE(aio_iiro_16_boards), -}; + data[1] = s->state; + + return 2; +} static int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); + unsigned int *data) +{ + if (insn->n != 2) + return -EINVAL; -static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); + data[1] = 0; + data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_0_7); + data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_8_15) << 8; + + return 2; +} static int aio_iiro_16_attach(struct comedi_device *dev, struct comedi_devconfig *it) @@ -148,53 +159,26 @@ static int aio_iiro_16_detach(struct comedi_device *dev) return 0; } -static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - if (insn->n != 2) - return -EINVAL; - - if (data[0]) { - s->state &= ~data[0]; - s->state |= data[0] & data[1]; - outb(s->state & 0xff, dev->iobase + AIO_IIRO_16_RELAY_0_7); - outb((s->state >> 8) & 0xff, - dev->iobase + AIO_IIRO_16_RELAY_8_15); - } - - data[1] = s->state; - - return 2; -} - -static int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - if (insn->n != 2) - return -EINVAL; - - data[1] = 0; - data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_0_7); - data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_8_15) << 8; - - return 2; -} +static struct comedi_driver driver_aio_iiro_16 = { + .driver_name = "aio_iiro_16", + .module = THIS_MODULE, + .attach = aio_iiro_16_attach, + .detach = aio_iiro_16_detach, + .board_name = &aio_iiro_16_boards[0].name, + .offset = sizeof(struct aio_iiro_16_board), + .num_names = ARRAY_SIZE(aio_iiro_16_boards), +}; static int __init driver_aio_iiro_16_init_module(void) { return comedi_driver_register(&driver_aio_iiro_16); } +module_init(driver_aio_iiro_16_init_module); static void __exit driver_aio_iiro_16_cleanup_module(void) { comedi_driver_unregister(&driver_aio_iiro_16); } - -module_init(driver_aio_iiro_16_init_module); module_exit(driver_aio_iiro_16_cleanup_module); MODULE_AUTHOR("Comedi http://www.comedi.org"); -- cgit v0.10.2 From 3c4ba9e8743d664e6c71cabf09f05aa92b50c366 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 23 Apr 2012 16:06:14 -0700 Subject: staging: comedi: refactor adv_pci7123 driver to remove forward declarations Move the struct comedi_driver variable and the associated attach/detach routines to remove the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 4a4ae5f..54a3304 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -150,34 +150,6 @@ static const struct pci1723_board boardtypes[] = { }, }; -/* - * This is used by modprobe to translate PCI IDs to drivers. - * Should only be used for PCI and ISA-PnP devices - */ -static DEFINE_PCI_DEVICE_TABLE(pci1723_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1723) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, pci1723_pci_table); - -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int pci1723_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pci1723_detach(struct comedi_device *dev); - -static struct comedi_driver driver_pci1723 = { - .driver_name = "adv_pci1723", - .module = THIS_MODULE, - .attach = pci1723_attach, - .detach = pci1723_detach, -}; - /* This structure is for data unique to this hardware driver. */ struct pci1723_private { int valid; /* card is usable; */ @@ -317,10 +289,6 @@ static int pci1723_dio_insn_bits(struct comedi_device *dev, return 2; } -/* - * Attach is called by the Comedi core to configure the driver - * for a pci1723 board. - */ static int pci1723_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -463,14 +431,6 @@ static int pci1723_attach(struct comedi_device *dev, return 0; } -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ static int pci1723_detach(struct comedi_device *dev) { printk(KERN_ERR "comedi%d: pci1723: remove\n", dev->minor); @@ -489,10 +449,13 @@ static int pci1723_detach(struct comedi_device *dev) return 0; } -/* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. - */ +static struct comedi_driver driver_pci1723 = { + .driver_name = "adv_pci1723", + .module = THIS_MODULE, + .attach = pci1723_attach, + .detach = pci1723_detach, +}; + static int __devinit driver_pci1723_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { @@ -504,10 +467,16 @@ static void __devexit driver_pci1723_pci_remove(struct pci_dev *dev) comedi_pci_auto_unconfig(dev); } +static DEFINE_PCI_DEVICE_TABLE(pci1723_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1723) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, pci1723_pci_table); + static struct pci_driver driver_pci1723_pci_driver = { - .id_table = pci1723_pci_table, - .probe = &driver_pci1723_pci_probe, - .remove = __devexit_p(&driver_pci1723_pci_remove) + .id_table = pci1723_pci_table, + .probe = driver_pci1723_pci_probe, + .remove = __devexit_p(driver_pci1723_pci_remove), }; static int __init driver_pci1723_init_module(void) @@ -521,14 +490,13 @@ static int __init driver_pci1723_init_module(void) driver_pci1723_pci_driver.name = (char *)driver_pci1723.driver_name; return pci_register_driver(&driver_pci1723_pci_driver); } +module_init(driver_pci1723_init_module); static void __exit driver_pci1723_cleanup_module(void) { pci_unregister_driver(&driver_pci1723_pci_driver); comedi_driver_unregister(&driver_pci1723); } - -module_init(driver_pci1723_init_module); module_exit(driver_pci1723_cleanup_module); MODULE_AUTHOR("Comedi http://www.comedi.org"); -- cgit v0.10.2 From 632d391b3572673fc272a6fd74e5c753065eca1c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 23 Apr 2012 15:57:48 -0700 Subject: staging: comedi: refactor adq12b driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and struct boardtype variables to the end of the source as is more typically done with other drivers. Then rearrange the attach/detach functions, this removes the need for all the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c index 5361f31..275cb77 100644 --- a/drivers/staging/comedi/drivers/adq12b.c +++ b/drivers/staging/comedi/drivers/adq12b.c @@ -125,24 +125,6 @@ struct adq12b_board { int do_chans; }; -static const struct adq12b_board adq12b_boards[] = { - { - .name = "adq12b", - .ai_se_chans = 16, - .ai_diff_chans = 8, - .ai_bits = 12, - .di_chans = 5, - .do_chans = 8} -/* potentially, more adq-based deviced will be added */ -/*, - .name = "adq12b", - .ai_chans = 16, // this is just for reference, hardcoded again later - .ai_bits = 12, - .di_chans = 8, - .do_chans = 5 - }*/ -}; - #define thisboard ((const struct adq12b_board *)dev->board_ptr) struct adq12b_private { @@ -156,41 +138,88 @@ struct adq12b_private { #define devpriv ((struct adq12b_private *)dev->private) /* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. + * "instructions" read/write data in "one-shot" or "software-triggered" + * mode. */ -static int adq12b_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int adq12b_detach(struct comedi_device *dev); - -static struct comedi_driver driver_adq12b = { - .driver_name = "adq12b", - .module = THIS_MODULE, - .attach = adq12b_attach, - .detach = adq12b_detach, - .board_name = &adq12b_boards[0].name, - .offset = sizeof(struct adq12b_board), - .num_names = ARRAY_SIZE(adq12b_boards), -}; static int adq12b_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); + unsigned int *data) +{ + int n, i; + int range, channel; + unsigned char hi, lo, status; + + /* change channel and range only if it is different from the previous */ + range = CR_RANGE(insn->chanspec); + channel = CR_CHAN(insn->chanspec); + if (channel != devpriv->last_channel || range != devpriv->last_range) { + outb((range << 4) | channel, dev->iobase + ADQ12B_CTREG); + udelay(50); /* wait for the mux to settle */ + } + + /* trigger conversion */ + status = inb(dev->iobase + ADQ12B_ADLOW); + + /* convert n samples */ + for (n = 0; n < insn->n; n++) { + + /* wait for end of conversion */ + i = 0; + do { + /* udelay(1); */ + status = inb(dev->iobase + ADQ12B_STINR); + status = status & ADQ12B_EOC; + } while (status == 0 && ++i < TIMEOUT); + /* } while (++i < 10); */ + + /* read data */ + hi = inb(dev->iobase + ADQ12B_ADHIG); + lo = inb(dev->iobase + ADQ12B_ADLOW); + + /* printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n", + channel, range, status, hi, lo); */ + data[n] = (hi << 8) | lo; + + } + + /* return the number of samples read/written */ + return n; +} + static int adq12b_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); + struct comedi_insn *insn, unsigned int *data) +{ + + /* only bits 0-4 have information about digital inputs */ + data[1] = (inb(dev->iobase + ADQ12B_STINR) & (0x1f)); + + return 2; +} + static int adq12b_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); + struct comedi_insn *insn, unsigned int *data) +{ + int channel; + + for (channel = 0; channel < 8; channel++) + if (((data[0] >> channel) & 0x01) != 0) + outb((((data[1] >> channel) & 0x01) << 3) | channel, + dev->iobase + ADQ12B_OUTBR); + + /* store information to retrieve when asked for reading */ + if (data[0]) { + devpriv->digital_state &= ~data[0]; + devpriv->digital_state |= (data[0] & data[1]); + } + + data[1] = devpriv->digital_state; + + return 2; +} -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; @@ -295,14 +324,6 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ static int adq12b_detach(struct comedi_device *dev) { if (dev->iobase) @@ -315,104 +336,37 @@ static int adq12b_detach(struct comedi_device *dev) return 0; } -/* - * "instructions" read/write data in "one-shot" or "software-triggered" - * mode. - */ - -static int adq12b_ai_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data) -{ - int n, i; - int range, channel; - unsigned char hi, lo, status; - - /* change channel and range only if it is different from the previous */ - range = CR_RANGE(insn->chanspec); - channel = CR_CHAN(insn->chanspec); - if (channel != devpriv->last_channel || range != devpriv->last_range) { - outb((range << 4) | channel, dev->iobase + ADQ12B_CTREG); - udelay(50); /* wait for the mux to settle */ - } - - /* trigger conversion */ - status = inb(dev->iobase + ADQ12B_ADLOW); - - /* convert n samples */ - for (n = 0; n < insn->n; n++) { - - /* wait for end of conversion */ - i = 0; - do { - /* udelay(1); */ - status = inb(dev->iobase + ADQ12B_STINR); - status = status & ADQ12B_EOC; - } while (status == 0 && ++i < TIMEOUT); - /* } while (++i < 10); */ - - /* read data */ - hi = inb(dev->iobase + ADQ12B_ADHIG); - lo = inb(dev->iobase + ADQ12B_ADLOW); - - /* printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n", - channel, range, status, hi, lo); */ - data[n] = (hi << 8) | lo; - - } - - /* return the number of samples read/written */ - return n; -} - -static int adq12b_di_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - - /* only bits 0-4 have information about digital inputs */ - data[1] = (inb(dev->iobase + ADQ12B_STINR) & (0x1f)); - - return 2; -} - -static int adq12b_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - int channel; - - for (channel = 0; channel < 8; channel++) - if (((data[0] >> channel) & 0x01) != 0) - outb((((data[1] >> channel) & 0x01) << 3) | channel, - dev->iobase + ADQ12B_OUTBR); - - /* store information to retrieve when asked for reading */ - if (data[0]) { - devpriv->digital_state &= ~data[0]; - devpriv->digital_state |= (data[0] & data[1]); - } - - data[1] = devpriv->digital_state; +static const struct adq12b_board adq12b_boards[] = { + { + .name = "adq12b", + .ai_se_chans = 16, + .ai_diff_chans = 8, + .ai_bits = 12, + .di_chans = 5, + .do_chans = 8, + }, +}; - return 2; -} +static struct comedi_driver driver_adq12b = { + .driver_name = "adq12b", + .module = THIS_MODULE, + .attach = adq12b_attach, + .detach = adq12b_detach, + .board_name = &adq12b_boards[0].name, + .offset = sizeof(struct adq12b_board), + .num_names = ARRAY_SIZE(adq12b_boards), +}; -/* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. - */ static int __init driver_adq12b_init_module(void) { return comedi_driver_register(&driver_adq12b); } +module_init(driver_adq12b_init_module); static void __exit driver_adq12b_cleanup_module(void) { comedi_driver_unregister(&driver_adq12b); } - -module_init(driver_adq12b_init_module); module_exit(driver_adq12b_cleanup_module); MODULE_AUTHOR("Comedi http://www.comedi.org"); -- cgit v0.10.2 From e68a83fe522a031d0799e8cad8c06f5d653c7782 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 23 Apr 2012 15:43:22 -0700 Subject: staging: comedi: refactor adl_pci9111 driver to remove forward declarations Move the module_init/module_exit routines and variables to the end of the source as is more typically done with other drivers. Then rearrange the attach/detach and probe/remove functions, this removes the need for all the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 6b4d98a..4e4e5fd 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -289,16 +289,6 @@ TODO: PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2); \ } while (0) -/* Function prototypes */ - -static int pci9111_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pci9111_detach(struct comedi_device *dev); -static void pci9111_ai_munge(struct comedi_device *dev, - struct comedi_subdevice *s, void *data, - unsigned int num_bytes, - unsigned int start_chan_index); - static const struct comedi_lrange pci9111_hr_ai_range = { 5, { @@ -310,14 +300,6 @@ static const struct comedi_lrange pci9111_hr_ai_range = { } }; -static DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID) }, - /* { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID) }, */ - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, pci9111_pci_table); - /* */ /* Board specification structure */ /* */ @@ -354,51 +336,6 @@ static const struct pci9111_board pci9111_boards[] = { #define pci9111_board_nbr \ (sizeof(pci9111_boards)/sizeof(struct pci9111_board)) -static struct comedi_driver pci9111_driver = { - .driver_name = PCI9111_DRIVER_NAME, - .module = THIS_MODULE, - .attach = pci9111_attach, - .detach = pci9111_detach, -}; - -static int __devinit pci9111_driver_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, &pci9111_driver); -} - -static void __devexit pci9111_driver_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver pci9111_driver_pci_driver = { - .id_table = pci9111_pci_table, - .probe = &pci9111_driver_pci_probe, - .remove = __devexit_p(&pci9111_driver_pci_remove) -}; - -static int __init pci9111_driver_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&pci9111_driver); - if (retval < 0) - return retval; - - pci9111_driver_pci_driver.name = (char *)pci9111_driver.driver_name; - return pci_register_driver(&pci9111_driver_pci_driver); -} - -static void __exit pci9111_driver_cleanup_module(void) -{ - pci_unregister_driver(&pci9111_driver_pci_driver); - comedi_driver_unregister(&pci9111_driver); -} - -module_init(pci9111_driver_init_module); -module_exit(pci9111_driver_cleanup_module); - /* Private data structure */ struct pci9111_private_data { @@ -1470,6 +1407,57 @@ static int pci9111_detach(struct comedi_device *dev) return 0; } +static struct comedi_driver pci9111_driver = { + .driver_name = PCI9111_DRIVER_NAME, + .module = THIS_MODULE, + .attach = pci9111_attach, + .detach = pci9111_detach, +}; + +static int __devinit pci9111_driver_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &pci9111_driver); +} + +static void __devexit pci9111_driver_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID) }, + /* { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID) }, */ + { 0 } +}; +MODULE_DEVICE_TABLE(pci, pci9111_pci_table); + +static struct pci_driver pci9111_driver_pci_driver = { + .id_table = pci9111_pci_table, + .probe = pci9111_driver_pci_probe, + .remove = __devexit_p(pci9111_driver_pci_remove), +}; + +static int __init pci9111_driver_init_module(void) +{ + int retval; + + retval = comedi_driver_register(&pci9111_driver); + if (retval < 0) + return retval; + + pci9111_driver_pci_driver.name = (char *)pci9111_driver.driver_name; + return pci_register_driver(&pci9111_driver_pci_driver); +} +module_init(pci9111_driver_init_module); + +static void __exit pci9111_driver_cleanup_module(void) +{ + pci_unregister_driver(&pci9111_driver_pci_driver); + comedi_driver_unregister(&pci9111_driver); +} +module_exit(pci9111_driver_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From bb4806ae508fcabab9e4ad7578f3334e1596f807 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 23 Apr 2012 15:37:02 -0700 Subject: staging: comedi: refactor adl_pci8164 driver to remove forward declarations Move the struct comedi_driver variable and the associated attach/detach routines to remove the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index bd0c14b..6b32e45c 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -56,13 +56,6 @@ Configuration Options: #define PCI_DEVICE_ID_PCI8164 0x8164 -static DEFINE_PCI_DEVICE_TABLE(adl_pci8164_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI8164) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, adl_pci8164_pci_table); - struct adl_pci8164_private { int data; struct pci_dev *pci_dev; @@ -70,159 +63,6 @@ struct adl_pci8164_private { #define devpriv ((struct adl_pci8164_private *)dev->private) -static int adl_pci8164_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int adl_pci8164_detach(struct comedi_device *dev); -static struct comedi_driver driver_adl_pci8164 = { - .driver_name = "adl_pci8164", - .module = THIS_MODULE, - .attach = adl_pci8164_attach, - .detach = adl_pci8164_detach, -}; - -static int adl_pci8164_insn_read_msts(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -static int adl_pci8164_insn_read_ssts(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -static int adl_pci8164_insn_read_buf0(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -static int adl_pci8164_insn_read_buf1(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -static int adl_pci8164_insn_write_cmd(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -static int adl_pci8164_insn_write_otp(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -static int adl_pci8164_insn_write_buf0(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -static int adl_pci8164_insn_write_buf1(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -static int adl_pci8164_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct pci_dev *pcidev = NULL; - struct comedi_subdevice *s; - int bus, slot; - - printk(KERN_INFO "comedi: attempt to attach...\n"); - printk(KERN_INFO "comedi%d: adl_pci8164\n", dev->minor); - - dev->board_name = "pci8164"; - bus = it->options[0]; - slot = it->options[1]; - - if (alloc_private(dev, sizeof(struct adl_pci8164_private)) < 0) - return -ENOMEM; - - if (alloc_subdevices(dev, 4) < 0) - return -ENOMEM; - - for_each_pci_dev(pcidev) { - if (pcidev->vendor == PCI_VENDOR_ID_ADLINK && - pcidev->device == PCI_DEVICE_ID_PCI8164) { - if (bus || slot) { - /* requested particular bus/slot */ - if (pcidev->bus->number != bus - || PCI_SLOT(pcidev->devfn) != slot) - continue; - } - devpriv->pci_dev = pcidev; - if (comedi_pci_enable(pcidev, "adl_pci8164") < 0) { - printk(KERN_ERR "comedi%d: Failed to enable " - "PCI device and request regions\n", dev->minor); - return -EIO; - } - dev->iobase = pci_resource_start(pcidev, 2); - printk(KERN_DEBUG "comedi: base addr %4lx\n", - dev->iobase); - - s = dev->subdevices + 0; - s->type = COMEDI_SUBD_PROC; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 4; - s->maxdata = 0xffff; - s->len_chanlist = 4; - /* s->range_table = &range_axis; */ - s->insn_read = adl_pci8164_insn_read_msts; - s->insn_write = adl_pci8164_insn_write_cmd; - - s = dev->subdevices + 1; - s->type = COMEDI_SUBD_PROC; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 4; - s->maxdata = 0xffff; - s->len_chanlist = 4; - /* s->range_table = &range_axis; */ - s->insn_read = adl_pci8164_insn_read_ssts; - s->insn_write = adl_pci8164_insn_write_otp; - - s = dev->subdevices + 2; - s->type = COMEDI_SUBD_PROC; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 4; - s->maxdata = 0xffff; - s->len_chanlist = 4; - /* s->range_table = &range_axis; */ - s->insn_read = adl_pci8164_insn_read_buf0; - s->insn_write = adl_pci8164_insn_write_buf0; - - s = dev->subdevices + 3; - s->type = COMEDI_SUBD_PROC; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 4; - s->maxdata = 0xffff; - s->len_chanlist = 4; - /* s->range_table = &range_axis; */ - s->insn_read = adl_pci8164_insn_read_buf1; - s->insn_write = adl_pci8164_insn_write_buf1; - - printk(KERN_INFO "comedi: attached\n"); - - return 1; - } - } - - printk(KERN_ERR "comedi%d: no supported board found!" - "(req. bus/slot : %d/%d)\n", dev->minor, bus, slot); - return -EIO; -} - -static int adl_pci8164_detach(struct comedi_device *dev) -{ - printk(KERN_INFO "comedi%d: pci8164: remove\n", dev->minor); - - if (devpriv && devpriv->pci_dev) { - if (dev->iobase) - comedi_pci_disable(devpriv->pci_dev); - pci_dev_put(devpriv->pci_dev); - } - - return 0; -} - /* all the read commands are the same except for the addition a constant * const to the data for inw() @@ -384,6 +224,116 @@ static int adl_pci8164_insn_write_buf1(struct comedi_device *dev, return 2; } +static int adl_pci8164_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct pci_dev *pcidev = NULL; + struct comedi_subdevice *s; + int bus, slot; + + printk(KERN_INFO "comedi: attempt to attach...\n"); + printk(KERN_INFO "comedi%d: adl_pci8164\n", dev->minor); + + dev->board_name = "pci8164"; + bus = it->options[0]; + slot = it->options[1]; + + if (alloc_private(dev, sizeof(struct adl_pci8164_private)) < 0) + return -ENOMEM; + + if (alloc_subdevices(dev, 4) < 0) + return -ENOMEM; + + for_each_pci_dev(pcidev) { + if (pcidev->vendor == PCI_VENDOR_ID_ADLINK && + pcidev->device == PCI_DEVICE_ID_PCI8164) { + if (bus || slot) { + /* requested particular bus/slot */ + if (pcidev->bus->number != bus + || PCI_SLOT(pcidev->devfn) != slot) + continue; + } + devpriv->pci_dev = pcidev; + if (comedi_pci_enable(pcidev, "adl_pci8164") < 0) { + printk(KERN_ERR "comedi%d: Failed to enable " + "PCI device and request regions\n", dev->minor); + return -EIO; + } + dev->iobase = pci_resource_start(pcidev, 2); + printk(KERN_DEBUG "comedi: base addr %4lx\n", + dev->iobase); + + s = dev->subdevices + 0; + s->type = COMEDI_SUBD_PROC; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->len_chanlist = 4; + /* s->range_table = &range_axis; */ + s->insn_read = adl_pci8164_insn_read_msts; + s->insn_write = adl_pci8164_insn_write_cmd; + + s = dev->subdevices + 1; + s->type = COMEDI_SUBD_PROC; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->len_chanlist = 4; + /* s->range_table = &range_axis; */ + s->insn_read = adl_pci8164_insn_read_ssts; + s->insn_write = adl_pci8164_insn_write_otp; + + s = dev->subdevices + 2; + s->type = COMEDI_SUBD_PROC; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->len_chanlist = 4; + /* s->range_table = &range_axis; */ + s->insn_read = adl_pci8164_insn_read_buf0; + s->insn_write = adl_pci8164_insn_write_buf0; + + s = dev->subdevices + 3; + s->type = COMEDI_SUBD_PROC; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->len_chanlist = 4; + /* s->range_table = &range_axis; */ + s->insn_read = adl_pci8164_insn_read_buf1; + s->insn_write = adl_pci8164_insn_write_buf1; + + printk(KERN_INFO "comedi: attached\n"); + + return 1; + } + } + + printk(KERN_ERR "comedi%d: no supported board found!" + "(req. bus/slot : %d/%d)\n", dev->minor, bus, slot); + return -EIO; +} + +static int adl_pci8164_detach(struct comedi_device *dev) +{ + printk(KERN_INFO "comedi%d: pci8164: remove\n", dev->minor); + + if (devpriv && devpriv->pci_dev) { + if (dev->iobase) + comedi_pci_disable(devpriv->pci_dev); + pci_dev_put(devpriv->pci_dev); + } + + return 0; +} + +static struct comedi_driver driver_adl_pci8164 = { + .driver_name = "adl_pci8164", + .module = THIS_MODULE, + .attach = adl_pci8164_attach, + .detach = adl_pci8164_detach, +}; + static int __devinit driver_adl_pci8164_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) @@ -396,10 +346,16 @@ static void __devexit driver_adl_pci8164_pci_remove(struct pci_dev *dev) comedi_pci_auto_unconfig(dev); } +static DEFINE_PCI_DEVICE_TABLE(adl_pci8164_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI8164) }, + {0} +}; +MODULE_DEVICE_TABLE(pci, adl_pci8164_pci_table); + static struct pci_driver driver_adl_pci8164_pci_driver = { - .id_table = adl_pci8164_pci_table, - .probe = &driver_adl_pci8164_pci_probe, - .remove = __devexit_p(&driver_adl_pci8164_pci_remove) + .id_table = adl_pci8164_pci_table, + .probe = driver_adl_pci8164_pci_probe, + .remove = __devexit_p(driver_adl_pci8164_pci_remove), }; static int __init driver_adl_pci8164_init_module(void) @@ -414,14 +370,13 @@ static int __init driver_adl_pci8164_init_module(void) (char *)driver_adl_pci8164.driver_name; return pci_register_driver(&driver_adl_pci8164_pci_driver); } +module_init(driver_adl_pci8164_init_module); static void __exit driver_adl_pci8164_cleanup_module(void) { pci_unregister_driver(&driver_adl_pci8164_pci_driver); comedi_driver_unregister(&driver_adl_pci8164); } - -module_init(driver_adl_pci8164_init_module); module_exit(driver_adl_pci8164_cleanup_module); MODULE_AUTHOR("Comedi http://www.comedi.org"); -- cgit v0.10.2 From d7bd1cd1478d7eb7dd21f330acb9419178edbdb3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 23 Apr 2012 15:31:08 -0700 Subject: staging: comedi: refactor adl_pci7432 driver to remove forward declarations Move the struct comedi_driver variable and the associated attach/detach routines to remove the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci7432.c b/drivers/staging/comedi/drivers/adl_pci7432.c index 1e0db48..db15ec6 100644 --- a/drivers/staging/comedi/drivers/adl_pci7432.c +++ b/drivers/staging/comedi/drivers/adl_pci7432.c @@ -43,13 +43,6 @@ Configuration Options: #define PCI_DEVICE_ID_PCI7432 0x7432 -static DEFINE_PCI_DEVICE_TABLE(adl_pci7432_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7432) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, adl_pci7432_pci_table); - struct adl_pci7432_private { int data; struct pci_dev *pci_dev; @@ -57,29 +50,44 @@ struct adl_pci7432_private { #define devpriv ((struct adl_pci7432_private *)dev->private) -static int adl_pci7432_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int adl_pci7432_detach(struct comedi_device *dev); -static struct comedi_driver driver_adl_pci7432 = { - .driver_name = "adl_pci7432", - .module = THIS_MODULE, - .attach = adl_pci7432_attach, - .detach = adl_pci7432_detach, -}; +static int adl_pci7432_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + printk(KERN_DEBUG "comedi: pci7432_do_insn_bits called\n"); + printk(KERN_DEBUG "comedi: data0: %8x data1: %8x\n", data[0], data[1]); + + if (insn->n != 2) + return -EINVAL; -/* Digital IO */ + if (data[0]) { + s->state &= ~data[0]; + s->state |= (data[0] & data[1]); + + printk(KERN_DEBUG "comedi: out: %8x on iobase %4lx\n", s->state, + dev->iobase + PCI7432_DO); + outl(s->state & 0xffffffff, dev->iobase + PCI7432_DO); + } + return 2; +} static int adl_pci7432_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); + unsigned int *data) +{ + printk(KERN_DEBUG "comedi: pci7432_di_insn_bits called\n"); + printk(KERN_DEBUG "comedi: data0: %8x data1: %8x\n", data[0], data[1]); -static int adl_pci7432_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); + if (insn->n != 2) + return -EINVAL; -/* */ + data[1] = inl(dev->iobase + PCI7432_DI) & 0xffffffff; + printk(KERN_DEBUG "comedi: data1 %8x\n", data[1]); + + return 2; +} static int adl_pci7432_attach(struct comedi_device *dev, struct comedi_devconfig *it) @@ -166,44 +174,12 @@ static int adl_pci7432_detach(struct comedi_device *dev) return 0; } -static int adl_pci7432_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - printk(KERN_DEBUG "comedi: pci7432_do_insn_bits called\n"); - printk(KERN_DEBUG "comedi: data0: %8x data1: %8x\n", data[0], data[1]); - - if (insn->n != 2) - return -EINVAL; - - if (data[0]) { - s->state &= ~data[0]; - s->state |= (data[0] & data[1]); - - printk(KERN_DEBUG "comedi: out: %8x on iobase %4lx\n", s->state, - dev->iobase + PCI7432_DO); - outl(s->state & 0xffffffff, dev->iobase + PCI7432_DO); - } - return 2; -} - -static int adl_pci7432_di_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - printk(KERN_DEBUG "comedi: pci7432_di_insn_bits called\n"); - printk(KERN_DEBUG "comedi: data0: %8x data1: %8x\n", data[0], data[1]); - - if (insn->n != 2) - return -EINVAL; - - data[1] = inl(dev->iobase + PCI7432_DI) & 0xffffffff; - printk(KERN_DEBUG "comedi: data1 %8x\n", data[1]); - - return 2; -} +static struct comedi_driver driver_adl_pci7432 = { + .driver_name = "adl_pci7432", + .module = THIS_MODULE, + .attach = adl_pci7432_attach, + .detach = adl_pci7432_detach, +}; static int __devinit driver_adl_pci7432_pci_probe(struct pci_dev *dev, const struct pci_device_id @@ -217,10 +193,16 @@ static void __devexit driver_adl_pci7432_pci_remove(struct pci_dev *dev) comedi_pci_auto_unconfig(dev); } +static DEFINE_PCI_DEVICE_TABLE(adl_pci7432_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7432) }, + {0} +}; +MODULE_DEVICE_TABLE(pci, adl_pci7432_pci_table); + static struct pci_driver driver_adl_pci7432_pci_driver = { - .id_table = adl_pci7432_pci_table, - .probe = &driver_adl_pci7432_pci_probe, - .remove = __devexit_p(&driver_adl_pci7432_pci_remove) + .id_table = adl_pci7432_pci_table, + .probe = driver_adl_pci7432_pci_probe, + .remove = __devexit_p(driver_adl_pci7432_pci_remove) }; static int __init driver_adl_pci7432_init_module(void) @@ -235,14 +217,13 @@ static int __init driver_adl_pci7432_init_module(void) (char *)driver_adl_pci7432.driver_name; return pci_register_driver(&driver_adl_pci7432_pci_driver); } +module_init(driver_adl_pci7432_init_module); static void __exit driver_adl_pci7432_cleanup_module(void) { pci_unregister_driver(&driver_adl_pci7432_pci_driver); comedi_driver_unregister(&driver_adl_pci7432); } - -module_init(driver_adl_pci7432_init_module); module_exit(driver_adl_pci7432_cleanup_module); MODULE_AUTHOR("Comedi http://www.comedi.org"); -- cgit v0.10.2 From db0eaeed6493fed37382fc98e06b2708aeaedaaa Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 23 Apr 2012 15:24:24 -0700 Subject: staging: comedi: refactor adl_pci7296 driver to remove forward declarations Move the struct comedi_driver variable and the associated attach/detach routines to remove the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci7296.c b/drivers/staging/comedi/drivers/adl_pci7296.c index bd18865..2bd749b 100644 --- a/drivers/staging/comedi/drivers/adl_pci7296.c +++ b/drivers/staging/comedi/drivers/adl_pci7296.c @@ -48,13 +48,6 @@ Configuration Options: #define PCI_DEVICE_ID_PCI7296 0x7296 -static DEFINE_PCI_DEVICE_TABLE(adl_pci7296_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7296) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, adl_pci7296_pci_table); - struct adl_pci7296_private { int data; struct pci_dev *pci_dev; @@ -63,16 +56,6 @@ struct adl_pci7296_private { #define devpriv ((struct adl_pci7296_private *)dev->private) static int adl_pci7296_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int adl_pci7296_detach(struct comedi_device *dev); -static struct comedi_driver driver_adl_pci7296 = { - .driver_name = "adl_pci7296", - .module = THIS_MODULE, - .attach = adl_pci7296_attach, - .detach = adl_pci7296_detach, -}; - -static int adl_pci7296_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct pci_dev *pcidev = NULL; @@ -172,6 +155,13 @@ static int adl_pci7296_detach(struct comedi_device *dev) return 0; } +static struct comedi_driver driver_adl_pci7296 = { + .driver_name = "adl_pci7296", + .module = THIS_MODULE, + .attach = adl_pci7296_attach, + .detach = adl_pci7296_detach, +}; + static int __devinit driver_adl_pci7296_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) @@ -184,10 +174,16 @@ static void __devexit driver_adl_pci7296_pci_remove(struct pci_dev *dev) comedi_pci_auto_unconfig(dev); } +static DEFINE_PCI_DEVICE_TABLE(adl_pci7296_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7296) }, + {0} +}; +MODULE_DEVICE_TABLE(pci, adl_pci7296_pci_table); + static struct pci_driver driver_adl_pci7296_pci_driver = { - .id_table = adl_pci7296_pci_table, - .probe = &driver_adl_pci7296_pci_probe, - .remove = __devexit_p(&driver_adl_pci7296_pci_remove) + .id_table = adl_pci7296_pci_table, + .probe = driver_adl_pci7296_pci_probe, + .remove = __devexit_p(driver_adl_pci7296_pci_remove) }; static int __init driver_adl_pci7296_init_module(void) @@ -202,14 +198,13 @@ static int __init driver_adl_pci7296_init_module(void) (char *)driver_adl_pci7296.driver_name; return pci_register_driver(&driver_adl_pci7296_pci_driver); } +module_init(driver_adl_pci7296_init_module); static void __exit driver_adl_pci7296_cleanup_module(void) { pci_unregister_driver(&driver_adl_pci7296_pci_driver); comedi_driver_unregister(&driver_adl_pci7296); } - -module_init(driver_adl_pci7296_init_module); module_exit(driver_adl_pci7296_cleanup_module); MODULE_AUTHOR("Comedi http://www.comedi.org"); -- cgit v0.10.2 From a10a5d6f62b7b08350e7f0fb3b5331abc51ba492 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 23 Apr 2012 15:16:23 -0700 Subject: staging: comedi: refactor adl_pci7230 driver to remove forward declarations Move the struct comedi_driver variable and the associated attach/detach routines to remove the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess CC: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci7230.c b/drivers/staging/comedi/drivers/adl_pci7230.c index c322433..7bb66b0 100644 --- a/drivers/staging/comedi/drivers/adl_pci7230.c +++ b/drivers/staging/comedi/drivers/adl_pci7230.c @@ -43,13 +43,6 @@ Configuration Options: #define PCI_DEVICE_ID_PCI7230 0x7230 -static DEFINE_PCI_DEVICE_TABLE(adl_pci7230_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7230) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, adl_pci7230_pci_table); - struct adl_pci7230_private { int data; struct pci_dev *pci_dev; @@ -57,27 +50,36 @@ struct adl_pci7230_private { #define devpriv ((struct adl_pci7230_private *)dev->private) -static int adl_pci7230_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int adl_pci7230_detach(struct comedi_device *dev); -static struct comedi_driver driver_adl_pci7230 = { - .driver_name = "adl_pci7230", - .module = THIS_MODULE, - .attach = adl_pci7230_attach, - .detach = adl_pci7230_detach, -}; +static int adl_pci7230_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + if (insn->n != 2) + return -EINVAL; -/* Digital IO */ + if (data[0]) { + s->state &= ~data[0]; + s->state |= (data[0] & data[1]); + + outl((s->state << 16) & 0xffffffff, dev->iobase + PCI7230_DO); + } + + return 2; +} static int adl_pci7230_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); + unsigned int *data) +{ + if (insn->n != 2) + return -EINVAL; -static int adl_pci7230_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); + data[1] = inl(dev->iobase + PCI7230_DI) & 0xffffffff; + + return 2; +} static int adl_pci7230_attach(struct comedi_device *dev, struct comedi_devconfig *it) @@ -161,36 +163,12 @@ static int adl_pci7230_detach(struct comedi_device *dev) return 0; } -static int adl_pci7230_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - if (insn->n != 2) - return -EINVAL; - - if (data[0]) { - s->state &= ~data[0]; - s->state |= (data[0] & data[1]); - - outl((s->state << 16) & 0xffffffff, dev->iobase + PCI7230_DO); - } - - return 2; -} - -static int adl_pci7230_di_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - if (insn->n != 2) - return -EINVAL; - - data[1] = inl(dev->iobase + PCI7230_DI) & 0xffffffff; - - return 2; -} +static struct comedi_driver driver_adl_pci7230 = { + .driver_name = "adl_pci7230", + .module = THIS_MODULE, + .attach = adl_pci7230_attach, + .detach = adl_pci7230_detach, +}; static int __devinit driver_adl_pci7230_pci_probe(struct pci_dev *dev, const struct pci_device_id @@ -204,10 +182,16 @@ static void __devexit driver_adl_pci7230_pci_remove(struct pci_dev *dev) comedi_pci_auto_unconfig(dev); } +static DEFINE_PCI_DEVICE_TABLE(adl_pci7230_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7230) }, + {0} +}; +MODULE_DEVICE_TABLE(pci, adl_pci7230_pci_table); + static struct pci_driver driver_adl_pci7230_pci_driver = { - .id_table = adl_pci7230_pci_table, - .probe = &driver_adl_pci7230_pci_probe, - .remove = __devexit_p(&driver_adl_pci7230_pci_remove) + .id_table = adl_pci7230_pci_table, + .probe = driver_adl_pci7230_pci_probe, + .remove = __devexit_p(driver_adl_pci7230_pci_remove) }; static int __init driver_adl_pci7230_init_module(void) @@ -222,14 +206,13 @@ static int __init driver_adl_pci7230_init_module(void) (char *)driver_adl_pci7230.driver_name; return pci_register_driver(&driver_adl_pci7230_pci_driver); } +module_init(driver_adl_pci7230_init_module); static void __exit driver_adl_pci7230_cleanup_module(void) { pci_unregister_driver(&driver_adl_pci7230_pci_driver); comedi_driver_unregister(&driver_adl_pci7230); } - -module_init(driver_adl_pci7230_init_module); module_exit(driver_adl_pci7230_cleanup_module); MODULE_AUTHOR("Comedi http://www.comedi.org"); -- cgit v0.10.2 From c8d87bcc2263401e60c08611e16e6a6481f29ef4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 23 Apr 2012 15:06:21 -0700 Subject: staging: comedi: refactor the adl_pci6208 driver to remove the forward declarations Move the module_init/module_exit routines and variables to the end of the source as is more typically done with other drivers. Then rearrange the attach/detach and probe/remove functions, this removes the need for all the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index de0ec80..889d147 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -85,17 +85,6 @@ static const struct pci6208_board pci6208_boards[] = { } }; -/* This is used by modprobe to translate PCI IDs to drivers. Should - * only be used for PCI and ISA-PnP devices */ -static DEFINE_PCI_DEVICE_TABLE(pci6208_pci_table) = { - /* { PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */ - /* { PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */ - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, 0x6208) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, pci6208_pci_table); - /* Will be initialized in pci6208_find device(). */ #define thisboard ((const struct pci6208_board *)dev->board_ptr) @@ -107,157 +96,6 @@ struct pci6208_private { #define devpriv ((struct pci6208_private *)dev->private) -static int pci6208_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pci6208_detach(struct comedi_device *dev); - -static struct comedi_driver driver_pci6208 = { - .driver_name = PCI6208_DRIVER_NAME, - .module = THIS_MODULE, - .attach = pci6208_attach, - .detach = pci6208_detach, -}; - -static int __devinit driver_pci6208_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, &driver_pci6208); -} - -static void __devexit driver_pci6208_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver driver_pci6208_pci_driver = { - .id_table = pci6208_pci_table, - .probe = &driver_pci6208_pci_probe, - .remove = __devexit_p(&driver_pci6208_pci_remove) -}; - -static int __init driver_pci6208_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_pci6208); - if (retval < 0) - return retval; - - driver_pci6208_pci_driver.name = (char *)driver_pci6208.driver_name; - return pci_register_driver(&driver_pci6208_pci_driver); -} - -static void __exit driver_pci6208_cleanup_module(void) -{ - pci_unregister_driver(&driver_pci6208_pci_driver); - comedi_driver_unregister(&driver_pci6208); -} - -module_init(driver_pci6208_init_module); -module_exit(driver_pci6208_cleanup_module); - -static int pci6208_find_device(struct comedi_device *dev, int bus, int slot); -static int -pci6208_pci_setup(struct pci_dev *pci_dev, unsigned long *io_base_ptr, - int dev_minor); - -/*read/write functions*/ -static int pci6208_ao_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int pci6208_ao_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -/* static int pci6208_dio_insn_bits (struct comedi_device *dev, - * struct comedi_subdevice *s, */ -/* struct comedi_insn *insn,unsigned int *data); */ -/* static int pci6208_dio_insn_config(struct comedi_device *dev, - * struct comedi_subdevice *s, */ -/* struct comedi_insn *insn,unsigned int *data); */ - -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ -static int pci6208_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - int retval; - unsigned long io_base; - - printk(KERN_INFO "comedi%d: pci6208: ", dev->minor); - - retval = alloc_private(dev, sizeof(struct pci6208_private)); - if (retval < 0) - return retval; - - retval = pci6208_find_device(dev, it->options[0], it->options[1]); - if (retval < 0) - return retval; - - retval = pci6208_pci_setup(devpriv->pci_dev, &io_base, dev->minor); - if (retval < 0) - return retval; - - dev->iobase = io_base; - dev->board_name = thisboard->name; - -/* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_subdevices(dev, 2) < 0) - return -ENOMEM; - - s = dev->subdevices + 0; - /* analog output subdevice */ - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE; /* anything else to add here?? */ - s->n_chan = thisboard->ao_chans; - s->maxdata = 0xffff; /* 16-bit DAC */ - s->range_table = &range_bipolar10; /* this needs to be checked. */ - s->insn_write = pci6208_ao_winsn; - s->insn_read = pci6208_ao_rinsn; - - /* s=dev->subdevices+1; */ - /* digital i/o subdevice */ - /* s->type=COMEDI_SUBD_DIO; */ - /* s->subdev_flags=SDF_READABLE|SDF_WRITABLE; */ - /* s->n_chan=16; */ - /* s->maxdata=1; */ - /* s->range_table=&range_digital; */ - /* s->insn_bits = pci6208_dio_insn_bits; */ - /* s->insn_config = pci6208_dio_insn_config; */ - - printk(KERN_INFO "attached\n"); - - return 1; -} - -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int pci6208_detach(struct comedi_device *dev) -{ - printk(KERN_INFO "comedi%d: pci6208: remove\n", dev->minor); - - if (devpriv && devpriv->pci_dev) { - if (dev->iobase) - comedi_pci_disable(devpriv->pci_dev); - pci_dev_put(devpriv->pci_dev); - } - - return 0; -} - static int pci6208_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -442,6 +280,125 @@ pci6208_pci_setup(struct pci_dev *pci_dev, unsigned long *io_base_ptr, return 0; } +static int pci6208_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + int retval; + unsigned long io_base; + + printk(KERN_INFO "comedi%d: pci6208: ", dev->minor); + + retval = alloc_private(dev, sizeof(struct pci6208_private)); + if (retval < 0) + return retval; + + retval = pci6208_find_device(dev, it->options[0], it->options[1]); + if (retval < 0) + return retval; + + retval = pci6208_pci_setup(devpriv->pci_dev, &io_base, dev->minor); + if (retval < 0) + return retval; + + dev->iobase = io_base; + dev->board_name = thisboard->name; + + if (alloc_subdevices(dev, 2) < 0) + return -ENOMEM; + + s = dev->subdevices + 0; + /* analog output subdevice */ + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE; /* anything else to add here?? */ + s->n_chan = thisboard->ao_chans; + s->maxdata = 0xffff; /* 16-bit DAC */ + s->range_table = &range_bipolar10; /* this needs to be checked. */ + s->insn_write = pci6208_ao_winsn; + s->insn_read = pci6208_ao_rinsn; + + /* s=dev->subdevices+1; */ + /* digital i/o subdevice */ + /* s->type=COMEDI_SUBD_DIO; */ + /* s->subdev_flags=SDF_READABLE|SDF_WRITABLE; */ + /* s->n_chan=16; */ + /* s->maxdata=1; */ + /* s->range_table=&range_digital; */ + /* s->insn_bits = pci6208_dio_insn_bits; */ + /* s->insn_config = pci6208_dio_insn_config; */ + + printk(KERN_INFO "attached\n"); + + return 1; +} + +static int pci6208_detach(struct comedi_device *dev) +{ + printk(KERN_INFO "comedi%d: pci6208: remove\n", dev->minor); + + if (devpriv && devpriv->pci_dev) { + if (dev->iobase) + comedi_pci_disable(devpriv->pci_dev); + pci_dev_put(devpriv->pci_dev); + } + + return 0; +} + +static struct comedi_driver driver_pci6208 = { + .driver_name = PCI6208_DRIVER_NAME, + .module = THIS_MODULE, + .attach = pci6208_attach, + .detach = pci6208_detach, +}; + +static int __devinit driver_pci6208_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &driver_pci6208); +} + +static void __devexit driver_pci6208_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +/* This is used by modprobe to translate PCI IDs to drivers. Should + * only be used for PCI and ISA-PnP devices */ +static DEFINE_PCI_DEVICE_TABLE(pci6208_pci_table) = { + /* { PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */ + /* { PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */ + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, 0x6208) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, pci6208_pci_table); + +static struct pci_driver driver_pci6208_pci_driver = { + .id_table = pci6208_pci_table, + .probe = driver_pci6208_pci_probe, + .remove = __devexit_p(driver_pci6208_pci_remove), +}; + +static int __init driver_pci6208_init_module(void) +{ + int retval; + + retval = comedi_driver_register(&driver_pci6208); + if (retval < 0) + return retval; + + driver_pci6208_pci_driver.name = (char *)driver_pci6208.driver_name; + return pci_register_driver(&driver_pci6208_pci_driver); +} +module_init(driver_pci6208_init_module); + +static void __exit driver_pci6208_cleanup_module(void) +{ + pci_unregister_driver(&driver_pci6208_pci_driver); + comedi_driver_unregister(&driver_pci6208); +} +module_exit(driver_pci6208_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 1b18bbb580e96af4e12788fcc1758f68a5cebf86 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 23 Apr 2012 14:50:39 -0700 Subject: staging: comedi: refactor the acl7225b driver to remove the forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and struct boardtype variables to the end of the source. This is more typical of how other drivers are written and removes the need to the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/acl7225b.c b/drivers/staging/comedi/drivers/acl7225b.c index f4a301a..ef685fc 100644 --- a/drivers/staging/comedi/drivers/acl7225b.c +++ b/drivers/staging/comedi/drivers/acl7225b.c @@ -22,45 +22,13 @@ Devices: [Adlink] ACL-7225b (acl7225b), [ICP] P16R16DIO (p16r16dio) #define ACL7225_DI_LO 2 /* Digital input low byte (DI0-DI7) */ #define ACL7225_DI_HI 3 /* Digital input high byte (DI8-DI15) */ -static int acl7225b_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int acl7225b_detach(struct comedi_device *dev); - struct boardtype { const char *name; /* driver name */ int io_range; /* len of I/O space */ }; -static const struct boardtype boardtypes[] = { - {"acl7225b", ACL7225_SIZE,}, - {"p16r16dio", P16R16DIO_SIZE,}, -}; - #define this_board ((const struct boardtype *)dev->board_ptr) -static struct comedi_driver driver_acl7225b = { - .driver_name = "acl7225b", - .module = THIS_MODULE, - .attach = acl7225b_attach, - .detach = acl7225b_detach, - .board_name = &boardtypes[0].name, - .num_names = ARRAY_SIZE(boardtypes), - .offset = sizeof(struct boardtype), -}; - -static int __init driver_acl7225b_init_module(void) -{ - return comedi_driver_register(&driver_acl7225b); -} - -static void __exit driver_acl7225b_cleanup_module(void) -{ - comedi_driver_unregister(&driver_acl7225b); -} - -module_init(driver_acl7225b_init_module); -module_exit(driver_acl7225b_cleanup_module); - static int acl7225b_do_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -161,6 +129,33 @@ static int acl7225b_detach(struct comedi_device *dev) return 0; } +static const struct boardtype boardtypes[] = { + { "acl7225b", ACL7225_SIZE, }, + { "p16r16dio", P16R16DIO_SIZE, }, +}; + +static struct comedi_driver driver_acl7225b = { + .driver_name = "acl7225b", + .module = THIS_MODULE, + .attach = acl7225b_attach, + .detach = acl7225b_detach, + .board_name = &boardtypes[0].name, + .num_names = ARRAY_SIZE(boardtypes), + .offset = sizeof(struct boardtype), +}; + +static int __init driver_acl7225b_init_module(void) +{ + return comedi_driver_register(&driver_acl7225b); +} +module_init(driver_acl7225b_init_module); + +static void __exit driver_acl7225b_cleanup_module(void) +{ + comedi_driver_unregister(&driver_acl7225b); +} +module_exit(driver_acl7225b_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 3e699ed17040f7c8474bbeaf834077f78d301e13 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 23 Apr 2012 09:38:24 -0700 Subject: staging: comedi: refactor 8255 driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver variable to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Also, move the do_config function to remove needing to have a forward declaration for that routine. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 6c26ac8..ed80397 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -107,31 +107,6 @@ struct subdev_8255_struct { #define CALLBACK_FUNC (((struct subdev_8255_struct *)s->private)->cb_func) #define subdevpriv ((struct subdev_8255_struct *)s->private) -static int dev_8255_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int dev_8255_detach(struct comedi_device *dev); -static struct comedi_driver driver_8255 = { - .driver_name = "8255", - .module = THIS_MODULE, - .attach = dev_8255_attach, - .detach = dev_8255_detach, -}; - -static int __init driver_8255_init_module(void) -{ - return comedi_driver_register(&driver_8255); -} - -static void __exit driver_8255_cleanup_module(void) -{ - comedi_driver_unregister(&driver_8255); -} - -module_init(driver_8255_init_module); -module_exit(driver_8255_cleanup_module); - -static void do_config(struct comedi_device *dev, struct comedi_subdevice *s); - void subdev_8255_interrupt(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -185,6 +160,23 @@ static int subdev_8255_insn(struct comedi_device *dev, return 2; } +static void do_config(struct comedi_device *dev, struct comedi_subdevice *s) +{ + int config; + + config = CR_CW; + /* 1 in io_bits indicates output, 1 in config indicates input */ + if (!(s->io_bits & 0x0000ff)) + config |= CR_A_IO; + if (!(s->io_bits & 0x00ff00)) + config |= CR_B_IO; + if (!(s->io_bits & 0x0f0000)) + config |= CR_C_LO_IO; + if (!(s->io_bits & 0xf00000)) + config |= CR_C_HI_IO; + CALLBACK_FUNC(1, _8255_CR, config, CALLBACK_ARG); +} + static int subdev_8255_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -222,23 +214,6 @@ static int subdev_8255_insn_config(struct comedi_device *dev, return 1; } -static void do_config(struct comedi_device *dev, struct comedi_subdevice *s) -{ - int config; - - config = CR_CW; - /* 1 in io_bits indicates output, 1 in config indicates input */ - if (!(s->io_bits & 0x0000ff)) - config |= CR_A_IO; - if (!(s->io_bits & 0x00ff00)) - config |= CR_B_IO; - if (!(s->io_bits & 0x0f0000)) - config |= CR_C_LO_IO; - if (!(s->io_bits & 0xf00000)) - config |= CR_C_HI_IO; - CALLBACK_FUNC(1, _8255_CR, config, CALLBACK_ARG); -} - static int subdev_8255_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) @@ -462,6 +437,25 @@ static int dev_8255_detach(struct comedi_device *dev) return 0; } +static struct comedi_driver driver_8255 = { + .driver_name = "8255", + .module = THIS_MODULE, + .attach = dev_8255_attach, + .detach = dev_8255_detach, +}; + +static int __init driver_8255_init_module(void) +{ + return comedi_driver_register(&driver_8255); +} +module_init(driver_8255_init_module); + +static void __exit driver_8255_cleanup_module(void) +{ + comedi_driver_unregister(&driver_8255); +} +module_exit(driver_8255_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From e17b8e484d429134b9693405e0f9b0936e007885 Mon Sep 17 00:00:00 2001 From: Gerard Snitselaar Date: Mon, 23 Apr 2012 18:30:06 -0700 Subject: staging: comedi: resolve section mismatch in s626 s626_attach is referencing s626_pci_table which is annotated __devinitconst. Put pci vendor/device ids in the s626_board struct and use s626_boards instead similar to what is done in gsc_hpdi. v2: I had moved the PCI id defines to s626.h earlier, but later decided to leave them in s626.c and forgot to move them up above where they are being used in s626_boards. Signed-off-by: Gerard Snitselaar Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 5e04d6a..a0b7c71 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -83,8 +83,17 @@ MODULE_AUTHOR("Gianluca Palli "); MODULE_DESCRIPTION("Sensoray 626 Comedi driver module"); MODULE_LICENSE("GPL"); +#define PCI_VENDOR_ID_S626 0x1131 +#define PCI_DEVICE_ID_S626 0x7146 +#define PCI_SUBVENDOR_ID_S626 0x6000 +#define PCI_SUBDEVICE_ID_S626 0x0272 + struct s626_board { const char *name; + int vendor_id; + int device_id; + int subvendor_id; + int subdevice_id; int ai_chans; int ai_bits; int ao_chans; @@ -97,6 +106,10 @@ struct s626_board { static const struct s626_board s626_boards[] = { { .name = "s626", + .vendor_id = PCI_VENDOR_ID_S626, + .device_id = PCI_DEVICE_ID_S626, + .subvendor_id = PCI_SUBVENDOR_ID_S626, + .subdevice_id = PCI_SUBDEVICE_ID_S626, .ai_chans = S626_ADC_CHANNELS, .ai_bits = 14, .ao_chans = S626_DAC_CHANNELS, @@ -108,8 +121,6 @@ static const struct s626_board s626_boards[] = { }; #define thisboard ((const struct s626_board *)dev->board_ptr) -#define PCI_VENDOR_ID_S626 0x1131 -#define PCI_DEVICE_ID_S626 0x7146 /* * For devices with vendor:device id == 0x1131:0x7146 you must specify @@ -117,7 +128,7 @@ static const struct s626_board s626_boards[] = { * Philips SAA7146 media/dvb based cards. */ static DEFINE_PCI_DEVICE_TABLE(s626_pci_table) = { - {PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626, 0x6000, 0x0272, 0, 0, 0}, + {PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626, PCI_SUBVENDOR_ID_S626, PCI_SUBDEVICE_ID_S626, 0, 0, 0}, {0} }; @@ -554,17 +565,17 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) resource_size_t resourceStart; dma_addr_t appdma; struct comedi_subdevice *s; - const struct pci_device_id *ids; struct pci_dev *pdev = NULL; if (alloc_private(dev, sizeof(struct s626_private)) < 0) return -ENOMEM; - for (i = 0; i < (ARRAY_SIZE(s626_pci_table) - 1) && !pdev; i++) { - ids = &s626_pci_table[i]; + for (i = 0; i < ARRAY_SIZE(s626_boards) && !pdev; i++) { do { - pdev = pci_get_subsys(ids->vendor, ids->device, - ids->subvendor, ids->subdevice, + pdev = pci_get_subsys(s626_boards[i].vendor_id, + s626_boards[i].device_id, + s626_boards[i].subvendor_id, + s626_boards[i].subdevice_id, pdev); if ((it->options[0] || it->options[1]) && pdev) { -- cgit v0.10.2 From 3c97c08b5735ac05ebc0cbd0aa7722393f50b846 Mon Sep 17 00:00:00 2001 From: Jon Brenner Date: Tue, 24 Apr 2012 11:56:49 -0500 Subject: staging: iio: add TAOS tsl2x7x driver TAOS device driver (version 9) for the tsl/tmd 2771 and 2772 device families (inc. all variants). Update: Removed bonus lines. Signed-off-by: Jon Brenner Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2583 b/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2583 new file mode 100755 index 0000000..470f7ad --- /dev/null +++ b/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2583 @@ -0,0 +1,6 @@ +What: /sys/bus/iio/devices/device[n]/in_illuminance0_calibrate +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + This property causes an internal calibration of the als gain trim + value which is later used in calculating illuminance in lux. diff --git a/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2x7x b/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2x7x new file mode 100755 index 0000000..b2798b2 --- /dev/null +++ b/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2x7x @@ -0,0 +1,13 @@ +What: /sys/bus/iio/devices/device[n]/in_illuminance0_calibrate +KernelVersion: 3.3-rc1 +Contact: linux-iio@vger.kernel.org +Description: + Causes an internal calibration of the als gain trim + value which is later used in calculating illuminance in lux. + +What: /sys/bus/iio/devices/device[n]/in_proximity0_calibrate +KernelVersion: 3.3-rc1 +Contact: linux-iio@vger.kernel.org +Description: + Causes a recalculation and adjustment to the + proximity_thresh_rising_value. diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio b/drivers/staging/iio/Documentation/sysfs-bus-iio index ca12784..eec9acb 100644 --- a/drivers/staging/iio/Documentation/sysfs-bus-iio +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio @@ -243,6 +243,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_accel_z_calibbias What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_x_calibbias What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_calibbias What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_calibbias +What: /sys/bus/iio/devices/iio:deviceX/in_illuminance0_calibbias +What: /sys/bus/iio/devices/iio:deviceX/in_proximity0_calibbias KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: @@ -258,6 +260,8 @@ What /sys/bus/iio/devices/iio:deviceX/in_accel_z_calibscale What /sys/bus/iio/devices/iio:deviceX/in_anglvel_x_calibscale What /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_calibscale What /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_calibscale +what /sys/bus/iio/devices/iio:deviceX/in_illuminance0_calibscale +what /sys/bus/iio/devices/iio:deviceX/in_proximity0_calibscale KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: @@ -457,6 +461,10 @@ What: /sys/.../events/in_voltageY_raw_thresh_rising_value What: /sys/.../events/in_voltageY_raw_thresh_falling_value What: /sys/.../events/in_tempY_raw_thresh_rising_value What: /sys/.../events/in_tempY_raw_thresh_falling_value +What: /sys/.../events/in_illuminance0_thresh_falling_value +what: /sys/.../events/in_illuminance0_thresh_rising_value +what: /sys/.../events/in_proximity0_thresh_falling_value +what: /sys/.../events/in_proximity0_thresh_rising_value KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: @@ -556,6 +564,8 @@ What: /sys/.../events/in_tempY_thresh_falling_period What: /sys/.../events/in_tempY_roc_rising_period What: /sys/.../events/in_tempY_roc_falling_period What: /sys/.../events/in_accel_x&y&z_mag_falling_period +What: /sys/.../events/in_intensity0_thresh_period +What: /sys/.../events/in_proximity0_thresh_period KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-light b/drivers/staging/iio/Documentation/sysfs-bus-iio-light index edbf470..715c74d 100644 --- a/drivers/staging/iio/Documentation/sysfs-bus-iio-light +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio-light @@ -26,7 +26,7 @@ Description: Hardware dependent list of possible values supported for the adc_resolution of the given sensor. -What: /sys/bus/iio/devices/device[n]/illuminance0[_input|_raw] +What: /sys/bus/iio/devices/device[n]/in_illuminance0[_input|_raw] KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: @@ -45,7 +45,7 @@ Description: do this calculation manually by reading the infrared sensor value and doing the negation in sw. -What: /sys/bus/iio/devices/device[n]/proximity[_input|_raw] +What: /sys/bus/iio/devices/device[n]/in_proximity[_input|_raw] KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: @@ -63,23 +63,22 @@ Description: and if expressed in SI units, should include _input. If this value is not in SI units, then it should include _raw. -What: /sys/bus/iio/devices/device[n]/illuminance0_target +What: /sys/bus/iio/devices/device[n]/in_illuminance0_target KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: This property gets/sets the last known external lux measurement used in/for calibration. -What: /sys/bus/iio/devices/device[n]/illuminance0_integration_time +What: /sys/bus/iio/devices/device[n]/in_illuminance0_integration_time KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: This property gets/sets the sensors ADC analog integration time. -What: /sys/bus/iio/devices/device[n]/illuminance0_calibscale +What: /sys/bus/iio/devices/device[n]/in_illuminance0_lux_table KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: - Hardware or software applied calibration scale factor assumed - to account for attenuation due to industrial design (glass - filters or aperture holes). + This property gets/sets the table of coefficients + used in calculating illuminance in lux. diff --git a/drivers/staging/iio/light/Kconfig b/drivers/staging/iio/light/Kconfig index fd39f72..4bed30e 100644 --- a/drivers/staging/iio/light/Kconfig +++ b/drivers/staging/iio/light/Kconfig @@ -42,4 +42,12 @@ config TSL2583 Provides support for the TAOS tsl2580, tsl2581 and tsl2583 devices. Access ALS data via iio, sysfs. +config TSL2x7x + tristate "TAOS TSL/TMD2x71 and TSL/TMD2x72 Family of light and proximity sensors" + depends on I2C + help + Support for: tsl2571, tsl2671, tmd2671, tsl2771, tmd2771, tsl2572, tsl2672, + tmd2672, tsl2772, tmd2772 devices. + Provides iio_events and direct access via sysfs. + endmenu diff --git a/drivers/staging/iio/light/Makefile b/drivers/staging/iio/light/Makefile index 535d313..141af1e 100644 --- a/drivers/staging/iio/light/Makefile +++ b/drivers/staging/iio/light/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o obj-$(CONFIG_SENSORS_ISL29018) += isl29018.o obj-$(CONFIG_SENSORS_ISL29028) += isl29028.o obj-$(CONFIG_TSL2583) += tsl2583.o +obj-$(CONFIG_TSL2x7x) += tsl2x7x_core.o diff --git a/drivers/staging/iio/light/tsl2x7x.h b/drivers/staging/iio/light/tsl2x7x.h new file mode 100755 index 0000000..c4acf5f --- /dev/null +++ b/drivers/staging/iio/light/tsl2x7x.h @@ -0,0 +1,100 @@ +/* + * Device driver for monitoring ambient light intensity (lux) + * and proximity (prox) within the TAOS TSL2X7X family of devices. + * + * Copyright (c) 2012, TAOS Corporation. + * + * 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. + */ + +#ifndef __TSL2X7X_H +#define __TSL2X7X_H +#include + +/* Max number of segments allowable in LUX table */ +#define TSL2X7X_MAX_LUX_TABLE_SIZE 9 +#define MAX_DEFAULT_TABLE_BYTES (sizeof(int) * TSL2X7X_MAX_LUX_TABLE_SIZE) + +struct iio_dev; + +struct tsl2x7x_lux { + unsigned int ratio; + unsigned int ch0; + unsigned int ch1; +}; + +/** + * struct tsl2x7x_default_settings - power on defaults unless + * overridden by platform data. + * @als_time: ALS Integration time - multiple of 50mS + * @als_gain: Index into the ALS gain table. + * @als_gain_trim: default gain trim to account for + * aperture effects. + * @wait_time: Time between PRX and ALS cycles + * in 2.7 periods + * @prx_time: 5.2ms prox integration time - + * decrease in 2.7ms periods + * @prx_gain: Proximity gain index + * @prox_config: Prox configuration filters. + * @als_cal_target: Known external ALS reading for + * calibration. + * @interrupts_en: Enable/Disable - 0x00 = none, 0x10 = als, + * 0x20 = prx, 0x30 = bth + * @persistence: H/W Filters, Number of 'out of limits' + * ADC readings PRX/ALS. + * @als_thresh_low: CH0 'low' count to trigger interrupt. + * @als_thresh_high: CH0 'high' count to trigger interrupt. + * @prox_thres_low: Low threshold proximity detection. + * @prox_thres_high: High threshold proximity detection + * @prox_pulse_count: Number if proximity emitter pulses + * @prox_max_samples_cal: Used for prox cal. + */ +struct tsl2x7x_settings { + int als_time; + int als_gain; + int als_gain_trim; + int wait_time; + int prx_time; + int prox_gain; + int prox_config; + int als_cal_target; + u8 interrupts_en; + u8 persistence; + int als_thresh_low; + int als_thresh_high; + int prox_thres_low; + int prox_thres_high; + int prox_pulse_count; + int prox_max_samples_cal; +}; + +/** + * struct tsl2X7X_platform_data - Platform callback, glass and defaults + * @platform_power: Suspend/resume platform callback + * @power_on: Power on callback + * @power_off: Power off callback + * @platform_lux_table: Device specific glass coefficents + * @platform_default_settings: Device specific power on defaults + * + */ +struct tsl2X7X_platform_data { + int (*platform_power)(struct device *dev, pm_message_t); + int (*power_on) (struct iio_dev *indio_dev); + int (*power_off) (struct i2c_client *dev); + struct tsl2x7x_lux platform_lux_table[TSL2X7X_MAX_LUX_TABLE_SIZE]; + struct tsl2x7x_settings *platform_default_settings; +}; + +#endif /* __TSL2X7X_H */ diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c new file mode 100755 index 0000000..ff44989 --- /dev/null +++ b/drivers/staging/iio/light/tsl2x7x_core.c @@ -0,0 +1,2072 @@ +/* + * Device driver for monitoring ambient light intensity in (lux) + * and proximity detection (prox) within the TAOS TSL2X7X family of devices. + * + * Copyright (c) 2012, TAOS Corporation. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include "tsl2x7x.h" +#include "../events.h" +#include "../iio.h" +#include "../sysfs.h" + +/* Cal defs*/ +#define PROX_STAT_CAL 0 +#define PROX_STAT_SAMP 1 +#define MAX_SAMPLES_CAL 200 + +/* TSL2X7X Device ID */ +#define TRITON_ID 0x00 +#define SWORDFISH_ID 0x30 +#define HALIBUT_ID 0x20 + +/* Lux calculation constants */ +#define TSL2X7X_LUX_CALC_OVER_FLOW 65535 + +/* TAOS Register definitions - note: + * depending on device, some of these register are not used and the + * register address is benign. + */ +/* 2X7X register offsets */ +#define TSL2X7X_MAX_CONFIG_REG 16 + +/* Device Registers and Masks */ +#define TSL2X7X_CNTRL 0x00 +#define TSL2X7X_ALS_TIME 0X01 +#define TSL2X7X_PRX_TIME 0x02 +#define TSL2X7X_WAIT_TIME 0x03 +#define TSL2X7X_ALS_MINTHRESHLO 0X04 +#define TSL2X7X_ALS_MINTHRESHHI 0X05 +#define TSL2X7X_ALS_MAXTHRESHLO 0X06 +#define TSL2X7X_ALS_MAXTHRESHHI 0X07 +#define TSL2X7X_PRX_MINTHRESHLO 0X08 +#define TSL2X7X_PRX_MINTHRESHHI 0X09 +#define TSL2X7X_PRX_MAXTHRESHLO 0X0A +#define TSL2X7X_PRX_MAXTHRESHHI 0X0B +#define TSL2X7X_PERSISTENCE 0x0C +#define TSL2X7X_PRX_CONFIG 0x0D +#define TSL2X7X_PRX_COUNT 0x0E +#define TSL2X7X_GAIN 0x0F +#define TSL2X7X_NOTUSED 0x10 +#define TSL2X7X_REVID 0x11 +#define TSL2X7X_CHIPID 0x12 +#define TSL2X7X_STATUS 0x13 +#define TSL2X7X_ALS_CHAN0LO 0x14 +#define TSL2X7X_ALS_CHAN0HI 0x15 +#define TSL2X7X_ALS_CHAN1LO 0x16 +#define TSL2X7X_ALS_CHAN1HI 0x17 +#define TSL2X7X_PRX_LO 0x18 +#define TSL2X7X_PRX_HI 0x19 + +/* tsl2X7X cmd reg masks */ +#define TSL2X7X_CMD_REG 0x80 +#define TSL2X7X_CMD_SPL_FN 0x60 + +#define TSL2X7X_CMD_PROX_INT_CLR 0X05 +#define TSL2X7X_CMD_ALS_INT_CLR 0x06 +#define TSL2X7X_CMD_PROXALS_INT_CLR 0X07 + +/* tsl2X7X cntrl reg masks */ +#define TSL2X7X_CNTL_ADC_ENBL 0x02 +#define TSL2X7X_CNTL_PWR_ON 0x01 + +/* tsl2X7X status reg masks */ +#define TSL2X7X_STA_ADC_VALID 0x01 +#define TSL2X7X_STA_PRX_VALID 0x02 +#define TSL2X7X_STA_ADC_PRX_VALID (TSL2X7X_STA_ADC_VALID |\ + TSL2X7X_STA_PRX_VALID) +#define TSL2X7X_STA_ALS_INTR 0x10 +#define TSL2X7X_STA_PRX_INTR 0x20 + +/* tsl2X7X cntrl reg masks */ +#define TSL2X7X_CNTL_REG_CLEAR 0x00 +#define TSL2X7X_CNTL_PROX_INT_ENBL 0X20 +#define TSL2X7X_CNTL_ALS_INT_ENBL 0X10 +#define TSL2X7X_CNTL_WAIT_TMR_ENBL 0X08 +#define TSL2X7X_CNTL_PROX_DET_ENBL 0X04 +#define TSL2X7X_CNTL_PWRON 0x01 +#define TSL2X7X_CNTL_ALSPON_ENBL 0x03 +#define TSL2X7X_CNTL_INTALSPON_ENBL 0x13 +#define TSL2X7X_CNTL_PROXPON_ENBL 0x0F +#define TSL2X7X_CNTL_INTPROXPON_ENBL 0x2F + +/*Prox diode to use */ +#define TSL2X7X_DIODE0 0x10 +#define TSL2X7X_DIODE1 0x20 +#define TSL2X7X_DIODE_BOTH 0x30 + +/* LED Power */ +#define TSL2X7X_mA100 0x00 +#define TSL2X7X_mA50 0x40 +#define TSL2X7X_mA25 0x80 +#define TSL2X7X_mA13 0xD0 +#define TSL2X7X_MAX_TIMER_CNT (0xFF) + +/*Common device IIO EventMask */ +#define TSL2X7X_EVENT_MASK \ + (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \ + IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)), + +/* TAOS txx2x7x Device family members */ +enum { + tsl2571, + tsl2671, + tmd2671, + tsl2771, + tmd2771, + tsl2572, + tsl2672, + tmd2672, + tsl2772, + tmd2772 +}; + +enum { + TSL2X7X_CHIP_UNKNOWN = 0, + TSL2X7X_CHIP_WORKING = 1, + TSL2X7X_CHIP_SUSPENDED = 2 +}; + +struct tsl2x7x_parse_result { + int integer; + int fract; +}; + +/* Per-device data */ +struct tsl2x7x_als_info { + u16 als_ch0; + u16 als_ch1; + u16 lux; +}; + +struct tsl2x7x_prox_stat { + int min; + int max; + int mean; + unsigned long stddev; +}; + +struct tsl2x7x_chip_info { + int chan_table_elements; + struct iio_chan_spec channel[4]; + const struct iio_info *info; +}; + +struct tsl2X7X_chip { + kernel_ulong_t id; + struct mutex prox_mutex; + struct mutex als_mutex; + struct i2c_client *client; + u16 prox_data; + struct tsl2x7x_als_info als_cur_info; + struct tsl2x7x_settings tsl2x7x_settings; + struct tsl2X7X_platform_data *pdata; + int als_time_scale; + int als_saturation; + int tsl2x7x_chip_status; + u8 tsl2x7x_config[TSL2X7X_MAX_CONFIG_REG]; + const struct tsl2x7x_chip_info *chip_info; + const struct iio_info *info; + s64 event_timestamp; + /* This structure is intentionally large to accommodate + * updates via sysfs. */ + /* Sized to 9 = max 8 segments + 1 termination segment */ + struct tsl2x7x_lux tsl2x7x_device_lux[TSL2X7X_MAX_LUX_TABLE_SIZE]; +}; + +/* Different devices require different coefficents */ +static const struct tsl2x7x_lux tsl2x71_lux_table[] = { + { 14461, 611, 1211 }, + { 18540, 352, 623 }, + { 0, 0, 0 }, +}; + +static const struct tsl2x7x_lux tmd2x71_lux_table[] = { + { 11635, 115, 256 }, + { 15536, 87, 179 }, + { 0, 0, 0 }, +}; + +static const struct tsl2x7x_lux tsl2x72_lux_table[] = { + { 14013, 466, 917 }, + { 18222, 310, 552 }, + { 0, 0, 0 }, +}; + +static const struct tsl2x7x_lux tmd2x72_lux_table[] = { + { 13218, 130, 262 }, + { 17592, 92, 169 }, + { 0, 0, 0 }, +}; + +static const struct tsl2x7x_lux *tsl2x7x_default_lux_table_group[] = { + [tsl2571] = tsl2x71_lux_table, + [tsl2671] = tsl2x71_lux_table, + [tmd2671] = tmd2x71_lux_table, + [tsl2771] = tsl2x71_lux_table, + [tmd2771] = tmd2x71_lux_table, + [tsl2572] = tsl2x72_lux_table, + [tsl2672] = tsl2x72_lux_table, + [tmd2672] = tmd2x72_lux_table, + [tsl2772] = tsl2x72_lux_table, + [tmd2772] = tmd2x72_lux_table, +}; + +static const struct tsl2x7x_settings tsl2x7x_default_settings = { + .als_time = 219, /* 101 ms */ + .als_gain = 0, + .prx_time = 254, /* 5.4 ms */ + .prox_gain = 1, + .wait_time = 245, + .prox_config = 0, + .als_gain_trim = 1000, + .als_cal_target = 150, + .als_thresh_low = 200, + .als_thresh_high = 256, + .persistence = 255, + .interrupts_en = 0, + .prox_thres_low = 0, + .prox_thres_high = 512, + .prox_max_samples_cal = 30, + .prox_pulse_count = 8 +}; + +static const s16 tsl2X7X_als_gainadj[] = { + 1, + 8, + 16, + 120 +}; + +static const s16 tsl2X7X_prx_gainadj[] = { + 1, + 2, + 4, + 8 +}; + +/* Channel variations */ +enum { + ALS, + PRX, + ALSPRX, + PRX2, + ALSPRX2, +}; + +const u8 device_channel_config[] = { + ALS, + PRX, + PRX, + ALSPRX, + ALSPRX, + ALS, + PRX2, + PRX2, + ALSPRX2, + ALSPRX2 +}; + +/** + * tsl2x7x_parse_buffer() - parse a decimal result from a buffer. + * @*buf: pointer to char buffer to parse + * @*result: pointer to buffer to contain + * resulting interger / decimal as ints. + * + */ +static int +tsl2x7x_parse_buffer(const char *buf, struct tsl2x7x_parse_result *result) +{ + int integer = 0, fract = 0, fract_mult = 100000; + bool integer_part = true, negative = false; + + if (buf[0] == '-') { + negative = true; + buf++; + } + + while (*buf) { + if ('0' <= *buf && *buf <= '9') { + if (integer_part) + integer = integer*10 + *buf - '0'; + else { + fract += fract_mult*(*buf - '0'); + if (fract_mult == 1) + break; + fract_mult /= 10; + } + } else if (*buf == '\n') { + if (*(buf + 1) == '\0') + break; + else + return -EINVAL; + } else if (*buf == '.') { + integer_part = false; + } else { + return -EINVAL; + } + buf++; + } + if (negative) { + if (integer) + integer = -integer; + else + fract = -fract; + } + + result->integer = integer; + result->fract = fract; + + return 0; +} + +/** + * tsl2x7x_i2c_read() - Read a byte from a register. + * @client: i2c client + * @reg: device register to read from + * @*val: pointer to location to store register contents. + * + */ +static int +tsl2x7x_i2c_read(struct i2c_client *client, u8 reg, u8 *val) +{ + int ret = 0; + + /* select register to write */ + ret = i2c_smbus_write_byte(client, (TSL2X7X_CMD_REG | reg)); + if (ret < 0) { + dev_err(&client->dev, "%s: failed to write register %x\n" + , __func__, reg); + return ret; + } + + /* read the data */ + ret = i2c_smbus_read_byte(client); + if (ret >= 0) + *val = (u8)ret; + else + dev_err(&client->dev, "%s: failed to read register %x\n" + , __func__, reg); + + return ret; +} + +/** + * tsl2x7x_get_lux() - Reads and calculates current lux value. + * @indio_dev: pointer to IIO device + * + * The raw ch0 and ch1 values of the ambient light sensed in the last + * integration cycle are read from the device. + * Time scale factor array values are adjusted based on the integration time. + * The raw values are multiplied by a scale factor, and device gain is obtained + * using gain index. Limit checks are done next, then the ratio of a multiple + * of ch1 value, to the ch0 value, is calculated. Array tsl2x7x_device_lux[] + * is then scanned to find the first ratio value that is just above the ratio + * we just calculated. The ch0 and ch1 multiplier constants in the array are + * then used along with the time scale factor array values, to calculate the + * lux. + */ +static int tsl2x7x_get_lux(struct iio_dev *indio_dev) +{ + u16 ch0, ch1; /* separated ch0/ch1 data from device */ + u32 lux; /* raw lux calculated from device data */ + u64 lux64; + u32 ratio; + u8 buf[4]; + struct tsl2x7x_lux *p; + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + int i, ret; + u32 ch0lux = 0; + u32 ch1lux = 0; + + if (mutex_trylock(&chip->als_mutex) == 0) + return chip->als_cur_info.lux; /* busy, so return LAST VALUE */ + + if (chip->tsl2x7x_chip_status != TSL2X7X_CHIP_WORKING) { + /* device is not enabled */ + dev_err(&chip->client->dev, "%s: device is not enabled\n", + __func__); + ret = -EBUSY ; + goto out_unlock; + } + + ret = tsl2x7x_i2c_read(chip->client, + (TSL2X7X_CMD_REG | TSL2X7X_STATUS), &buf[0]); + if (ret < 0) { + dev_err(&chip->client->dev, + "%s: Failed to read STATUS Reg\n", __func__); + goto out_unlock; + } + /* is data new & valid */ + if (!(buf[0] & TSL2X7X_STA_ADC_VALID)) { + dev_err(&chip->client->dev, + "%s: data not valid yet\n", __func__); + ret = chip->als_cur_info.lux; /* return LAST VALUE */ + goto out_unlock; + } + + for (i = 0; i < 4; i++) { + ret = tsl2x7x_i2c_read(chip->client, + (TSL2X7X_CMD_REG | (TSL2X7X_ALS_CHAN0LO + i)), + &buf[i]); + if (ret < 0) { + dev_err(&chip->client->dev, + "%s: failed to read. err=%x\n", __func__, ret); + goto out_unlock; + } + } + + /* clear any existing interrupt status */ + ret = i2c_smbus_write_byte(chip->client, + (TSL2X7X_CMD_REG | + TSL2X7X_CMD_SPL_FN | + TSL2X7X_CMD_ALS_INT_CLR)); + if (ret < 0) { + dev_err(&chip->client->dev, + "%s: i2c_write_command failed - err = %d\n", + __func__, ret); + goto out_unlock; /* have no data, so return failure */ + } + + /* extract ALS/lux data */ + ch0 = le16_to_cpup((const __le16 *)&buf[0]); + ch1 = le16_to_cpup((const __le16 *)&buf[2]); + + chip->als_cur_info.als_ch0 = ch0; + chip->als_cur_info.als_ch1 = ch1; + + if ((ch0 >= chip->als_saturation) || (ch1 >= chip->als_saturation)) { + lux = TSL2X7X_LUX_CALC_OVER_FLOW; + goto return_max; + } + + if (ch0 == 0) { + /* have no data, so return LAST VALUE */ + ret = chip->als_cur_info.lux; + goto out_unlock; + } + /* calculate ratio */ + ratio = (ch1 << 15) / ch0; + /* convert to unscaled lux using the pointer to the table */ + p = (struct tsl2x7x_lux *) chip->tsl2x7x_device_lux; + while (p->ratio != 0 && p->ratio < ratio) + p++; + + if (p->ratio == 0) { + lux = 0; + } else { + ch0lux = DIV_ROUND_UP((ch0 * p->ch0), + tsl2X7X_als_gainadj[chip->tsl2x7x_settings.als_gain]); + ch1lux = DIV_ROUND_UP((ch1 * p->ch1), + tsl2X7X_als_gainadj[chip->tsl2x7x_settings.als_gain]); + lux = ch0lux - ch1lux; + } + + /* note: lux is 31 bit max at this point */ + if (ch1lux > ch0lux) { + dev_dbg(&chip->client->dev, "ch1lux > ch0lux-return last value\n"); + ret = chip->als_cur_info.lux; + goto out_unlock; + } + + /* adjust for active time scale */ + if (chip->als_time_scale == 0) + lux = 0; + else + lux = (lux + (chip->als_time_scale >> 1)) / + chip->als_time_scale; + + /* adjust for active gain scale + * The tsl2x7x_device_lux tables have a factor of 256 built-in. + * User-specified gain provides a multiplier. + * Apply user-specified gain before shifting right to retain precision. + * Use 64 bits to avoid overflow on multiplication. + * Then go back to 32 bits before division to avoid using div_u64(). + */ + + lux64 = lux; + lux64 = lux64 * chip->tsl2x7x_settings.als_gain_trim; + lux64 >>= 8; + lux = lux64; + lux = (lux + 500) / 1000; + + if (lux > TSL2X7X_LUX_CALC_OVER_FLOW) /* check for overflow */ + lux = TSL2X7X_LUX_CALC_OVER_FLOW; + + /* Update the structure with the latest lux. */ +return_max: + chip->als_cur_info.lux = lux; + ret = lux; + +out_unlock: + mutex_unlock(&chip->als_mutex); + + return ret; +} + +/** + * tsl2x7x_get_prox() - Reads proximity data registers and updates + * chip->prox_data. + * + * @indio_dev: pointer to IIO device + */ +static int tsl2x7x_get_prox(struct iio_dev *indio_dev) +{ + int i; + int ret; + u8 status; + u8 chdata[2]; + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + + if (mutex_trylock(&chip->prox_mutex) == 0) { + dev_err(&chip->client->dev, + "%s: Can't get prox mutex\n", __func__); + return -EBUSY; + } + + ret = tsl2x7x_i2c_read(chip->client, + (TSL2X7X_CMD_REG | TSL2X7X_STATUS), &status); + if (ret < 0) { + dev_err(&chip->client->dev, + "%s: i2c err=%d\n", __func__, ret); + goto prox_poll_err; + } + + switch (chip->id) { + case tsl2571: + case tsl2671: + case tmd2671: + case tsl2771: + case tmd2771: + if (!(status & TSL2X7X_STA_ADC_VALID)) + goto prox_poll_err; + break; + case tsl2572: + case tsl2672: + case tmd2672: + case tsl2772: + case tmd2772: + if (!(status & TSL2X7X_STA_PRX_VALID)) + goto prox_poll_err; + break; + } + + for (i = 0; i < 2; i++) { + ret = tsl2x7x_i2c_read(chip->client, + (TSL2X7X_CMD_REG | + (TSL2X7X_PRX_LO + i)), &chdata[i]); + if (ret < 0) + goto prox_poll_err; + } + + chip->prox_data = + le16_to_cpup((const __le16 *)&chdata[0]); + +prox_poll_err: + + mutex_unlock(&chip->prox_mutex); + + return chip->prox_data; +} + +/** + * tsl2x7x_defaults() - Populates the device nominal operating parameters + * with those provided by a 'platform' data struct or + * with prefined defaults. + * + * @chip: pointer to device structure. + */ +static void tsl2x7x_defaults(struct tsl2X7X_chip *chip) +{ + /* If Operational settings defined elsewhere.. */ + if (chip->pdata && chip->pdata->platform_default_settings != 0) + memcpy(&(chip->tsl2x7x_settings), + chip->pdata->platform_default_settings, + sizeof(tsl2x7x_default_settings)); + else + memcpy(&(chip->tsl2x7x_settings), + &tsl2x7x_default_settings, + sizeof(tsl2x7x_default_settings)); + + /* Load up the proper lux table. */ + if (chip->pdata && chip->pdata->platform_lux_table[0].ratio != 0) + memcpy(chip->tsl2x7x_device_lux, + chip->pdata->platform_lux_table, + sizeof(chip->pdata->platform_lux_table)); + else + memcpy(chip->tsl2x7x_device_lux, + (struct tsl2x7x_lux *)tsl2x7x_default_lux_table_group[chip->id], + MAX_DEFAULT_TABLE_BYTES); +} + +/** + * tsl2x7x_als_calibrate() - Obtain single reading and calculate + * the als_gain_trim. + * + * @indio_dev: pointer to IIO device + */ +static int tsl2x7x_als_calibrate(struct iio_dev *indio_dev) +{ + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + u8 reg_val; + int gain_trim_val; + int ret; + int lux_val; + + ret = i2c_smbus_write_byte(chip->client, + (TSL2X7X_CMD_REG | TSL2X7X_CNTRL)); + if (ret < 0) { + dev_err(&chip->client->dev, + "%s: failed to write CNTRL register, ret=%d\n", + __func__, ret); + return ret; + } + + reg_val = i2c_smbus_read_byte(chip->client); + if ((reg_val & (TSL2X7X_CNTL_ADC_ENBL | TSL2X7X_CNTL_PWR_ON)) + != (TSL2X7X_CNTL_ADC_ENBL | TSL2X7X_CNTL_PWR_ON)) { + dev_err(&chip->client->dev, + "%s: failed: ADC not enabled\n", __func__); + return -1; + } + + ret = i2c_smbus_write_byte(chip->client, + (TSL2X7X_CMD_REG | TSL2X7X_CNTRL)); + if (ret < 0) { + dev_err(&chip->client->dev, + "%s: failed to write ctrl reg: ret=%d\n", + __func__, ret); + return ret; + } + + reg_val = i2c_smbus_read_byte(chip->client); + if ((reg_val & TSL2X7X_STA_ADC_VALID) != TSL2X7X_STA_ADC_VALID) { + dev_err(&chip->client->dev, + "%s: failed: STATUS - ADC not valid.\n", __func__); + return -ENODATA; + } + + lux_val = tsl2x7x_get_lux(indio_dev); + if (lux_val < 0) { + dev_err(&chip->client->dev, + "%s: failed to get lux\n", __func__); + return lux_val; + } + + gain_trim_val = (((chip->tsl2x7x_settings.als_cal_target) + * chip->tsl2x7x_settings.als_gain_trim) / lux_val); + if ((gain_trim_val < 250) || (gain_trim_val > 4000)) + return -ERANGE; + + chip->tsl2x7x_settings.als_gain_trim = gain_trim_val; + dev_info(&chip->client->dev, + "%s als_calibrate completed\n", chip->client->name); + + return (int) gain_trim_val; +} + +static int tsl2x7x_chip_on(struct iio_dev *indio_dev) +{ + int i; + int ret = 0; + u8 *dev_reg; + u8 utmp; + int als_count; + int als_time; + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + u8 reg_val = 0; + + if (chip->pdata && chip->pdata->power_on) + chip->pdata->power_on(indio_dev); + + /* Non calculated parameters */ + chip->tsl2x7x_config[TSL2X7X_PRX_TIME] = + chip->tsl2x7x_settings.prx_time; + chip->tsl2x7x_config[TSL2X7X_WAIT_TIME] = + chip->tsl2x7x_settings.wait_time; + chip->tsl2x7x_config[TSL2X7X_PRX_CONFIG] = + chip->tsl2x7x_settings.prox_config; + + chip->tsl2x7x_config[TSL2X7X_ALS_MINTHRESHLO] = + (chip->tsl2x7x_settings.als_thresh_low) & 0xFF; + chip->tsl2x7x_config[TSL2X7X_ALS_MINTHRESHHI] = + (chip->tsl2x7x_settings.als_thresh_low >> 8) & 0xFF; + chip->tsl2x7x_config[TSL2X7X_ALS_MAXTHRESHLO] = + (chip->tsl2x7x_settings.als_thresh_high) & 0xFF; + chip->tsl2x7x_config[TSL2X7X_ALS_MAXTHRESHHI] = + (chip->tsl2x7x_settings.als_thresh_high >> 8) & 0xFF; + chip->tsl2x7x_config[TSL2X7X_PERSISTENCE] = + chip->tsl2x7x_settings.persistence; + + chip->tsl2x7x_config[TSL2X7X_PRX_COUNT] = + chip->tsl2x7x_settings.prox_pulse_count; + chip->tsl2x7x_config[TSL2X7X_PRX_MINTHRESHLO] = + chip->tsl2x7x_settings.prox_thres_low; + chip->tsl2x7x_config[TSL2X7X_PRX_MAXTHRESHLO] = + chip->tsl2x7x_settings.prox_thres_high; + + /* and make sure we're not already on */ + if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) { + /* if forcing a register update - turn off, then on */ + dev_info(&chip->client->dev, "device is already enabled\n"); + return -EINVAL; + } + + /* determine als integration regster */ + als_count = (chip->tsl2x7x_settings.als_time * 100 + 135) / 270; + if (als_count == 0) + als_count = 1; /* ensure at least one cycle */ + + /* convert back to time (encompasses overrides) */ + als_time = (als_count * 27 + 5) / 10; + chip->tsl2x7x_config[TSL2X7X_ALS_TIME] = 256 - als_count; + + /* Set the gain based on tsl2x7x_settings struct */ + chip->tsl2x7x_config[TSL2X7X_GAIN] = + (chip->tsl2x7x_settings.als_gain | + (TSL2X7X_mA100 | TSL2X7X_DIODE1) + | ((chip->tsl2x7x_settings.prox_gain) << 2)); + + /* set chip struct re scaling and saturation */ + chip->als_saturation = als_count * 922; /* 90% of full scale */ + chip->als_time_scale = (als_time + 25) / 50; + + /* TSL2X7X Specific power-on / adc enable sequence + * Power on the device 1st. */ + utmp = TSL2X7X_CNTL_PWR_ON; + ret = i2c_smbus_write_byte_data(chip->client, + TSL2X7X_CMD_REG | TSL2X7X_CNTRL, utmp); + if (ret < 0) { + dev_err(&chip->client->dev, + "%s: failed on CNTRL reg.\n", __func__); + return ret; + } + + /* Use the following shadow copy for our delay before enabling ADC. + * Write all the registers. */ + for (i = 0, dev_reg = chip->tsl2x7x_config; + i < TSL2X7X_MAX_CONFIG_REG; i++) { + ret = i2c_smbus_write_byte_data(chip->client, + TSL2X7X_CMD_REG + i, *dev_reg++); + if (ret < 0) { + dev_err(&chip->client->dev, + "%s: failed on write to reg %d.\n", __func__, i); + return ret; + } + } + + udelay(3000); /* Power-on settling time */ + + /* NOW enable the ADC + * initialize the desired mode of operation */ + utmp = TSL2X7X_CNTL_PWR_ON | + TSL2X7X_CNTL_ADC_ENBL | + TSL2X7X_CNTL_PROX_DET_ENBL; + ret = i2c_smbus_write_byte_data(chip->client, + TSL2X7X_CMD_REG | TSL2X7X_CNTRL, utmp); + if (ret < 0) { + dev_err(&chip->client->dev, + "%s: failed on 2nd CTRL reg.\n", __func__); + return ret; + } + + chip->tsl2x7x_chip_status = TSL2X7X_CHIP_WORKING; + + if (chip->tsl2x7x_settings.interrupts_en != 0) { + dev_info(&chip->client->dev, "Setting Up Interrupt(s)\n"); + + reg_val = TSL2X7X_CNTL_PWR_ON | TSL2X7X_CNTL_ADC_ENBL; + if ((chip->tsl2x7x_settings.interrupts_en == 0x20) || + (chip->tsl2x7x_settings.interrupts_en == 0x30)) + reg_val |= TSL2X7X_CNTL_PROX_DET_ENBL; + + reg_val |= chip->tsl2x7x_settings.interrupts_en; + ret = i2c_smbus_write_byte_data(chip->client, + (TSL2X7X_CMD_REG | TSL2X7X_CNTRL), reg_val); + if (ret < 0) + dev_err(&chip->client->dev, + "%s: failed in tsl2x7x_IOCTL_INT_SET.\n", + __func__); + + /* Clear out any initial interrupts */ + ret = i2c_smbus_write_byte(chip->client, + TSL2X7X_CMD_REG | TSL2X7X_CMD_SPL_FN | + TSL2X7X_CMD_PROXALS_INT_CLR); + if (ret < 0) { + dev_err(&chip->client->dev, + "%s: Failed to clear Int status\n", + __func__); + return ret; + } + } + + return ret; +} + +static int tsl2x7x_chip_off(struct iio_dev *indio_dev) +{ + int ret; + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + + /* turn device off */ + chip->tsl2x7x_chip_status = TSL2X7X_CHIP_SUSPENDED; + + ret = i2c_smbus_write_byte_data(chip->client, + TSL2X7X_CMD_REG | TSL2X7X_CNTRL, 0x00); + + if (chip->pdata && chip->pdata->power_off) + chip->pdata->power_off(chip->client); + + return ret; +} + +/** + * tsl2x7x_invoke_change + * @indio_dev: pointer to IIO device + * + * Obtain and lock both ALS and PROX resources, + * determine and save device state (On/Off), + * cycle device to implement updated parameter, + * put device back into proper state, and unlock + * resource. + */ +int tsl2x7x_invoke_change(struct iio_dev *indio_dev) +{ + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + int device_status = chip->tsl2x7x_chip_status; + + mutex_lock(&chip->als_mutex); + mutex_lock(&chip->prox_mutex); + + if (device_status == TSL2X7X_CHIP_WORKING) + tsl2x7x_chip_off(indio_dev); + + tsl2x7x_chip_on(indio_dev); + + if (device_status != TSL2X7X_CHIP_WORKING) + tsl2x7x_chip_off(indio_dev); + + mutex_unlock(&chip->prox_mutex); + mutex_unlock(&chip->als_mutex); + + return 0; +} + +static +void tsl2x7x_prox_calculate(int *data, int length, + struct tsl2x7x_prox_stat *statP) +{ + int i; + int sample_sum; + int tmp; + + if (length == 0) + length = 1; + + sample_sum = 0; + statP->min = INT_MAX; + statP->max = INT_MIN; + for (i = 0; i < length; i++) { + sample_sum += data[i]; + statP->min = min(statP->min, data[i]); + statP->max = max(statP->max, data[i]); + } + + statP->mean = sample_sum / length; + sample_sum = 0; + for (i = 0; i < length; i++) { + tmp = data[i] - statP->mean; + sample_sum += tmp * tmp; + } + statP->stddev = int_sqrt((long)sample_sum)/length; +} + +/** + * tsl2x7x_prox_cal() - Calculates std. and sets thresholds. + * @indio_dev: pointer to IIO device + * + * Calculates a standard deviation based on the samples, + * and sets the threshold accordingly. + */ +static void tsl2x7x_prox_cal(struct iio_dev *indio_dev) +{ + int prox_history[MAX_SAMPLES_CAL + 1]; + int i; + struct tsl2x7x_prox_stat prox_stat_data[2]; + struct tsl2x7x_prox_stat *calP; + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + u8 tmp_irq_settings; + u8 current_state = chip->tsl2x7x_chip_status; + + if (chip->tsl2x7x_settings.prox_max_samples_cal > MAX_SAMPLES_CAL) { + dev_err(&chip->client->dev, + "%s: max prox samples cal is too big: %d\n", + __func__, chip->tsl2x7x_settings.prox_max_samples_cal); + chip->tsl2x7x_settings.prox_max_samples_cal = MAX_SAMPLES_CAL; + } + + /* have to stop to change settings */ + tsl2x7x_chip_off(indio_dev); + + /* Enable proximity detection save just in case prox not wanted yet*/ + tmp_irq_settings = chip->tsl2x7x_settings.interrupts_en; + chip->tsl2x7x_settings.interrupts_en |= TSL2X7X_CNTL_PROX_INT_ENBL; + + /*turn on device if not already on*/ + tsl2x7x_chip_on(indio_dev); + + /*gather the samples*/ + for (i = 0; i < chip->tsl2x7x_settings.prox_max_samples_cal; i++) { + mdelay(15); + tsl2x7x_get_prox(indio_dev); + prox_history[i] = chip->prox_data; + dev_info(&chip->client->dev, "2 i=%d prox data= %d\n", + i, chip->prox_data); + } + + tsl2x7x_chip_off(indio_dev); + calP = &prox_stat_data[PROX_STAT_CAL]; + tsl2x7x_prox_calculate(prox_history, + chip->tsl2x7x_settings.prox_max_samples_cal, calP); + chip->tsl2x7x_settings.prox_thres_high = (calP->max << 1) - calP->mean; + + dev_info(&chip->client->dev, " cal min=%d mean=%d max=%d\n", + calP->min, calP->mean, calP->max); + dev_info(&chip->client->dev, + "%s proximity threshold set to %d\n", + chip->client->name, chip->tsl2x7x_settings.prox_thres_high); + + /* back to the way they were */ + chip->tsl2x7x_settings.interrupts_en = tmp_irq_settings; + if (current_state == TSL2X7X_CHIP_WORKING) + tsl2x7x_chip_on(indio_dev); +} + +static ssize_t tsl2x7x_power_state_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tsl2X7X_chip *chip = iio_priv(dev_get_drvdata(dev)); + + return snprintf(buf, PAGE_SIZE, "%d\n", chip->tsl2x7x_chip_status); +} + +static ssize_t tsl2x7x_power_state_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + bool value; + + if (strtobool(buf, &value)) + return -EINVAL; + + if (value) + tsl2x7x_chip_on(indio_dev); + else + tsl2x7x_chip_off(indio_dev); + + return len; +} + +static ssize_t tsl2x7x_gain_available_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tsl2X7X_chip *chip = iio_priv(dev_get_drvdata(dev)); + + switch (chip->id) { + case tsl2571: + case tsl2671: + case tmd2671: + case tsl2771: + case tmd2771: + return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 128"); + break; + } + + return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 120"); +} + +static ssize_t tsl2x7x_prox_gain_available_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", "1 2 4 8"); +} + +static ssize_t tsl2x7x_als_time_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tsl2X7X_chip *chip = iio_priv(dev_get_drvdata(dev)); + int y, z; + + y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1; + z = y * 2.72; + y /= 1000; + z %= 1000; + + return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z); +} + +static ssize_t tsl2x7x_als_time_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct tsl2X7X_chip *chip = iio_priv(dev_get_drvdata(dev)); + struct tsl2x7x_parse_result result; + + result.integer = 0; + result.fract = 0; + + tsl2x7x_parse_buffer(buf, &result); + + result.fract /= 1000; + result.fract /= 3; + chip->tsl2x7x_settings.als_time = + (TSL2X7X_MAX_TIMER_CNT - (u8)result.fract); + + dev_info(&chip->client->dev, "%s: als time = %d", + __func__, chip->tsl2x7x_settings.als_time); + + tsl2x7x_invoke_change(indio_dev); + + return IIO_VAL_INT_PLUS_MICRO; +} + +static IIO_CONST_ATTR(in_illuminance0_integration_time_available, + ".00272 - .696"); + +static ssize_t tsl2x7x_als_cal_target_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tsl2X7X_chip *chip = iio_priv(dev_get_drvdata(dev)); + + return snprintf(buf, PAGE_SIZE, "%d\n", + chip->tsl2x7x_settings.als_cal_target); +} + +static ssize_t tsl2x7x_als_cal_target_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct tsl2X7X_chip *chip = iio_priv(dev_get_drvdata(dev)); + unsigned long value; + + if (kstrtoul(buf, 0, &value)) + return -EINVAL; + + if (value) + chip->tsl2x7x_settings.als_cal_target = value; + + tsl2x7x_invoke_change(indio_dev); + + return len; +} + +/* persistence settings */ +static ssize_t tsl2x7x_als_persistence_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tsl2X7X_chip *chip = iio_priv(dev_get_drvdata(dev)); + int y, z, filter_delay; + + /* Determine integration time */ + y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1; + z = y * 2.72; + filter_delay = z * (chip->tsl2x7x_settings.persistence & 0x0F); + y = (filter_delay / 1000); + z = (filter_delay % 1000); + + return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z); +} + +static ssize_t tsl2x7x_als_persistence_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct tsl2X7X_chip *chip = iio_priv(dev_get_drvdata(dev)); + struct tsl2x7x_parse_result result; + int y, z, filter_delay; + + result.integer = 0; + result.fract = 0; + tsl2x7x_parse_buffer(buf, &result); + + result.fract /= 1000; + y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1; + z = y * 2.72; + + filter_delay = + DIV_ROUND_UP(((result.integer * 1000) + result.fract), z); + + chip->tsl2x7x_settings.persistence &= 0xF0; + chip->tsl2x7x_settings.persistence |= (filter_delay & 0x0F); + + dev_info(&chip->client->dev, "%s: als persistence = %d", + __func__, filter_delay); + + tsl2x7x_invoke_change(indio_dev); + + return IIO_VAL_INT_PLUS_MICRO; +} + +static ssize_t tsl2x7x_prox_persistence_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tsl2X7X_chip *chip = iio_priv(dev_get_drvdata(dev)); + int y, z, filter_delay; + + /* Determine integration time */ + y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.prx_time) + 1; + z = y * 2.72; + filter_delay = z * ((chip->tsl2x7x_settings.persistence & 0xF0) >> 4); + y = (filter_delay / 1000); + z = (filter_delay % 1000); + + return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z); +} + +static ssize_t tsl2x7x_prox_persistence_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct tsl2X7X_chip *chip = iio_priv(dev_get_drvdata(dev)); + struct tsl2x7x_parse_result result; + int y, z, filter_delay; + + result.integer = 0; + result.fract = 0; + tsl2x7x_parse_buffer(buf, &result); + + result.fract /= 1000; + y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.prx_time) + 1; + z = y * 2.72; + + filter_delay = + DIV_ROUND_UP(((result.integer * 1000) + result.fract), z); + + chip->tsl2x7x_settings.persistence &= 0x0F; + chip->tsl2x7x_settings.persistence |= ((filter_delay << 4) & 0xF0); + + dev_info(&chip->client->dev, "%s: prox persistence = %d", + __func__, filter_delay); + + tsl2x7x_invoke_change(indio_dev); + + return IIO_VAL_INT_PLUS_MICRO; +} + +static ssize_t tsl2x7x_do_calibrate(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + bool value; + + if (strtobool(buf, &value)) + return -EINVAL; + + if (value) + tsl2x7x_als_calibrate(indio_dev); + + tsl2x7x_invoke_change(indio_dev); + + return len; +} + +static ssize_t tsl2x7x_luxtable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tsl2X7X_chip *chip = iio_priv(dev_get_drvdata(dev)); + int i = 0; + int offset = 0; + + while (i < (TSL2X7X_MAX_LUX_TABLE_SIZE * 3)) { + offset += snprintf(buf + offset, PAGE_SIZE, "%d,%d,%d,", + chip->tsl2x7x_device_lux[i].ratio, + chip->tsl2x7x_device_lux[i].ch0, + chip->tsl2x7x_device_lux[i].ch1); + if (chip->tsl2x7x_device_lux[i].ratio == 0) { + /* We just printed the first "0" entry. + * Now get rid of the extra "," and break. */ + offset--; + break; + } + i++; + } + + offset += snprintf(buf + offset, PAGE_SIZE, "\n"); + return offset; +} + +static ssize_t tsl2x7x_luxtable_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct tsl2X7X_chip *chip = iio_priv(dev_get_drvdata(dev)); + int value[ARRAY_SIZE(chip->tsl2x7x_device_lux)*3 + 1]; + int n; + + get_options(buf, ARRAY_SIZE(value), value); + + /* We now have an array of ints starting at value[1], and + * enumerated by value[0]. + * We expect each group of three ints is one table entry, + * and the last table entry is all 0. + */ + n = value[0]; + if ((n % 3) || n < 6 || + n > ((ARRAY_SIZE(chip->tsl2x7x_device_lux) - 1) * 3)) { + dev_info(dev, "LUX TABLE INPUT ERROR 1 Value[0]=%d\n", n); + return -EINVAL; + } + + if ((value[(n - 2)] | value[(n - 1)] | value[n]) != 0) { + dev_info(dev, "LUX TABLE INPUT ERROR 2 Value[0]=%d\n", n); + return -EINVAL; + } + + if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) + tsl2x7x_chip_off(indio_dev); + + /* Zero out the table */ + memset(chip->tsl2x7x_device_lux, 0, sizeof(chip->tsl2x7x_device_lux)); + memcpy(chip->tsl2x7x_device_lux, &value[1], (value[0] * 4)); + + tsl2x7x_invoke_change(indio_dev); + + return len; +} + +static ssize_t tsl2x7x_do_prox_calibrate(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + bool value; + + if (strtobool(buf, &value)) + return -EINVAL; + + if (value) + tsl2x7x_prox_cal(indio_dev); + + tsl2x7x_invoke_change(indio_dev); + + return len; +} + +static int tsl2x7x_read_interrupt_config(struct iio_dev *indio_dev, + u64 event_code) +{ + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + int ret; + + if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) + ret = !!(chip->tsl2x7x_settings.interrupts_en & 0x10); + else + ret = !!(chip->tsl2x7x_settings.interrupts_en & 0x20); + + return ret; +} + +static int tsl2x7x_write_interrupt_config(struct iio_dev *indio_dev, + u64 event_code, + int val) +{ + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + + if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) { + if (val) + chip->tsl2x7x_settings.interrupts_en |= 0x10; + else + chip->tsl2x7x_settings.interrupts_en &= 0x20; + } else { + if (val) + chip->tsl2x7x_settings.interrupts_en |= 0x20; + else + chip->tsl2x7x_settings.interrupts_en &= 0x10; + } + + tsl2x7x_invoke_change(indio_dev); + + return 0; +} + +static int tsl2x7x_write_thresh(struct iio_dev *indio_dev, + u64 event_code, + int val) +{ + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + + if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) { + switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) { + case IIO_EV_DIR_RISING: + chip->tsl2x7x_settings.als_thresh_high = val; + break; + case IIO_EV_DIR_FALLING: + chip->tsl2x7x_settings.als_thresh_low = val; + break; + default: + return -EINVAL; + } + } else { + switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) { + case IIO_EV_DIR_RISING: + chip->tsl2x7x_settings.prox_thres_high = val; + break; + case IIO_EV_DIR_FALLING: + chip->tsl2x7x_settings.prox_thres_low = val; + break; + default: + return -EINVAL; + } + } + + tsl2x7x_invoke_change(indio_dev); + + return 0; +} + +static int tsl2x7x_read_thresh(struct iio_dev *indio_dev, + u64 event_code, + int *val) +{ + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + + if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) { + switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) { + case IIO_EV_DIR_RISING: + *val = chip->tsl2x7x_settings.als_thresh_high; + break; + case IIO_EV_DIR_FALLING: + *val = chip->tsl2x7x_settings.als_thresh_low; + break; + default: + return -EINVAL; + } + } else { + switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) { + case IIO_EV_DIR_RISING: + *val = chip->tsl2x7x_settings.prox_thres_high; + break; + case IIO_EV_DIR_FALLING: + *val = chip->tsl2x7x_settings.prox_thres_low; + break; + default: + return -EINVAL; + } + } + + return 0; +} + +static int tsl2x7x_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long mask) +{ + int ret = -EINVAL; + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + switch (chan->type) { + case IIO_LIGHT: + tsl2x7x_get_lux(indio_dev); + *val = chip->als_cur_info.lux; + ret = IIO_VAL_INT; + break; + case IIO_INTENSITY: + tsl2x7x_get_lux(indio_dev); + if (chan->channel == 0) + *val = chip->als_cur_info.als_ch0; + else + *val = chip->als_cur_info.als_ch1; + ret = IIO_VAL_INT; + break; + case IIO_PROXIMITY: + tsl2x7x_get_prox(indio_dev); + *val = chip->prox_data; + ret = IIO_VAL_INT; + break; + default: + return -EINVAL; + break; + } + break; + case IIO_CHAN_INFO_CALIBSCALE: + if (chan->type == IIO_LIGHT) + *val = + tsl2X7X_als_gainadj[chip->tsl2x7x_settings.als_gain]; + else + *val = + tsl2X7X_prx_gainadj[chip->tsl2x7x_settings.prox_gain]; + ret = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_CALIBBIAS: + *val = chip->tsl2x7x_settings.als_gain_trim; + ret = IIO_VAL_INT; + break; + + default: + ret = -EINVAL; + } + + return ret; +} + +static int tsl2x7x_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_CALIBSCALE: + if (chan->type == IIO_INTENSITY) { + switch (val) { + case 1: + chip->tsl2x7x_settings.als_gain = 0; + break; + case 8: + chip->tsl2x7x_settings.als_gain = 1; + break; + case 16: + chip->tsl2x7x_settings.als_gain = 2; + break; + case 120: + switch (chip->id) { + case tsl2572: + case tsl2672: + case tmd2672: + case tsl2772: + case tmd2772: + return -EINVAL; + break; + } + chip->tsl2x7x_settings.als_gain = 3; + break; + case 128: + switch (chip->id) { + case tsl2571: + case tsl2671: + case tmd2671: + case tsl2771: + case tmd2771: + return -EINVAL; + break; + } + chip->tsl2x7x_settings.als_gain = 3; + break; + default: + return -EINVAL; + } + } else { + switch (val) { + case 1: + chip->tsl2x7x_settings.prox_gain = 0; + break; + case 2: + chip->tsl2x7x_settings.prox_gain = 1; + break; + case 4: + chip->tsl2x7x_settings.prox_gain = 2; + break; + case 8: + chip->tsl2x7x_settings.prox_gain = 3; + break; + default: + return -EINVAL; + } + } + break; + case IIO_CHAN_INFO_CALIBBIAS: + chip->tsl2x7x_settings.als_gain_trim = val; + break; + + default: + return -EINVAL; + } + + tsl2x7x_invoke_change(indio_dev); + + return 0; +} + +static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR, + tsl2x7x_power_state_show, tsl2x7x_power_state_store); + +static DEVICE_ATTR(in_proximity0_calibscale_available, S_IRUGO, + tsl2x7x_prox_gain_available_show, NULL); + +static DEVICE_ATTR(in_illuminance0_calibscale_available, S_IRUGO, + tsl2x7x_gain_available_show, NULL); + +static DEVICE_ATTR(in_illuminance0_integration_time, S_IRUGO | S_IWUSR, + tsl2x7x_als_time_show, tsl2x7x_als_time_store); + +static DEVICE_ATTR(in_illuminance0_target_input, S_IRUGO | S_IWUSR, + tsl2x7x_als_cal_target_show, tsl2x7x_als_cal_target_store); + +static DEVICE_ATTR(in_illuminance0_calibrate, S_IWUSR, NULL, + tsl2x7x_do_calibrate); + +static DEVICE_ATTR(in_proximity0_calibrate, S_IWUSR, NULL, + tsl2x7x_do_prox_calibrate); + +static DEVICE_ATTR(in_illuminance0_lux_table, S_IRUGO | S_IWUSR, + tsl2x7x_luxtable_show, tsl2x7x_luxtable_store); + +static DEVICE_ATTR(in_intensity0_thresh_period, S_IRUGO | S_IWUSR, + tsl2x7x_als_persistence_show, tsl2x7x_als_persistence_store); + +static DEVICE_ATTR(in_proximity0_thresh_period, S_IRUGO | S_IWUSR, + tsl2x7x_prox_persistence_show, tsl2x7x_prox_persistence_store); + +/* Use the default register values to identify the Taos device */ +static int tsl2x7x_device_id(unsigned char *id, int target) +{ + switch (target) { + case tsl2571: + case tsl2671: + case tsl2771: + return ((*id & 0xf0) == TRITON_ID); + break; + case tmd2671: + case tmd2771: + return ((*id & 0xf0) == HALIBUT_ID); + break; + case tsl2572: + case tsl2672: + case tmd2672: + case tsl2772: + case tmd2772: + return ((*id & 0xf0) == SWORDFISH_ID); + break; + } + + return -EINVAL; +} + +static irqreturn_t tsl2x7x_event_handler(int irq, void *private) +{ + struct iio_dev *indio_dev = private; + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + s64 timestamp = iio_get_time_ns(); + int ret; + u8 value; + + value = i2c_smbus_read_byte_data(chip->client, + TSL2X7X_CMD_REG | TSL2X7X_STATUS); + + /* What type of interrupt do we need to process */ + if (value & TSL2X7X_STA_PRX_INTR) { + tsl2x7x_get_prox(indio_dev); /* freshen data for ABI */ + iio_push_event(indio_dev, + IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, + 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_EITHER), + timestamp); + } + + if (value & TSL2X7X_STA_ALS_INTR) { + tsl2x7x_get_lux(indio_dev); /* freshen data for ABI */ + iio_push_event(indio_dev, + IIO_UNMOD_EVENT_CODE(IIO_LIGHT, + 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_EITHER), + timestamp); + } + /* Clear interrupt now that we have handled it. */ + ret = i2c_smbus_write_byte(chip->client, + TSL2X7X_CMD_REG | TSL2X7X_CMD_SPL_FN | + TSL2X7X_CMD_PROXALS_INT_CLR); + if (ret < 0) + dev_err(&chip->client->dev, + "%s: Failed to clear irq from event handler. err = %d\n", + __func__, ret); + + return IRQ_HANDLED; +} + +static struct attribute *tsl2x7x_ALS_device_attrs[] = { + &dev_attr_power_state.attr, + &dev_attr_in_illuminance0_calibscale_available.attr, + &dev_attr_in_illuminance0_integration_time.attr, + &iio_const_attr_in_illuminance0_integration_time_available\ + .dev_attr.attr, + &dev_attr_in_illuminance0_target_input.attr, + &dev_attr_in_illuminance0_calibrate.attr, + &dev_attr_in_illuminance0_lux_table.attr, + NULL +}; + +static struct attribute *tsl2x7x_PRX_device_attrs[] = { + &dev_attr_power_state.attr, + &dev_attr_in_proximity0_calibrate.attr, + NULL +}; + +static struct attribute *tsl2x7x_ALSPRX_device_attrs[] = { + &dev_attr_power_state.attr, + &dev_attr_in_illuminance0_calibscale_available.attr, + &dev_attr_in_illuminance0_integration_time.attr, + &iio_const_attr_in_illuminance0_integration_time_available\ + .dev_attr.attr, + &dev_attr_in_illuminance0_target_input.attr, + &dev_attr_in_illuminance0_calibrate.attr, + &dev_attr_in_illuminance0_lux_table.attr, + &dev_attr_in_proximity0_calibrate.attr, + NULL +}; + +static struct attribute *tsl2x7x_PRX2_device_attrs[] = { + &dev_attr_power_state.attr, + &dev_attr_in_proximity0_calibrate.attr, + &dev_attr_in_proximity0_calibscale_available.attr, + NULL +}; + +static struct attribute *tsl2x7x_ALSPRX2_device_attrs[] = { + &dev_attr_power_state.attr, + &dev_attr_in_illuminance0_calibscale_available.attr, + &dev_attr_in_illuminance0_integration_time.attr, + &iio_const_attr_in_illuminance0_integration_time_available\ + .dev_attr.attr, + &dev_attr_in_illuminance0_target_input.attr, + &dev_attr_in_illuminance0_calibrate.attr, + &dev_attr_in_illuminance0_lux_table.attr, + &dev_attr_in_proximity0_calibrate.attr, + &dev_attr_in_proximity0_calibscale_available.attr, + NULL +}; + +static struct attribute *tsl2X7X_ALS_event_attrs[] = { + &dev_attr_in_intensity0_thresh_period.attr, + NULL, +}; +static struct attribute *tsl2X7X_PRX_event_attrs[] = { + &dev_attr_in_proximity0_thresh_period.attr, + NULL, +}; + +static struct attribute *tsl2X7X_ALSPRX_event_attrs[] = { + &dev_attr_in_intensity0_thresh_period.attr, + &dev_attr_in_proximity0_thresh_period.attr, + NULL, +}; + +static const struct attribute_group tsl2X7X_device_attr_group_tbl[] = { + [ALS] = { + .attrs = tsl2x7x_ALS_device_attrs, + }, + [PRX] = { + .attrs = tsl2x7x_PRX_device_attrs, + }, + [ALSPRX] = { + .attrs = tsl2x7x_ALSPRX_device_attrs, + }, + [PRX2] = { + .attrs = tsl2x7x_PRX2_device_attrs, + }, + [ALSPRX2] = { + .attrs = tsl2x7x_ALSPRX2_device_attrs, + }, +}; + +static struct attribute_group tsl2X7X_event_attr_group_tbl[] = { + [ALS] = { + .attrs = tsl2X7X_ALS_event_attrs, + .name = "events", + }, + [PRX] = { + .attrs = tsl2X7X_PRX_event_attrs, + .name = "events", + }, + [ALSPRX] = { + .attrs = tsl2X7X_ALSPRX_event_attrs, + .name = "events", + }, +}; + +static const struct iio_info tsl2X7X_device_info[] = { + [ALS] = { + .attrs = &tsl2X7X_device_attr_group_tbl[ALS], + .event_attrs = &tsl2X7X_event_attr_group_tbl[ALS], + .driver_module = THIS_MODULE, + .read_raw = &tsl2x7x_read_raw, + .write_raw = &tsl2x7x_write_raw, + .read_event_value = &tsl2x7x_read_thresh, + .write_event_value = &tsl2x7x_write_thresh, + .read_event_config = &tsl2x7x_read_interrupt_config, + .write_event_config = &tsl2x7x_write_interrupt_config, + }, + [PRX] = { + .attrs = &tsl2X7X_device_attr_group_tbl[PRX], + .event_attrs = &tsl2X7X_event_attr_group_tbl[PRX], + .driver_module = THIS_MODULE, + .read_raw = &tsl2x7x_read_raw, + .write_raw = &tsl2x7x_write_raw, + .read_event_value = &tsl2x7x_read_thresh, + .write_event_value = &tsl2x7x_write_thresh, + .read_event_config = &tsl2x7x_read_interrupt_config, + .write_event_config = &tsl2x7x_write_interrupt_config, + }, + [ALSPRX] = { + .attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX], + .event_attrs = &tsl2X7X_event_attr_group_tbl[ALSPRX], + .driver_module = THIS_MODULE, + .read_raw = &tsl2x7x_read_raw, + .write_raw = &tsl2x7x_write_raw, + .read_event_value = &tsl2x7x_read_thresh, + .write_event_value = &tsl2x7x_write_thresh, + .read_event_config = &tsl2x7x_read_interrupt_config, + .write_event_config = &tsl2x7x_write_interrupt_config, + }, + [PRX2] = { + .attrs = &tsl2X7X_device_attr_group_tbl[PRX2], + .event_attrs = &tsl2X7X_event_attr_group_tbl[PRX], + .driver_module = THIS_MODULE, + .read_raw = &tsl2x7x_read_raw, + .write_raw = &tsl2x7x_write_raw, + .read_event_value = &tsl2x7x_read_thresh, + .write_event_value = &tsl2x7x_write_thresh, + .read_event_config = &tsl2x7x_read_interrupt_config, + .write_event_config = &tsl2x7x_write_interrupt_config, + }, + [ALSPRX2] = { + .attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX2], + .event_attrs = &tsl2X7X_event_attr_group_tbl[ALSPRX], + .driver_module = THIS_MODULE, + .read_raw = &tsl2x7x_read_raw, + .write_raw = &tsl2x7x_write_raw, + .read_event_value = &tsl2x7x_read_thresh, + .write_event_value = &tsl2x7x_write_thresh, + .read_event_config = &tsl2x7x_read_interrupt_config, + .write_event_config = &tsl2x7x_write_interrupt_config, + }, +}; + +static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { + [ALS] = { + .channel = { + { + .type = IIO_LIGHT, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, + }, { + .type = IIO_INTENSITY, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .event_mask = TSL2X7X_EVENT_MASK + }, { + .type = IIO_INTENSITY, + .indexed = 1, + .channel = 1, + }, + }, + .chan_table_elements = 3, + .info = &tsl2X7X_device_info[ALS], + }, + [PRX] = { + .channel = { + { + .type = IIO_PROXIMITY, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .event_mask = TSL2X7X_EVENT_MASK + }, + }, + .chan_table_elements = 1, + .info = &tsl2X7X_device_info[PRX], + }, + [ALSPRX] = { + .channel = { + { + .type = IIO_LIGHT, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT + }, { + .type = IIO_INTENSITY, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .event_mask = TSL2X7X_EVENT_MASK + }, { + .type = IIO_INTENSITY, + .indexed = 1, + .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + }, { + .type = IIO_PROXIMITY, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .event_mask = TSL2X7X_EVENT_MASK + }, + }, + .chan_table_elements = 4, + .info = &tsl2X7X_device_info[ALSPRX], + }, + [PRX2] = { + .channel = { + { + .type = IIO_PROXIMITY, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, + .event_mask = TSL2X7X_EVENT_MASK + }, + }, + .chan_table_elements = 1, + .info = &tsl2X7X_device_info[PRX2], + }, + [ALSPRX2] = { + .channel = { + { + .type = IIO_LIGHT, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, + }, { + .type = IIO_INTENSITY, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .event_mask = TSL2X7X_EVENT_MASK + }, { + .type = IIO_INTENSITY, + .indexed = 1, + .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + }, { + .type = IIO_PROXIMITY, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, + .event_mask = TSL2X7X_EVENT_MASK + }, + }, + .chan_table_elements = 4, + .info = &tsl2X7X_device_info[ALSPRX2], + }, +}; + +static int __devinit tsl2x7x_probe(struct i2c_client *clientp, + const struct i2c_device_id *id) +{ + int ret; + unsigned char device_id; + struct iio_dev *indio_dev; + struct tsl2X7X_chip *chip; + + indio_dev = iio_allocate_device(sizeof(*chip)); + if (!indio_dev) + return -ENOMEM; + + chip = iio_priv(indio_dev); + chip->client = clientp; + i2c_set_clientdata(clientp, indio_dev); + + ret = tsl2x7x_i2c_read(chip->client, + TSL2X7X_CHIPID, &device_id); + if (ret < 0) + goto fail1; + + if ((!tsl2x7x_device_id(&device_id, id->driver_data)) || + (tsl2x7x_device_id(&device_id, id->driver_data) == -EINVAL)) { + dev_info(&chip->client->dev, + "%s: i2c device found does not match expected id\n", + __func__); + goto fail1; + } + + ret = i2c_smbus_write_byte(clientp, (TSL2X7X_CMD_REG | TSL2X7X_CNTRL)); + if (ret < 0) { + dev_err(&clientp->dev, "%s: write to cmd reg failed. err = %d\n", + __func__, ret); + goto fail1; + } + + /* ALS and PROX functions can be invoked via user space poll + * or H/W interrupt. If busy return last sample. */ + mutex_init(&chip->als_mutex); + mutex_init(&chip->prox_mutex); + + chip->tsl2x7x_chip_status = TSL2X7X_CHIP_UNKNOWN; + chip->pdata = clientp->dev.platform_data; + chip->id = id->driver_data; + chip->chip_info = + &tsl2x7x_chip_info_tbl[device_channel_config[id->driver_data]]; + + indio_dev->info = chip->chip_info->info; + indio_dev->dev.parent = &clientp->dev; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->name = chip->client->name; + indio_dev->channels = chip->chip_info->channel; + indio_dev->num_channels = chip->chip_info->chan_table_elements; + + if (clientp->irq) { + ret = request_threaded_irq(clientp->irq, + NULL, + &tsl2x7x_event_handler, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "TSL2X7X_event", + indio_dev); + if (ret) { + dev_err(&clientp->dev, + "%s: irq request failed", __func__); + goto fail2; + } + } + + /* Load up the defaults */ + tsl2x7x_defaults(chip); + /* Make sure the chip is on */ + tsl2x7x_chip_on(indio_dev); + + ret = iio_device_register(indio_dev); + if (ret) { + dev_err(&clientp->dev, + "%s: iio registration failed\n", __func__); + goto fail1; + } + + dev_info(&clientp->dev, "%s Light sensor found.\n", id->name); + + return 0; + +fail1: + if (clientp->irq) + free_irq(clientp->irq, indio_dev); +fail2: + iio_free_device(indio_dev); + + return ret; +} + +static int tsl2x7x_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + int ret = 0; + + if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) { + ret = tsl2x7x_chip_off(indio_dev); + chip->tsl2x7x_chip_status = TSL2X7X_CHIP_SUSPENDED; + } + + if (chip->pdata && chip->pdata->platform_power) { + pm_message_t pmm = {PM_EVENT_SUSPEND}; + chip->pdata->platform_power(dev, pmm); + } + + return ret; +} + +static int tsl2x7x_resume(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + int ret = 0; + + if (chip->pdata && chip->pdata->platform_power) { + pm_message_t pmm = {PM_EVENT_RESUME}; + chip->pdata->platform_power(dev, pmm); + } + + if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_SUSPENDED) + ret = tsl2x7x_chip_on(indio_dev); + + return ret; +} + +static int __devexit tsl2x7x_remove(struct i2c_client *client) +{ + struct tsl2X7X_chip *chip = i2c_get_clientdata(client); + struct iio_dev *indio_dev = iio_priv_to_dev(chip); + + tsl2x7x_chip_off(indio_dev); + + iio_device_unregister(indio_dev); + if (client->irq) + free_irq(client->irq, chip->client->name); + + iio_free_device(indio_dev); + + return 0; +} + +static struct i2c_device_id tsl2x7x_idtable[] = { + { "tsl2571", tsl2571 }, + { "tsl2671", tsl2671 }, + { "tmd2671", tmd2671 }, + { "tsl2771", tsl2771 }, + { "tmd2771", tmd2771 }, + { "tsl2572", tsl2572 }, + { "tsl2672", tsl2672 }, + { "tmd2672", tmd2672 }, + { "tsl2772", tsl2772 }, + { "tmd2772", tmd2772 }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, tsl2x7x_idtable); + +static const struct dev_pm_ops tsl2x7x_pm_ops = { + .suspend = tsl2x7x_suspend, + .resume = tsl2x7x_resume, +}; + +/* Driver definition */ +static struct i2c_driver tsl2x7x_driver = { + .driver = { + .name = "tsl2x7x", + .pm = &tsl2x7x_pm_ops, + }, + .id_table = tsl2x7x_idtable, + .probe = tsl2x7x_probe, + .remove = __devexit_p(tsl2x7x_remove), +}; + +module_i2c_driver(tsl2x7x_driver); + +MODULE_AUTHOR("J. August Brenner"); +MODULE_DESCRIPTION("TAOS tsl2x7x ambient and proximity light sensor driver"); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 0f3bcfe67f175d4edf0c6ab5487fbe23b6533d4a Mon Sep 17 00:00:00 2001 From: Jon Brenner Date: Tue, 24 Apr 2012 17:59:10 -0500 Subject: staging: iio: tsl2x7x: bugfixes TAOS (version 9a) tsl2x7x driver change / bug fix. Fixed - removed decimal multiplications. Added missing 'static' declarations Fixed _read_raw case logic to allow reading of _PROCESSED IIO_LIGHT Replaced udelay with mdelay to accomodate eabi. Signed-off-by: Jon Brenner Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c index ff44989..f3fc85a 100755 --- a/drivers/staging/iio/light/tsl2x7x_core.c +++ b/drivers/staging/iio/light/tsl2x7x_core.c @@ -130,6 +130,8 @@ (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \ IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)), +#define TSL2X7X_MIN_ITIME 3 + /* TAOS txx2x7x Device family members */ enum { tsl2571, @@ -277,7 +279,7 @@ enum { ALSPRX2, }; -const u8 device_channel_config[] = { +static const u8 device_channel_config[] = { ALS, PRX, PRX, @@ -778,7 +780,7 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev) } } - udelay(3000); /* Power-on settling time */ + mdelay(3); /* Power-on settling time */ /* NOW enable the ADC * initialize the desired mode of operation */ @@ -853,6 +855,7 @@ static int tsl2x7x_chip_off(struct iio_dev *indio_dev) * put device back into proper state, and unlock * resource. */ +static int tsl2x7x_invoke_change(struct iio_dev *indio_dev) { struct tsl2X7X_chip *chip = iio_priv(indio_dev); @@ -1021,7 +1024,7 @@ static ssize_t tsl2x7x_als_time_show(struct device *dev, int y, z; y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1; - z = y * 2.72; + z = y * TSL2X7X_MIN_ITIME; y /= 1000; z %= 1000; @@ -1092,7 +1095,7 @@ static ssize_t tsl2x7x_als_persistence_show(struct device *dev, /* Determine integration time */ y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1; - z = y * 2.72; + z = y * TSL2X7X_MIN_ITIME; filter_delay = z * (chip->tsl2x7x_settings.persistence & 0x0F); y = (filter_delay / 1000); z = (filter_delay % 1000); @@ -1114,7 +1117,7 @@ static ssize_t tsl2x7x_als_persistence_store(struct device *dev, result.fract /= 1000; y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1; - z = y * 2.72; + z = y * TSL2X7X_MIN_ITIME; filter_delay = DIV_ROUND_UP(((result.integer * 1000) + result.fract), z); @@ -1138,7 +1141,7 @@ static ssize_t tsl2x7x_prox_persistence_show(struct device *dev, /* Determine integration time */ y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.prx_time) + 1; - z = y * 2.72; + z = y * TSL2X7X_MIN_ITIME; filter_delay = z * ((chip->tsl2x7x_settings.persistence & 0xF0) >> 4); y = (filter_delay / 1000); z = (filter_delay % 1000); @@ -1160,7 +1163,7 @@ static ssize_t tsl2x7x_prox_persistence_store(struct device *dev, result.fract /= 1000; y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.prx_time) + 1; - z = y * 2.72; + z = y * TSL2X7X_MIN_ITIME; filter_delay = DIV_ROUND_UP(((result.integer * 1000) + result.fract), z); @@ -1389,13 +1392,20 @@ static int tsl2x7x_read_raw(struct iio_dev *indio_dev, struct tsl2X7X_chip *chip = iio_priv(indio_dev); switch (mask) { - case IIO_CHAN_INFO_RAW: + case IIO_CHAN_INFO_PROCESSED: switch (chan->type) { case IIO_LIGHT: tsl2x7x_get_lux(indio_dev); *val = chip->als_cur_info.lux; ret = IIO_VAL_INT; break; + default: + return -EINVAL; + break; + } + break; + case IIO_CHAN_INFO_RAW: + switch (chan->type) { case IIO_INTENSITY: tsl2x7x_get_lux(indio_dev); if (chan->channel == 0) -- cgit v0.10.2 From 07ffd0d071153aa45205891e0e577aaba1d74d0f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 25 Apr 2012 09:44:52 +0200 Subject: staging:iio:dac:ad5446: Do not exit powerdown when writing a sample Both the powerdown mode bits and the sample value are stored in the same register, so writing a sample while the device is powered down will clear the power down bits. To avoid this only update the cached value when the device is powered down. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron ---- v1 actually had a small bug in that it would still write to the device's register when the sample was updated while the device was powered down. This was not critical since it would send out the powerdown mode again. Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index ec6968b..de796c2 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -272,7 +272,7 @@ static int ad5446_write_raw(struct iio_dev *indio_dev, long mask) { struct ad5446_state *st = iio_priv(indio_dev); - int ret; + int ret = 0; switch (mask) { case IIO_CHAN_INFO_RAW: @@ -282,8 +282,10 @@ static int ad5446_write_raw(struct iio_dev *indio_dev, val <<= chan->scan_type.shift; mutex_lock(&indio_dev->mlock); st->cached_val = val; - st->chip_info->store_sample(st, val); - ret = spi_sync(st->spi, &st->msg); + if (!st->pwr_down) { + st->chip_info->store_sample(st, val); + ret = spi_sync(st->spi, &st->msg); + } mutex_unlock(&indio_dev->mlock); break; default: -- cgit v0.10.2 From 5ff6a99d7c6c804c3b58608e8a476f4d7fd2dfd8 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 25 Apr 2012 09:44:53 +0200 Subject: staging:iio:dac:ad5446: Remove duplicated write sample functions AD5620_LOAD and AD5446_LOAD are both 0, so all these three functions are identical and we can replace them with only one. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index de796c2..0da5c6c 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -26,19 +26,9 @@ static void ad5446_store_sample(struct ad5446_state *st, unsigned val) { - st->data.d16 = cpu_to_be16(AD5446_LOAD | val); -} - -static void ad5542_store_sample(struct ad5446_state *st, unsigned val) -{ st->data.d16 = cpu_to_be16(val); } -static void ad5620_store_sample(struct ad5446_state *st, unsigned val) -{ - st->data.d16 = cpu_to_be16(AD5620_LOAD | val); -} - static void ad5660_store_sample(struct ad5446_state *st, unsigned val) { val |= AD5660_LOAD; @@ -174,61 +164,61 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { }, [ID_AD5541A] = { .channel = AD5446_CHANNEL(16, 16, 0), - .store_sample = ad5542_store_sample, + .store_sample = ad5446_store_sample, }, [ID_AD5542A] = { .channel = AD5446_CHANNEL(16, 16, 0), - .store_sample = ad5542_store_sample, + .store_sample = ad5446_store_sample, }, [ID_AD5543] = { .channel = AD5446_CHANNEL(16, 16, 0), - .store_sample = ad5542_store_sample, + .store_sample = ad5446_store_sample, }, [ID_AD5512A] = { .channel = AD5446_CHANNEL(12, 16, 4), - .store_sample = ad5542_store_sample, + .store_sample = ad5446_store_sample, }, [ID_AD5553] = { .channel = AD5446_CHANNEL(14, 16, 0), - .store_sample = ad5542_store_sample, + .store_sample = ad5446_store_sample, }, [ID_AD5601] = { .channel = AD5446_CHANNEL(8, 16, 6), - .store_sample = ad5542_store_sample, + .store_sample = ad5446_store_sample, .store_pwr_down = ad5620_store_pwr_down, }, [ID_AD5611] = { .channel = AD5446_CHANNEL(10, 16, 4), - .store_sample = ad5542_store_sample, + .store_sample = ad5446_store_sample, .store_pwr_down = ad5620_store_pwr_down, }, [ID_AD5621] = { .channel = AD5446_CHANNEL(12, 16, 2), - .store_sample = ad5542_store_sample, + .store_sample = ad5446_store_sample, .store_pwr_down = ad5620_store_pwr_down, }, [ID_AD5620_2500] = { .channel = AD5446_CHANNEL(12, 16, 2), .int_vref_mv = 2500, - .store_sample = ad5620_store_sample, + .store_sample = ad5446_store_sample, .store_pwr_down = ad5620_store_pwr_down, }, [ID_AD5620_1250] = { .channel = AD5446_CHANNEL(12, 16, 2), .int_vref_mv = 1250, - .store_sample = ad5620_store_sample, + .store_sample = ad5446_store_sample, .store_pwr_down = ad5620_store_pwr_down, }, [ID_AD5640_2500] = { .channel = AD5446_CHANNEL(14, 16, 0), .int_vref_mv = 2500, - .store_sample = ad5620_store_sample, + .store_sample = ad5446_store_sample, .store_pwr_down = ad5620_store_pwr_down, }, [ID_AD5640_1250] = { .channel = AD5446_CHANNEL(14, 16, 0), .int_vref_mv = 1250, - .store_sample = ad5620_store_sample, + .store_sample = ad5446_store_sample, .store_pwr_down = ad5620_store_pwr_down, }, [ID_AD5660_2500] = { -- cgit v0.10.2 From af836d9a38aec16a99c9c9bee114111db8b9e8df Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 25 Apr 2012 09:44:54 +0200 Subject: staging:iio:dac:ad5446: Fix 24bit transfers We currently only write 16 bit in case where we should write 24 bit. The spi message length is calculated from the channel storage_size, but since the storage size is only 16 bit we end up with the wrong value for devices which have power down bits and thus a register with 24 bit. Since each store function knows how many bytes it has to write just use the spi_write function from there instead of going through the hassle of manually preparing a spi_message and keeping buffers in the state struct. Another advantage of this patch is that it will make implementing support for similar I2C based DACs much easier. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index 0da5c6c..2ce6b5b 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -24,31 +24,40 @@ #include "ad5446.h" -static void ad5446_store_sample(struct ad5446_state *st, unsigned val) +static int ad5446_store_sample(struct ad5446_state *st, unsigned val) { - st->data.d16 = cpu_to_be16(val); + __be16 data = cpu_to_be16(val); + return spi_write(st->spi, &data, sizeof(data)); } -static void ad5660_store_sample(struct ad5446_state *st, unsigned val) +static int ad5660_store_sample(struct ad5446_state *st, unsigned val) { + uint8_t data[3]; + val |= AD5660_LOAD; - st->data.d24[0] = (val >> 16) & 0xFF; - st->data.d24[1] = (val >> 8) & 0xFF; - st->data.d24[2] = val & 0xFF; + data[0] = (val >> 16) & 0xFF; + data[1] = (val >> 8) & 0xFF; + data[2] = val & 0xFF; + + return spi_write(st->spi, data, sizeof(data)); } -static void ad5620_store_pwr_down(struct ad5446_state *st, unsigned mode) +static int ad5620_store_pwr_down(struct ad5446_state *st, unsigned mode) { - st->data.d16 = cpu_to_be16(mode << 14); + __be16 data = cpu_to_be16(mode << 14); + return spi_write(st->spi, &data, sizeof(data)); } -static void ad5660_store_pwr_down(struct ad5446_state *st, unsigned mode) +static int ad5660_store_pwr_down(struct ad5446_state *st, unsigned mode) { unsigned val = mode << 16; + uint8_t data[3]; + + data[0] = (val >> 16) & 0xFF; + data[1] = (val >> 8) & 0xFF; + data[2] = val & 0xFF; - st->data.d24[0] = (val >> 16) & 0xFF; - st->data.d24[1] = (val >> 8) & 0xFF; - st->data.d24[2] = val & 0xFF; + return spi_write(st->spi, data, sizeof(data)); } static ssize_t ad5446_write_powerdown_mode(struct device *dev, @@ -111,11 +120,10 @@ static ssize_t ad5446_write_dac_powerdown(struct device *dev, st->pwr_down = readin; if (st->pwr_down) - st->chip_info->store_pwr_down(st, st->pwr_down_mode); + ret = st->chip_info->store_pwr_down(st, st->pwr_down_mode); else - st->chip_info->store_sample(st, st->cached_val); + ret = st->chip_info->store_sample(st, st->cached_val); - ret = spi_sync(st->spi, &st->msg); mutex_unlock(&indio_dev->mlock); return ret ? ret : len; @@ -272,10 +280,8 @@ static int ad5446_write_raw(struct iio_dev *indio_dev, val <<= chan->scan_type.shift; mutex_lock(&indio_dev->mlock); st->cached_val = val; - if (!st->pwr_down) { - st->chip_info->store_sample(st, val); - ret = spi_sync(st->spi, &st->msg); - } + if (!st->pwr_down) + ret = st->chip_info->store_sample(st, val); mutex_unlock(&indio_dev->mlock); break; default: @@ -338,14 +344,6 @@ static int __devinit ad5446_probe(struct spi_device *spi) indio_dev->channels = &st->chip_info->channel; indio_dev->num_channels = 1; - /* Setup default message */ - - st->xfer.tx_buf = &st->data; - st->xfer.len = st->chip_info->channel.scan_type.storagebits / 8; - - spi_message_init(&st->msg); - spi_message_add_tail(&st->xfer, &st->msg); - switch (spi_get_device_id(spi)->driver_data) { case ID_AD5620_2500: case ID_AD5620_1250: diff --git a/drivers/staging/iio/dac/ad5446.h b/drivers/staging/iio/dac/ad5446.h index 4ea3476..f9fff71 100644 --- a/drivers/staging/iio/dac/ad5446.h +++ b/drivers/staging/iio/dac/ad5446.h @@ -36,9 +36,6 @@ * @reg: supply regulator * @poll_work: bottom half of polling interrupt handler * @vref_mv: actual reference voltage used - * @xfer: default spi transfer - * @msg: default spi message - * @data: spi transmit buffer */ struct ad5446_state { @@ -50,12 +47,6 @@ struct ad5446_state { unsigned cached_val; unsigned pwr_down_mode; unsigned pwr_down; - struct spi_transfer xfer; - struct spi_message msg; - union { - unsigned short d16; - unsigned char d24[3]; - } data; }; /** @@ -69,8 +60,8 @@ struct ad5446_state { struct ad5446_chip_info { struct iio_chan_spec channel; u16 int_vref_mv; - void (*store_sample) (struct ad5446_state *st, unsigned val); - void (*store_pwr_down) (struct ad5446_state *st, unsigned mode); + int (*store_sample) (struct ad5446_state *st, unsigned val); + int (*store_pwr_down) (struct ad5446_state *st, unsigned mode); }; /** -- cgit v0.10.2 From 39c58b607948c731cc1b4c64a1f22f90f72684e2 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 25 Apr 2012 09:44:55 +0200 Subject: staging:iio:dac:ad5446: Remove unused struct field Remove the unused "poll_work" field from the ad5446_state struct. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/dac/ad5446.h b/drivers/staging/iio/dac/ad5446.h index f9fff71..29aa0dc 100644 --- a/drivers/staging/iio/dac/ad5446.h +++ b/drivers/staging/iio/dac/ad5446.h @@ -34,7 +34,6 @@ * @spi: spi_device * @chip_info: chip model specific constants, available modes etc * @reg: supply regulator - * @poll_work: bottom half of polling interrupt handler * @vref_mv: actual reference voltage used */ @@ -42,7 +41,6 @@ struct ad5446_state { struct spi_device *spi; const struct ad5446_chip_info *chip_info; struct regulator *reg; - struct work_struct poll_work; unsigned short vref_mv; unsigned cached_val; unsigned pwr_down_mode; -- cgit v0.10.2 From 4e5d3f92cfe79c928414ec497f04a831e5c63a83 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 25 Apr 2012 09:44:56 +0200 Subject: staging:iio:dac:ad5446: Do not check for individual chip ids in probe Use the chip_info's int_vref_mv field to decide whether a certain chip has a internal reference or not. There is no need to check for individual chip ids. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index 2ce6b5b..659d083 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -344,22 +344,12 @@ static int __devinit ad5446_probe(struct spi_device *spi) indio_dev->channels = &st->chip_info->channel; indio_dev->num_channels = 1; - switch (spi_get_device_id(spi)->driver_data) { - case ID_AD5620_2500: - case ID_AD5620_1250: - case ID_AD5640_2500: - case ID_AD5640_1250: - case ID_AD5660_2500: - case ID_AD5660_1250: + if (st->chip_info->int_vref_mv) st->vref_mv = st->chip_info->int_vref_mv; - break; - default: - if (voltage_uv) - st->vref_mv = voltage_uv / 1000; - else - dev_warn(&spi->dev, - "reference voltage unspecified\n"); - } + else if (voltage_uv) + st->vref_mv = voltage_uv / 1000; + else + dev_warn(&spi->dev, "reference voltage unspecified\n"); ret = iio_device_register(indio_dev); if (ret) -- cgit v0.10.2 From 11a7df4890d38886fc7f3eb993a5b3038c0a5527 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 25 Apr 2012 09:44:57 +0200 Subject: staging:iio:dac:ad5446: Remove duplicated chip_info entries There are three identical chip_info entries. Remove two of them and use the id of the remaining entry for all three device table entries. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index 659d083..00eece4 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -174,14 +174,6 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { .channel = AD5446_CHANNEL(16, 16, 0), .store_sample = ad5446_store_sample, }, - [ID_AD5542A] = { - .channel = AD5446_CHANNEL(16, 16, 0), - .store_sample = ad5446_store_sample, - }, - [ID_AD5543] = { - .channel = AD5446_CHANNEL(16, 16, 0), - .store_sample = ad5446_store_sample, - }, [ID_AD5512A] = { .channel = AD5446_CHANNEL(12, 16, 4), .store_sample = ad5446_store_sample, @@ -389,8 +381,8 @@ static const struct spi_device_id ad5446_id[] = { {"ad5446", ID_AD5446}, {"ad5512a", ID_AD5512A}, {"ad5541a", ID_AD5541A}, - {"ad5542a", ID_AD5542A}, - {"ad5543", ID_AD5543}, + {"ad5542a", ID_AD5541A}, /* ad5541a and ad5542a are compatible */ + {"ad5543", ID_AD5541A}, /* ad5541a and ad5543 are compatible */ {"ad5553", ID_AD5553}, {"ad5601", ID_AD5601}, {"ad5611", ID_AD5611}, diff --git a/drivers/staging/iio/dac/ad5446.h b/drivers/staging/iio/dac/ad5446.h index 29aa0dc..0651816 100644 --- a/drivers/staging/iio/dac/ad5446.h +++ b/drivers/staging/iio/dac/ad5446.h @@ -74,8 +74,6 @@ enum ad5446_supported_device_ids { ID_AD5444, ID_AD5446, ID_AD5541A, - ID_AD5542A, - ID_AD5543, ID_AD5512A, ID_AD5553, ID_AD5601, -- cgit v0.10.2 From 83f0f5723eb86ed0fcdeafde4a495303a1e19004 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 25 Apr 2012 09:44:58 +0200 Subject: staging:iio:dac:ad5446: Convert to extended channel attributes Use extended channel attributes instead of raw sysfs files for the additional channel attributes. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index 00eece4..20c414c 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -60,64 +60,69 @@ static int ad5660_store_pwr_down(struct ad5446_state *st, unsigned mode) return spi_write(st->spi, data, sizeof(data)); } -static ssize_t ad5446_write_powerdown_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) +static const char * const ad5446_powerdown_modes[] = { + "", "1kohm_to_gnd", "100kohm_to_gnd", "three_state" +}; + +static ssize_t ad5446_read_powerdown_mode_available(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, char *buf) +{ + return sprintf(buf, "%s %s %s\n", ad5446_powerdown_modes[1], + ad5446_powerdown_modes[2], ad5446_powerdown_modes[3]); +} + +static ssize_t ad5446_write_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ad5446_state *st = iio_priv(indio_dev); + int i; - if (sysfs_streq(buf, "1kohm_to_gnd")) - st->pwr_down_mode = MODE_PWRDWN_1k; - else if (sysfs_streq(buf, "100kohm_to_gnd")) - st->pwr_down_mode = MODE_PWRDWN_100k; - else if (sysfs_streq(buf, "three_state")) - st->pwr_down_mode = MODE_PWRDWN_TRISTATE; - else + for (i = 1; i < ARRAY_SIZE(ad5446_powerdown_modes); i++) { + if (sysfs_streq(buf, ad5446_powerdown_modes[i])) { + st->pwr_down_mode = i; + break; + } + } + + if (i == ARRAY_SIZE(ad5446_powerdown_modes)) return -EINVAL; return len; } -static ssize_t ad5446_read_powerdown_mode(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t ad5446_read_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ad5446_state *st = iio_priv(indio_dev); - char mode[][15] = {"", "1kohm_to_gnd", "100kohm_to_gnd", "three_state"}; - - return sprintf(buf, "%s\n", mode[st->pwr_down_mode]); + return sprintf(buf, "%s\n", ad5446_powerdown_modes[st->pwr_down_mode]); } -static ssize_t ad5446_read_dac_powerdown(struct device *dev, - struct device_attribute *attr, +static ssize_t ad5446_read_dac_powerdown(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ad5446_state *st = iio_priv(indio_dev); return sprintf(buf, "%d\n", st->pwr_down); } -static ssize_t ad5446_write_dac_powerdown(struct device *dev, - struct device_attribute *attr, +static ssize_t ad5446_write_dac_powerdown(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ad5446_state *st = iio_priv(indio_dev); - unsigned long readin; + bool powerdown; int ret; - ret = strict_strtol(buf, 10, &readin); + ret = strtobool(buf, &powerdown); if (ret) return ret; - if (readin > 1) - ret = -EINVAL; - mutex_lock(&indio_dev->mlock); - st->pwr_down = readin; + st->pwr_down = powerdown; if (st->pwr_down) ret = st->chip_info->store_pwr_down(st, st->pwr_down_mode); @@ -129,38 +134,40 @@ static ssize_t ad5446_write_dac_powerdown(struct device *dev, return ret ? ret : len; } -static IIO_DEVICE_ATTR(out_voltage_powerdown_mode, S_IRUGO | S_IWUSR, - ad5446_read_powerdown_mode, - ad5446_write_powerdown_mode, 0); - -static IIO_CONST_ATTR(out_voltage_powerdown_mode_available, - "1kohm_to_gnd 100kohm_to_gnd three_state"); - -static IIO_DEVICE_ATTR(out_voltage0_powerdown, S_IRUGO | S_IWUSR, - ad5446_read_dac_powerdown, - ad5446_write_dac_powerdown, 0); - -static struct attribute *ad5446_attributes[] = { - &iio_dev_attr_out_voltage0_powerdown.dev_attr.attr, - &iio_dev_attr_out_voltage_powerdown_mode.dev_attr.attr, - &iio_const_attr_out_voltage_powerdown_mode_available.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad5446_attribute_group = { - .attrs = ad5446_attributes, +static const struct iio_chan_spec_ext_info ad5064_ext_info_powerdown[] = { + { + .name = "powerdown", + .read = ad5446_read_dac_powerdown, + .write = ad5446_write_dac_powerdown, + }, { + .name = "powerdown_mode", + .read = ad5446_read_powerdown_mode, + .write = ad5446_write_powerdown_mode, + }, { + .name = "powerdown_mode_available", + .shared = true, + .read = ad5446_read_powerdown_mode_available, + }, + { }, }; -#define AD5446_CHANNEL(bits, storage, shift) { \ +#define _AD5446_CHANNEL(bits, storage, shift, ext) { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ .output = 1, \ .channel = 0, \ .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ IIO_CHAN_INFO_SCALE_SHARED_BIT, \ - .scan_type = IIO_ST('u', (bits), (storage), (shift)) \ + .scan_type = IIO_ST('u', (bits), (storage), (shift)), \ + .ext_info = (ext), \ } +#define AD5446_CHANNEL(bits, storage, shift) \ + _AD5446_CHANNEL(bits, storage, shift, NULL) + +#define AD5446_CHANNEL_POWERDOWN(bits, storage, shift) \ + _AD5446_CHANNEL(bits, storage, shift, ad5064_ext_info_powerdown) + static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { [ID_AD5444] = { .channel = AD5446_CHANNEL(12, 16, 2), @@ -183,52 +190,52 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { .store_sample = ad5446_store_sample, }, [ID_AD5601] = { - .channel = AD5446_CHANNEL(8, 16, 6), + .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 6), .store_sample = ad5446_store_sample, .store_pwr_down = ad5620_store_pwr_down, }, [ID_AD5611] = { - .channel = AD5446_CHANNEL(10, 16, 4), + .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 4), .store_sample = ad5446_store_sample, .store_pwr_down = ad5620_store_pwr_down, }, [ID_AD5621] = { - .channel = AD5446_CHANNEL(12, 16, 2), + .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), .store_sample = ad5446_store_sample, .store_pwr_down = ad5620_store_pwr_down, }, [ID_AD5620_2500] = { - .channel = AD5446_CHANNEL(12, 16, 2), + .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), .int_vref_mv = 2500, .store_sample = ad5446_store_sample, .store_pwr_down = ad5620_store_pwr_down, }, [ID_AD5620_1250] = { - .channel = AD5446_CHANNEL(12, 16, 2), + .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), .int_vref_mv = 1250, .store_sample = ad5446_store_sample, .store_pwr_down = ad5620_store_pwr_down, }, [ID_AD5640_2500] = { - .channel = AD5446_CHANNEL(14, 16, 0), + .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0), .int_vref_mv = 2500, .store_sample = ad5446_store_sample, .store_pwr_down = ad5620_store_pwr_down, }, [ID_AD5640_1250] = { - .channel = AD5446_CHANNEL(14, 16, 0), + .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0), .int_vref_mv = 1250, .store_sample = ad5446_store_sample, .store_pwr_down = ad5620_store_pwr_down, }, [ID_AD5660_2500] = { - .channel = AD5446_CHANNEL(16, 16, 0), + .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), .int_vref_mv = 2500, .store_sample = ad5660_store_sample, .store_pwr_down = ad5660_store_pwr_down, }, [ID_AD5660_1250] = { - .channel = AD5446_CHANNEL(16, 16, 0), + .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), .int_vref_mv = 1250, .store_sample = ad5660_store_sample, .store_pwr_down = ad5660_store_pwr_down, @@ -286,13 +293,6 @@ static int ad5446_write_raw(struct iio_dev *indio_dev, static const struct iio_info ad5446_info = { .read_raw = ad5446_read_raw, .write_raw = ad5446_write_raw, - .attrs = &ad5446_attribute_group, - .driver_module = THIS_MODULE, -}; - -static const struct iio_info ad5446_info_no_pwr_down = { - .read_raw = ad5446_read_raw, - .write_raw = ad5446_write_raw, .driver_module = THIS_MODULE, }; @@ -328,10 +328,7 @@ static int __devinit ad5446_probe(struct spi_device *spi) /* Establish that the iio_dev is a child of the spi device */ indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(spi)->name; - if (st->chip_info->store_pwr_down) - indio_dev->info = &ad5446_info; - else - indio_dev->info = &ad5446_info_no_pwr_down; + indio_dev->info = &ad5446_info; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = &st->chip_info->channel; indio_dev->num_channels = 1; -- cgit v0.10.2 From cae329e04ac1f187338d0febd4e1ddf81db582cf Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 25 Apr 2012 09:44:59 +0200 Subject: staging:iio:dac:ad5446: Consolidate store_sample and store_pwr_down functions The devices supported by this drivers only have a single shift register, which contains both the power down mode and the output sample. So writing the power down mode and the output sample can be done by the same function. Call this function prepare_write as it will prepare the spi message for a write. Also introduce a small helper function which performs the whole write by calling the chip the specific prepare function followed by a spi_sync. The two power down bits are always placed ontop of the msb of the output sample, so we can easily calculate their position by adding the channels shift to the channels realbits. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index 20c414c..731cd05 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -24,35 +24,16 @@ #include "ad5446.h" -static int ad5446_store_sample(struct ad5446_state *st, unsigned val) +static int ad5446_write(struct ad5446_state *st, unsigned val) { __be16 data = cpu_to_be16(val); return spi_write(st->spi, &data, sizeof(data)); } -static int ad5660_store_sample(struct ad5446_state *st, unsigned val) +static int ad5660_write(struct ad5446_state *st, unsigned val) { uint8_t data[3]; - val |= AD5660_LOAD; - data[0] = (val >> 16) & 0xFF; - data[1] = (val >> 8) & 0xFF; - data[2] = val & 0xFF; - - return spi_write(st->spi, data, sizeof(data)); -} - -static int ad5620_store_pwr_down(struct ad5446_state *st, unsigned mode) -{ - __be16 data = cpu_to_be16(mode << 14); - return spi_write(st->spi, &data, sizeof(data)); -} - -static int ad5660_store_pwr_down(struct ad5446_state *st, unsigned mode) -{ - unsigned val = mode << 16; - uint8_t data[3]; - data[0] = (val >> 16) & 0xFF; data[1] = (val >> 8) & 0xFF; data[2] = val & 0xFF; @@ -114,6 +95,8 @@ static ssize_t ad5446_write_dac_powerdown(struct iio_dev *indio_dev, const char *buf, size_t len) { struct ad5446_state *st = iio_priv(indio_dev); + unsigned int shift; + unsigned int val; bool powerdown; int ret; @@ -124,11 +107,14 @@ static ssize_t ad5446_write_dac_powerdown(struct iio_dev *indio_dev, mutex_lock(&indio_dev->mlock); st->pwr_down = powerdown; - if (st->pwr_down) - ret = st->chip_info->store_pwr_down(st, st->pwr_down_mode); - else - ret = st->chip_info->store_sample(st, st->cached_val); + if (st->pwr_down) { + shift = chan->scan_type.realbits + chan->scan_type.shift; + val = st->pwr_down_mode << shift; + } else { + val = st->cached_val; + } + ret = st->chip_info->write(st, val); mutex_unlock(&indio_dev->mlock); return ret ? ret : len; @@ -171,74 +157,65 @@ static const struct iio_chan_spec_ext_info ad5064_ext_info_powerdown[] = { static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { [ID_AD5444] = { .channel = AD5446_CHANNEL(12, 16, 2), - .store_sample = ad5446_store_sample, + .write = ad5446_write, }, [ID_AD5446] = { .channel = AD5446_CHANNEL(14, 16, 0), - .store_sample = ad5446_store_sample, + .write = ad5446_write, }, [ID_AD5541A] = { .channel = AD5446_CHANNEL(16, 16, 0), - .store_sample = ad5446_store_sample, + .write = ad5446_write, }, [ID_AD5512A] = { .channel = AD5446_CHANNEL(12, 16, 4), - .store_sample = ad5446_store_sample, + .write = ad5446_write, }, [ID_AD5553] = { .channel = AD5446_CHANNEL(14, 16, 0), - .store_sample = ad5446_store_sample, + .write = ad5446_write, }, [ID_AD5601] = { .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 6), - .store_sample = ad5446_store_sample, - .store_pwr_down = ad5620_store_pwr_down, + .write = ad5446_write, }, [ID_AD5611] = { .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 4), - .store_sample = ad5446_store_sample, - .store_pwr_down = ad5620_store_pwr_down, + .write = ad5446_write, }, [ID_AD5621] = { .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), - .store_sample = ad5446_store_sample, - .store_pwr_down = ad5620_store_pwr_down, + .write = ad5446_write, }, [ID_AD5620_2500] = { .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), .int_vref_mv = 2500, - .store_sample = ad5446_store_sample, - .store_pwr_down = ad5620_store_pwr_down, + .write = ad5446_write, }, [ID_AD5620_1250] = { .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), .int_vref_mv = 1250, - .store_sample = ad5446_store_sample, - .store_pwr_down = ad5620_store_pwr_down, + .write = ad5446_write, }, [ID_AD5640_2500] = { .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0), .int_vref_mv = 2500, - .store_sample = ad5446_store_sample, - .store_pwr_down = ad5620_store_pwr_down, + .write = ad5446_write, }, [ID_AD5640_1250] = { .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0), .int_vref_mv = 1250, - .store_sample = ad5446_store_sample, - .store_pwr_down = ad5620_store_pwr_down, + .write = ad5446_write, }, [ID_AD5660_2500] = { .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), .int_vref_mv = 2500, - .store_sample = ad5660_store_sample, - .store_pwr_down = ad5660_store_pwr_down, + .write = ad5660_write, }, [ID_AD5660_1250] = { .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), .int_vref_mv = 1250, - .store_sample = ad5660_store_sample, - .store_pwr_down = ad5660_store_pwr_down, + .write = ad5660_write, }, }; @@ -280,7 +257,7 @@ static int ad5446_write_raw(struct iio_dev *indio_dev, mutex_lock(&indio_dev->mlock); st->cached_val = val; if (!st->pwr_down) - ret = st->chip_info->store_sample(st, val); + ret = st->chip_info->write(st, val); mutex_unlock(&indio_dev->mlock); break; default: diff --git a/drivers/staging/iio/dac/ad5446.h b/drivers/staging/iio/dac/ad5446.h index 0651816..1a0fb4a 100644 --- a/drivers/staging/iio/dac/ad5446.h +++ b/drivers/staging/iio/dac/ad5446.h @@ -51,15 +51,13 @@ struct ad5446_state { * struct ad5446_chip_info - chip specific information * @channel: channel spec for the DAC * @int_vref_mv: AD5620/40/60: the internal reference voltage - * @store_sample: chip specific helper function to store the datum - * @store_sample: chip specific helper function to store the powerpown cmd + * @write: chip specific helper function to write to the register */ struct ad5446_chip_info { struct iio_chan_spec channel; u16 int_vref_mv; - int (*store_sample) (struct ad5446_state *st, unsigned val); - int (*store_pwr_down) (struct ad5446_state *st, unsigned mode); + int (*write)(struct ad5446_state *st, unsigned val); }; /** -- cgit v0.10.2 From 5e06bdfb46e8b96bdde1f306d3fadff2d6a2ae77 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 25 Apr 2012 09:45:00 +0200 Subject: staging:iio:dac:ad5446: Return cached value for 'raw' attribute We can not read back the value from the device, but we cache the value anyway so we might as well return the cached value instead of an error. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index 731cd05..9dc67c8 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -229,6 +229,9 @@ static int ad5446_read_raw(struct iio_dev *indio_dev, unsigned long scale_uv; switch (m) { + case IIO_CHAN_INFO_RAW: + *val = st->cached_val; + return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits; *val = scale_uv / 1000; -- cgit v0.10.2 From 18e5ab31eeffc6977b0dc558154ebf6475131b34 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 25 Apr 2012 09:45:01 +0200 Subject: staging:iio:dac:ad5446: Add support for the AD5662 The AD5662 is compatible to the AD5660, but uses an external reference instead of an internal. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index 9dc67c8..00b138e 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -217,6 +217,10 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { .int_vref_mv = 1250, .write = ad5660_write, }, + [ID_AD5662] = { + .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), + .write = ad5660_write, + }, }; static int ad5446_read_raw(struct iio_dev *indio_dev, @@ -370,6 +374,7 @@ static const struct spi_device_id ad5446_id[] = { {"ad5640-1250", ID_AD5640_1250}, {"ad5660-2500", ID_AD5660_2500}, {"ad5660-1250", ID_AD5660_1250}, + {"ad5662", ID_AD5662}, {} }; MODULE_DEVICE_TABLE(spi, ad5446_id); diff --git a/drivers/staging/iio/dac/ad5446.h b/drivers/staging/iio/dac/ad5446.h index 1a0fb4a..dfd68ce 100644 --- a/drivers/staging/iio/dac/ad5446.h +++ b/drivers/staging/iio/dac/ad5446.h @@ -83,6 +83,7 @@ enum ad5446_supported_device_ids { ID_AD5640_1250, ID_AD5660_2500, ID_AD5660_1250, + ID_AD5662, }; #endif /* IIO_DAC_AD5446_H_ */ -- cgit v0.10.2 From ae467dd55d9cff0e8e3535e8b353e4a686205096 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 25 Apr 2012 09:45:02 +0200 Subject: staging:iio:dac:ad5446: Update Kconfig entry There is one device supported by the driver which is not listed in the Kconfig help test. This patch adds it. Also we are past the point were we can possible fit all devices supported by the driver in the Kconfig entry title, so just list the initial device that was supported by this driver and note that similar devices are supported as well. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/dac/Kconfig b/drivers/staging/iio/dac/Kconfig index a57803a..a626f03 100644 --- a/drivers/staging/iio/dac/Kconfig +++ b/drivers/staging/iio/dac/Kconfig @@ -56,12 +56,12 @@ config AD5624R_SPI AD5664R converters (DAC). This driver uses the common SPI interface. config AD5446 - tristate "Analog Devices AD5444/6, AD5620/40/60 and AD5542A/12A DAC SPI driver" + tristate "Analog Devices AD5446 and similar single channel DACs driver" depends on SPI help Say yes here to build support for Analog Devices AD5444, AD5446, - AD5512A, AD5542A, AD5543, AD5553, AD5601, AD5611, AD5620, AD5621, - AD5640, AD5660, AD5662 DACs. + AD5512A, AD5541A, AD5542A, AD5543, AD5553, AD5601, AD5611, AD5620, + AD5621, AD5640, AD5660, AD5662 DACs. To compile this driver as a module, choose M here: the module will be called ad5446. -- cgit v0.10.2 From a27545bf0bab9027e5c040901b68956551d9f63e Mon Sep 17 00:00:00 2001 From: Minchan Kim Date: Wed, 25 Apr 2012 15:23:09 +0900 Subject: zsmalloc: use PageFlag macro instead of [set|test]_bit MM code always uses PageXXX to handle page flags. Let's keep the consistency. Signed-off-by: Minchan Kim Acked-by: Nitin Gupta Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c index 09caa4f..388fb8b 100644 --- a/drivers/staging/zsmalloc/zsmalloc-main.c +++ b/drivers/staging/zsmalloc/zsmalloc-main.c @@ -45,12 +45,12 @@ static DEFINE_PER_CPU(struct mapping_area, zs_map_area); static int is_first_page(struct page *page) { - return test_bit(PG_private, &page->flags); + return PagePrivate(page); } static int is_last_page(struct page *page) { - return test_bit(PG_private_2, &page->flags); + return PagePrivate2(page); } static void get_zspage_mapping(struct page *page, unsigned int *class_idx, @@ -371,7 +371,7 @@ static struct page *alloc_zspage(struct size_class *class, gfp_t flags) INIT_LIST_HEAD(&page->lru); if (i == 0) { /* first page */ - set_bit(PG_private, &page->flags); + SetPagePrivate(page); set_page_private(page, 0); first_page = page; first_page->inuse = 0; @@ -383,8 +383,7 @@ static struct page *alloc_zspage(struct size_class *class, gfp_t flags) if (i >= 2) list_add(&page->lru, &prev_page->lru); if (i == class->zspage_order - 1) /* last page */ - set_bit(PG_private_2, &page->flags); - + SetPagePrivate2(page); prev_page = page; } -- cgit v0.10.2 From 8dc245970a25f51b3862fae7df782a5c0e1777fb Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 25 Apr 2012 23:28:35 +0900 Subject: staging,ozwpan: Fix typo in comments within staging/ozwpan Correct spelling in comments withon staging/ozwpan Signed-off-by: Masanari Iida Acked-by: Chris Kelly Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ozwpan/README b/drivers/staging/ozwpan/README index bb1a69b..7c055ec 100644 --- a/drivers/staging/ozwpan/README +++ b/drivers/staging/ozwpan/README @@ -9,7 +9,7 @@ technology. To operate the driver must be bound to a suitable network interface. This can be done when the module is loaded (specifying the name of the network interface -as a paramter - e.g. 'insmod ozwpan g_net_dev=go0') or can be bound after +as a parameter - e.g. 'insmod ozwpan g_net_dev=go0') or can be bound after loading using an ioctl call. See the ozappif.h file and the ioctls OZ_IOCTL_ADD_BINDING and OZ_IOCTL_REMOVE_BINDING. diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index cfa25e8..251f07c 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c @@ -1416,7 +1416,7 @@ static void oz_process_ep0_urb(struct oz_hcd *ozhcd, struct urb *urb, oz_trace("USB_REQ_SET_CONFIGURATION - req\n"); break; case USB_REQ_GET_CONFIGURATION: - /* We short curcuit this case and reply directly since + /* We short circuit this case and reply directly since * we have the selected configuration number cached. */ oz_event_log(OZ_EVT_CTRL_LOCAL, setup->bRequest, 0, 0, @@ -1432,7 +1432,7 @@ static void oz_process_ep0_urb(struct oz_hcd *ozhcd, struct urb *urb, } break; case USB_REQ_GET_INTERFACE: - /* We short curcuit this case and reply directly since + /* We short circuit this case and reply directly since * we have the selected interface alternative cached. */ oz_event_log(OZ_EVT_CTRL_LOCAL, setup->bRequest, 0, 0, diff --git a/drivers/staging/ozwpan/ozusbsvc.c b/drivers/staging/ozwpan/ozusbsvc.c index 9e74f96..8fa7f25 100644 --- a/drivers/staging/ozwpan/ozusbsvc.c +++ b/drivers/staging/ozwpan/ozusbsvc.c @@ -7,7 +7,7 @@ * The implementation of this service is split into two parts the first of which * is protocol independent and the second contains protocol specific details. * This split is to allow alternative protocols to be defined. - * The implemenation of this service uses ozhcd.c to implement a USB HCD. + * The implementation of this service uses ozhcd.c to implement a USB HCD. * ----------------------------------------------------------------------------- */ #include -- cgit v0.10.2 From 49c36dffbd4624fef306162f7ff7458abfc22e1d Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 25 Apr 2012 15:54:56 +0100 Subject: staging:iio:documentation pull a few sysfs entries out of main docs. These two attributes are only used in the one driver. Whilst they are fairly general I'm not entirely happy committing to them at this stage. Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio b/drivers/staging/iio/Documentation/sysfs-bus-iio index eec9acb..f7de494 100644 --- a/drivers/staging/iio/Documentation/sysfs-bus-iio +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio @@ -728,24 +728,3 @@ Contact: linux-iio@vger.kernel.org Description: This attribute is used to read the amount of quadrature error present in the device at a given time. - -What: /sys/.../iio:deviceX/ac_excitation_en -KernelVersion: 3.1.0 -Contact: linux-iio@vger.kernel.org -Description: - This attribute, if available, is used to enable the AC - excitation mode found on some converters. In ac excitation mode, - the polarity of the excitation voltage is reversed on - alternate cycles, to eliminate DC errors. - -What: /sys/.../iio:deviceX/bridge_switch_en -KernelVersion: 3.1.0 -Contact: linux-iio@vger.kernel.org -Description: - This attribute, if available, is used to close or open the - bridge power down switch found on some converters. - In bridge applications, such as strain gauges and load cells, - the bridge itself consumes the majority of the current in the - system. To minimize the current consumption of the system, - the bridge can be disconnected (when it is not being used - using the bridge_switch_en attribute. diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-ad7192 b/drivers/staging/iio/Documentation/sysfs-bus-iio-ad7192 new file mode 100644 index 0000000..1c35c50 --- /dev/null +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio-ad7192 @@ -0,0 +1,20 @@ +What: /sys/.../iio:deviceX/ac_excitation_en +KernelVersion: 3.1.0 +Contact: linux-iio@vger.kernel.org +Description: + This attribute, if available, is used to enable the AC + excitation mode found on some converters. In ac excitation mode, + the polarity of the excitation voltage is reversed on + alternate cycles, to eliminate DC errors. + +What: /sys/.../iio:deviceX/bridge_switch_en +KernelVersion: 3.1.0 +Contact: linux-iio@vger.kernel.org +Description: + This attribute, if available, is used to close or open the + bridge power down switch found on some converters. + In bridge applications, such as strain gauges and load cells, + the bridge itself consumes the majority of the current in the + system. To minimize the current consumption of the system, + the bridge can be disconnected (when it is not being used + using the bridge_switch_en attribute. -- cgit v0.10.2 From 68284a12923f9f8f2741efca10c045e179f2e753 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 25 Apr 2012 15:54:57 +0100 Subject: staging:iio:Documentation Trivial typo fixes. Just a couple of things I came across whilst reviewing this file for moving out of staging. I doubt anyone cares, but seemed sensible to fix them now! Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio b/drivers/staging/iio/Documentation/sysfs-bus-iio index f7de494..2ce4dad 100644 --- a/drivers/staging/iio/Documentation/sysfs-bus-iio +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio @@ -108,7 +108,7 @@ Description: physically equivalent inputs when non differential readings are separately available. In differential only parts, then all that is required is a consistent labeling. Units after application - of scale and offset are nanofarads.. + of scale and offset are nanofarads. What: /sys/bus/iio/devices/iio:deviceX/in_temp_raw What: /sys/bus/iio/devices/iio:deviceX/in_tempX_raw @@ -119,7 +119,7 @@ KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: Raw (unscaled no bias removal etc) temperature measurement. - It an axis is specified it generally means that the temperature + If an axis is specified it generally means that the temperature sensor is associated with one part of a compound device (e.g. a gyroscope axis). Units after application of scale and offset are milli degrees Celsuis. @@ -232,7 +232,7 @@ Description: If known for a device, scale to be applied to Y[_name]_raw post addition of [Y][_name]_offset in order to obtain the measured value in units as specified in - [Y][_name]_raw documentation.. If shared across all in + [Y][_name]_raw documentation. If shared across all in channels then Y and are not present and the value is called [Y][_name]_scale. The peak modifier means this value is applied to Y[_name]_peak_raw values. -- cgit v0.10.2 From 06458e277eac2b8761b0a04d3c808d57be281a2e Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 25 Apr 2012 15:54:58 +0100 Subject: IIO: Move core headers to include/linux/iio Step 1 in moving the IIO core out of staging. Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/Documentation/iio_event_monitor.c b/drivers/staging/iio/Documentation/iio_event_monitor.c index 0d21a27..2227584 100644 --- a/drivers/staging/iio/Documentation/iio_event_monitor.c +++ b/drivers/staging/iio/Documentation/iio_event_monitor.c @@ -27,7 +27,7 @@ #include #include #include "iio_utils.h" -#include "../events.h" +#include static const char * const iio_chan_type_name_spec[] = { [IIO_VOLTAGE] = "voltage", diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c index 8022bbd..9dce7b8 100644 --- a/drivers/staging/iio/accel/adis16201_core.c +++ b/drivers/staging/iio/accel/adis16201_core.c @@ -15,9 +15,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include +#include +#include #include "adis16201.h" diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c index 49912e2..247602a 100644 --- a/drivers/staging/iio/accel/adis16201_ring.c +++ b/drivers/staging/iio/accel/adis16201_ring.c @@ -5,9 +5,9 @@ #include #include -#include "../iio.h" +#include #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include #include "adis16201.h" diff --git a/drivers/staging/iio/accel/adis16201_trigger.c b/drivers/staging/iio/accel/adis16201_trigger.c index bce505e..da687e0 100644 --- a/drivers/staging/iio/accel/adis16201_trigger.c +++ b/drivers/staging/iio/accel/adis16201_trigger.c @@ -3,8 +3,8 @@ #include #include -#include "../iio.h" -#include "../trigger.h" +#include +#include #include "adis16201.h" /** diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c index f23b7c5..cf1a0e5 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_core.c @@ -15,9 +15,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include +#include +#include #include "adis16203.h" diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c index 5c40f6c..2171f74 100644 --- a/drivers/staging/iio/accel/adis16203_ring.c +++ b/drivers/staging/iio/accel/adis16203_ring.c @@ -5,9 +5,9 @@ #include #include -#include "../iio.h" +#include #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include #include "adis16203.h" /** diff --git a/drivers/staging/iio/accel/adis16203_trigger.c b/drivers/staging/iio/accel/adis16203_trigger.c index 24bcb8e..1e1b981e 100644 --- a/drivers/staging/iio/accel/adis16203_trigger.c +++ b/drivers/staging/iio/accel/adis16203_trigger.c @@ -3,8 +3,8 @@ #include #include -#include "../iio.h" -#include "../trigger.h" +#include +#include #include "adis16203.h" /** diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index bffbbe8..2a15d71 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -18,9 +18,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include +#include +#include #include "adis16204.h" diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c index bf5488e..0a8b125 100644 --- a/drivers/staging/iio/accel/adis16204_ring.c +++ b/drivers/staging/iio/accel/adis16204_ring.c @@ -5,9 +5,9 @@ #include #include -#include "../iio.h" +#include #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include #include "adis16204.h" /** diff --git a/drivers/staging/iio/accel/adis16204_trigger.c b/drivers/staging/iio/accel/adis16204_trigger.c index 6e542af..e6f2937 100644 --- a/drivers/staging/iio/accel/adis16204_trigger.c +++ b/drivers/staging/iio/accel/adis16204_trigger.c @@ -3,8 +3,8 @@ #include #include -#include "../iio.h" -#include "../trigger.h" +#include +#include #include "adis16204.h" /** diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index b1fbf19..cad4113 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -16,9 +16,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include +#include +#include #include "adis16209.h" diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c index 3101c53..f7ed989 100644 --- a/drivers/staging/iio/accel/adis16209_ring.c +++ b/drivers/staging/iio/accel/adis16209_ring.c @@ -5,9 +5,9 @@ #include #include -#include "../iio.h" +#include #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include #include "adis16209.h" /** diff --git a/drivers/staging/iio/accel/adis16209_trigger.c b/drivers/staging/iio/accel/adis16209_trigger.c index c5d82c1..5f5dbed 100644 --- a/drivers/staging/iio/accel/adis16209_trigger.c +++ b/drivers/staging/iio/accel/adis16209_trigger.c @@ -3,8 +3,8 @@ #include #include -#include "../iio.h" -#include "../trigger.h" +#include +#include #include "adis16209.h" /** diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index 2740c8e..c86a3db 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -15,8 +15,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #include "adis16220.h" diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index 18ed396..fcc2c19 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -19,9 +19,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include +#include +#include #include "adis16240.h" diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c index c4459f7..1aa9566 100644 --- a/drivers/staging/iio/accel/adis16240_ring.c +++ b/drivers/staging/iio/accel/adis16240_ring.c @@ -5,9 +5,9 @@ #include #include -#include "../iio.h" +#include #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include #include "adis16240.h" /** diff --git a/drivers/staging/iio/accel/adis16240_trigger.c b/drivers/staging/iio/accel/adis16240_trigger.c index 8e0ce56..53eda35 100644 --- a/drivers/staging/iio/accel/adis16240_trigger.c +++ b/drivers/staging/iio/accel/adis16240_trigger.c @@ -3,8 +3,8 @@ #include #include -#include "../iio.h" -#include "../trigger.h" +#include +#include #include "adis16240.h" /** diff --git a/drivers/staging/iio/accel/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c index 601da28..3292390 100644 --- a/drivers/staging/iio/accel/kxsd9.c +++ b/drivers/staging/iio/accel/kxsd9.c @@ -23,8 +23,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #define KXSD9_REG_X 0x00 #define KXSD9_REG_Y 0x02 diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index ee8ad3a..bbef0be 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -23,10 +23,10 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" -#include "../buffer.h" +#include +#include +#include +#include #include "lis3l02dq.h" diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index ebd5b4d..c8b8164 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -6,11 +6,11 @@ #include #include -#include "../iio.h" +#include #include "../ring_sw.h" -#include "../kfifo_buf.h" -#include "../trigger.h" -#include "../trigger_consumer.h" +#include +#include +#include #include "lis3l02dq.h" /** diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index 646e05c..2ee5eb0 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -18,10 +18,10 @@ #include #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" -#include "../buffer.h" +#include +#include +#include +#include #include "sca3000.h" diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c index 6b824a1..889bc86 100644 --- a/drivers/staging/iio/accel/sca3000_ring.c +++ b/drivers/staging/iio/accel/sca3000_ring.c @@ -18,9 +18,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include +#include +#include #include "../ring_hw.h" #include "sca3000.h" diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 5d31685..14f9834 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -17,12 +17,12 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include +#include +#include #include "../ring_sw.h" -#include "../trigger.h" -#include "../trigger_consumer.h" +#include +#include #include "ad7192.h" diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c index f0c0c72..d72780f 100644 --- a/drivers/staging/iio/adc/ad7280a.c +++ b/drivers/staging/iio/adc/ad7280a.c @@ -16,9 +16,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" +#include +#include +#include #include "ad7280a.h" diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c index 298249f..b8e4fe6 100644 --- a/drivers/staging/iio/adc/ad7291.c +++ b/drivers/staging/iio/adc/ad7291.c @@ -17,9 +17,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" +#include +#include +#include /* * Simplified handling diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c index 5d54a79..974a8e3 100644 --- a/drivers/staging/iio/adc/ad7298_core.c +++ b/drivers/staging/iio/adc/ad7298_core.c @@ -16,9 +16,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include +#include +#include #include "ad7298.h" diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c index 538e3b3..943caa3 100644 --- a/drivers/staging/iio/adc/ad7298_ring.c +++ b/drivers/staging/iio/adc/ad7298_ring.c @@ -11,10 +11,10 @@ #include #include -#include "../iio.h" -#include "../buffer.h" +#include +#include #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include #include "ad7298.h" diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c index ce71522..1241b9f 100644 --- a/drivers/staging/iio/adc/ad7476_core.c +++ b/drivers/staging/iio/adc/ad7476_core.c @@ -15,9 +15,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include +#include +#include #include "ad7476.h" diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c index 8534f6b..51403892 100644 --- a/drivers/staging/iio/adc/ad7476_ring.c +++ b/drivers/staging/iio/adc/ad7476_ring.c @@ -13,10 +13,10 @@ #include #include -#include "../iio.h" -#include "../buffer.h" +#include +#include #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include #include "ad7476.h" diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c index 802cdaf..9c54064 100644 --- a/drivers/staging/iio/adc/ad7606_core.c +++ b/drivers/staging/iio/adc/ad7606_core.c @@ -18,9 +18,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include +#include +#include #include "ad7606.h" diff --git a/drivers/staging/iio/adc/ad7606_par.c b/drivers/staging/iio/adc/ad7606_par.c index bb152a8..a53faaf 100644 --- a/drivers/staging/iio/adc/ad7606_par.c +++ b/drivers/staging/iio/adc/ad7606_par.c @@ -12,7 +12,7 @@ #include #include -#include "../iio.h" +#include #include "ad7606.h" static int ad7606_par16_read_block(struct device *dev, diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c index 007b600..3dd9602 100644 --- a/drivers/staging/iio/adc/ad7606_ring.c +++ b/drivers/staging/iio/adc/ad7606_ring.c @@ -11,10 +11,10 @@ #include #include -#include "../iio.h" -#include "../buffer.h" +#include +#include #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include #include "ad7606.h" diff --git a/drivers/staging/iio/adc/ad7606_spi.c b/drivers/staging/iio/adc/ad7606_spi.c index 237f1c4..099d347 100644 --- a/drivers/staging/iio/adc/ad7606_spi.c +++ b/drivers/staging/iio/adc/ad7606_spi.c @@ -11,7 +11,7 @@ #include #include -#include "../iio.h" +#include #include "ad7606.h" #define MAX_SPI_FREQ_HZ 23500000 /* VDRIVE above 4.75 V */ diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c index eeedbdb..a8e661e 100644 --- a/drivers/staging/iio/adc/ad7780.c +++ b/drivers/staging/iio/adc/ad7780.c @@ -18,8 +18,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #include "ad7780.h" diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index 7f68c7c..3a7d1a7 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -18,12 +18,12 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include +#include +#include #include "../ring_sw.h" -#include "../trigger.h" -#include "../trigger_consumer.h" +#include +#include #include "ad7793.h" diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c index 52b720e..586f6c2 100644 --- a/drivers/staging/iio/adc/ad7816.c +++ b/drivers/staging/iio/adc/ad7816.c @@ -16,9 +16,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" +#include +#include +#include /* * AD7816 config masks diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c index 2cce09f..fef9169 100644 --- a/drivers/staging/iio/adc/ad7887_core.c +++ b/drivers/staging/iio/adc/ad7887_core.c @@ -15,9 +15,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include +#include +#include #include "ad7887.h" diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c index 62681a8..f1846db 100644 --- a/drivers/staging/iio/adc/ad7887_ring.c +++ b/drivers/staging/iio/adc/ad7887_ring.c @@ -12,10 +12,10 @@ #include #include -#include "../iio.h" -#include "../buffer.h" +#include +#include #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include #include "ad7887.h" diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c index 429fb41..561ae17 100644 --- a/drivers/staging/iio/adc/ad799x_core.c +++ b/drivers/staging/iio/adc/ad799x_core.c @@ -33,10 +33,10 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" -#include "../buffer.h" +#include +#include +#include +#include #include "ad799x.h" diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c index 5190e50..18366b5 100644 --- a/drivers/staging/iio/adc/ad799x_ring.c +++ b/drivers/staging/iio/adc/ad799x_ring.c @@ -16,10 +16,10 @@ #include #include -#include "../iio.h" -#include "../buffer.h" +#include +#include #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include #include "ad799x.h" diff --git a/drivers/staging/iio/adc/adt7310.c b/drivers/staging/iio/adc/adt7310.c index caf57c1..223aea5 100644 --- a/drivers/staging/iio/adc/adt7310.c +++ b/drivers/staging/iio/adc/adt7310.c @@ -15,9 +15,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" +#include +#include +#include /* * ADT7310 registers definition */ diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c index dff3e8c..dab4a5a 100644 --- a/drivers/staging/iio/adc/adt7410.c +++ b/drivers/staging/iio/adc/adt7410.c @@ -15,9 +15,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" +#include +#include +#include /* * ADT7410 registers definition diff --git a/drivers/staging/iio/adc/lpc32xx_adc.c b/drivers/staging/iio/adc/lpc32xx_adc.c index d7f4fe4..0ddd917 100644 --- a/drivers/staging/iio/adc/lpc32xx_adc.c +++ b/drivers/staging/iio/adc/lpc32xx_adc.c @@ -32,8 +32,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include /* * LPC32XX registers definitions diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index 1a7a027..7ab871c 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -32,11 +32,11 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" -#include "../buffer.h" -#include "../driver.h" +#include +#include +#include +#include +#include #include "max1363.h" diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c index 8372e98..b302013 100644 --- a/drivers/staging/iio/adc/max1363_ring.c +++ b/drivers/staging/iio/adc/max1363_ring.c @@ -14,10 +14,10 @@ #include #include -#include "../iio.h" -#include "../buffer.h" +#include +#include #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include #include "max1363.h" diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c index 3ca5cc9..2b4e1eb 100644 --- a/drivers/staging/iio/adc/spear_adc.c +++ b/drivers/staging/iio/adc/spear_adc.c @@ -19,8 +19,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include /* * SPEAR registers definitions diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c index fd6a454..f469ab3 100644 --- a/drivers/staging/iio/addac/adt7316.c +++ b/drivers/staging/iio/addac/adt7316.c @@ -19,9 +19,9 @@ #include #include -#include "../iio.h" -#include "../events.h" -#include "../sysfs.h" +#include +#include +#include #include "adt7316.h" /* diff --git a/drivers/staging/iio/buffer.h b/drivers/staging/iio/buffer.h deleted file mode 100644 index 3d3ea9e..0000000 --- a/drivers/staging/iio/buffer.h +++ /dev/null @@ -1,191 +0,0 @@ -/* The industrial I/O core - generic buffer interfaces. - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -#ifndef _IIO_BUFFER_GENERIC_H_ -#define _IIO_BUFFER_GENERIC_H_ -#include -#include "iio.h" - -#ifdef CONFIG_IIO_BUFFER - -struct iio_buffer; - -/** - * struct iio_buffer_access_funcs - access functions for buffers. - * @store_to: actually store stuff to the buffer - * @read_first_n: try to get a specified number of bytes (must exist) - * @request_update: if a parameter change has been marked, update underlying - * storage. - * @get_bytes_per_datum:get current bytes per datum - * @set_bytes_per_datum:set number of bytes per datum - * @get_length: get number of datums in buffer - * @set_length: set number of datums in buffer - * - * The purpose of this structure is to make the buffer element - * modular as event for a given driver, different usecases may require - * different buffer designs (space efficiency vs speed for example). - * - * It is worth noting that a given buffer implementation may only support a - * small proportion of these functions. The core code 'should' cope fine with - * any of them not existing. - **/ -struct iio_buffer_access_funcs { - int (*store_to)(struct iio_buffer *buffer, u8 *data, s64 timestamp); - int (*read_first_n)(struct iio_buffer *buffer, - size_t n, - char __user *buf); - - int (*request_update)(struct iio_buffer *buffer); - - int (*get_bytes_per_datum)(struct iio_buffer *buffer); - int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd); - int (*get_length)(struct iio_buffer *buffer); - int (*set_length)(struct iio_buffer *buffer, int length); -}; - -/** - * struct iio_buffer - general buffer structure - * @length: [DEVICE] number of datums in buffer - * @bytes_per_datum: [DEVICE] size of individual datum including timestamp - * @scan_el_attrs: [DRIVER] control of scan elements if that scan mode - * control method is used - * @scan_mask: [INTERN] bitmask used in masking scan mode elements - * @scan_timestamp: [INTERN] does the scan mode include a timestamp - * @access: [DRIVER] buffer access functions associated with the - * implementation. - * @scan_el_dev_attr_list:[INTERN] list of scan element related attributes. - * @scan_el_group: [DRIVER] attribute group for those attributes not - * created from the iio_chan_info array. - * @pollq: [INTERN] wait queue to allow for polling on the buffer. - * @stufftoread: [INTERN] flag to indicate new data. - * @demux_list: [INTERN] list of operations required to demux the scan. - * @demux_bounce: [INTERN] buffer for doing gather from incoming scan. - **/ -struct iio_buffer { - int length; - int bytes_per_datum; - struct attribute_group *scan_el_attrs; - long *scan_mask; - bool scan_timestamp; - const struct iio_buffer_access_funcs *access; - struct list_head scan_el_dev_attr_list; - struct attribute_group scan_el_group; - wait_queue_head_t pollq; - bool stufftoread; - const struct attribute_group *attrs; - struct list_head demux_list; - unsigned char *demux_bounce; -}; - -/** - * iio_buffer_init() - Initialize the buffer structure - * @buffer: buffer to be initialized - **/ -void iio_buffer_init(struct iio_buffer *buffer); - -/** - * __iio_update_buffer() - update common elements of buffers - * @buffer: buffer that is the event source - * @bytes_per_datum: size of individual datum including timestamp - * @length: number of datums in buffer - **/ -static inline void __iio_update_buffer(struct iio_buffer *buffer, - int bytes_per_datum, int length) -{ - buffer->bytes_per_datum = bytes_per_datum; - buffer->length = length; -} - -int iio_scan_mask_query(struct iio_dev *indio_dev, - struct iio_buffer *buffer, int bit); - -/** - * iio_scan_mask_set() - set particular bit in the scan mask - * @buffer: the buffer whose scan mask we are interested in - * @bit: the bit to be set. - **/ -int iio_scan_mask_set(struct iio_dev *indio_dev, - struct iio_buffer *buffer, int bit); - -/** - * iio_push_to_buffer() - push to a registered buffer. - * @buffer: IIO buffer structure for device - * @scan: Full scan. - * @timestamp: - */ -int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data, - s64 timestamp); - -int iio_update_demux(struct iio_dev *indio_dev); - -/** - * iio_buffer_register() - register the buffer with IIO core - * @indio_dev: device with the buffer to be registered - **/ -int iio_buffer_register(struct iio_dev *indio_dev, - const struct iio_chan_spec *channels, - int num_channels); - -/** - * iio_buffer_unregister() - unregister the buffer from IIO core - * @indio_dev: the device with the buffer to be unregistered - **/ -void iio_buffer_unregister(struct iio_dev *indio_dev); - -/** - * iio_buffer_read_length() - attr func to get number of datums in the buffer - **/ -ssize_t iio_buffer_read_length(struct device *dev, - struct device_attribute *attr, - char *buf); -/** - * iio_buffer_write_length() - attr func to set number of datums in the buffer - **/ -ssize_t iio_buffer_write_length(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len); -/** - * iio_buffer_store_enable() - attr to turn the buffer on - **/ -ssize_t iio_buffer_store_enable(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len); -/** - * iio_buffer_show_enable() - attr to see if the buffer is on - **/ -ssize_t iio_buffer_show_enable(struct device *dev, - struct device_attribute *attr, - char *buf); -#define IIO_BUFFER_LENGTH_ATTR DEVICE_ATTR(length, S_IRUGO | S_IWUSR, \ - iio_buffer_read_length, \ - iio_buffer_write_length) - -#define IIO_BUFFER_ENABLE_ATTR DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, \ - iio_buffer_show_enable, \ - iio_buffer_store_enable) - -int iio_sw_buffer_preenable(struct iio_dev *indio_dev); - -#else /* CONFIG_IIO_BUFFER */ - -static inline int iio_buffer_register(struct iio_dev *indio_dev, - struct iio_chan_spec *channels, - int num_channels) -{ - return 0; -} - -static inline void iio_buffer_unregister(struct iio_dev *indio_dev) -{}; - -#endif /* CONFIG_IIO_BUFFER */ - -#endif /* _IIO_BUFFER_GENERIC_H_ */ diff --git a/drivers/staging/iio/cdc/ad7150.c b/drivers/staging/iio/cdc/ad7150.c index 116e6c2..c0ccbc5 100644 --- a/drivers/staging/iio/cdc/ad7150.c +++ b/drivers/staging/iio/cdc/ad7150.c @@ -13,9 +13,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" +#include +#include +#include /* * AD7150 registers definition */ diff --git a/drivers/staging/iio/cdc/ad7152.c b/drivers/staging/iio/cdc/ad7152.c index 1067ce5..ea40359 100644 --- a/drivers/staging/iio/cdc/ad7152.c +++ b/drivers/staging/iio/cdc/ad7152.c @@ -15,8 +15,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include /* * TODO: Check compliance of calibbias with abi (units) diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c index 750bf4b..74a889a 100644 --- a/drivers/staging/iio/cdc/ad7746.c +++ b/drivers/staging/iio/cdc/ad7746.c @@ -16,8 +16,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #include "ad7746.h" diff --git a/drivers/staging/iio/consumer.h b/drivers/staging/iio/consumer.h deleted file mode 100644 index 36a060c..0000000 --- a/drivers/staging/iio/consumer.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Industrial I/O in kernel consumer interface - * - * Copyright (c) 2011 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ -#ifndef _IIO_INKERN_CONSUMER_H_ -#define _IIO_INKERN_CONSUMER_H -#include "types.h" - -struct iio_dev; -struct iio_chan_spec; - -/** - * struct iio_channel - everything needed for a consumer to use a channel - * @indio_dev: Device on which the channel exists. - * @channel: Full description of the channel. - */ -struct iio_channel { - struct iio_dev *indio_dev; - const struct iio_chan_spec *channel; -}; - -/** - * iio_channel_get() - get description of all that is needed to access channel. - * @name: Unique name of the device as provided in the iio_map - * with which the desired provider to consumer mapping - * was registered. - * @consumer_channel: Unique name to identify the channel on the consumer - * side. This typically describes the channels use within - * the consumer. E.g. 'battery_voltage' - */ -struct iio_channel *iio_st_channel_get(const char *name, - const char *consumer_channel); - -/** - * iio_st_channel_release() - release channels obtained via iio_st_channel_get - * @chan: The channel to be released. - */ -void iio_st_channel_release(struct iio_channel *chan); - -/** - * iio_st_channel_get_all() - get all channels associated with a client - * @name: name of consumer device. - * - * Returns an array of iio_channel structures terminated with one with - * null iio_dev pointer. - * This function is used by fairly generic consumers to get all the - * channels registered as having this consumer. - */ -struct iio_channel *iio_st_channel_get_all(const char *name); - -/** - * iio_st_channel_release_all() - reverse iio_st_get_all - * @chan: Array of channels to be released. - */ -void iio_st_channel_release_all(struct iio_channel *chan); - -/** - * iio_st_read_channel_raw() - read from a given channel - * @channel: The channel being queried. - * @val: Value read back. - * - * Note raw reads from iio channels are in adc counts and hence - * scale will need to be applied if standard units required. - */ -int iio_st_read_channel_raw(struct iio_channel *chan, - int *val); - -/** - * iio_st_get_channel_type() - get the type of a channel - * @channel: The channel being queried. - * @type: The type of the channel. - * - * returns the enum iio_chan_type of the channel - */ -int iio_st_get_channel_type(struct iio_channel *channel, - enum iio_chan_type *type); - -/** - * iio_st_read_channel_scale() - read the scale value for a channel - * @channel: The channel being queried. - * @val: First part of value read back. - * @val2: Second part of value read back. - * - * Note returns a description of what is in val and val2, such - * as IIO_VAL_INT_PLUS_MICRO telling us we have a value of val - * + val2/1e6 - */ -int iio_st_read_channel_scale(struct iio_channel *chan, int *val, - int *val2); - -#endif diff --git a/drivers/staging/iio/dac/ad5064.c b/drivers/staging/iio/dac/ad5064.c index 21893ed..c0fad4f 100644 --- a/drivers/staging/iio/dac/ad5064.c +++ b/drivers/staging/iio/dac/ad5064.c @@ -16,8 +16,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #include "dac.h" #define AD5064_MAX_DAC_CHANNELS 8 diff --git a/drivers/staging/iio/dac/ad5360.c b/drivers/staging/iio/dac/ad5360.c index cb6160d..0978dd2 100644 --- a/drivers/staging/iio/dac/ad5360.c +++ b/drivers/staging/iio/dac/ad5360.c @@ -16,8 +16,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #include "dac.h" #define AD5360_CMD(x) ((x) << 22) diff --git a/drivers/staging/iio/dac/ad5380.c b/drivers/staging/iio/dac/ad5380.c index 1d384f0..aa077e6 100644 --- a/drivers/staging/iio/dac/ad5380.c +++ b/drivers/staging/iio/dac/ad5380.c @@ -18,8 +18,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #include "dac.h" diff --git a/drivers/staging/iio/dac/ad5421.c b/drivers/staging/iio/dac/ad5421.c index a8b5211..b1a893c 100644 --- a/drivers/staging/iio/dac/ad5421.c +++ b/drivers/staging/iio/dac/ad5421.c @@ -16,9 +16,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" +#include +#include +#include #include "dac.h" #include "ad5421.h" diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index 00b138e..62ad1d5 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -18,8 +18,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #include "dac.h" #include "ad5446.h" diff --git a/drivers/staging/iio/dac/ad5504.c b/drivers/staging/iio/dac/ad5504.c index 796691e..18fc391 100644 --- a/drivers/staging/iio/dac/ad5504.c +++ b/drivers/staging/iio/dac/ad5504.c @@ -16,9 +16,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" +#include +#include +#include #include "dac.h" #include "ad5504.h" diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c index 74eb889..c7786c1 100644 --- a/drivers/staging/iio/dac/ad5624r_spi.c +++ b/drivers/staging/iio/dac/ad5624r_spi.c @@ -16,8 +16,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #include "dac.h" #include "ad5624r.h" diff --git a/drivers/staging/iio/dac/ad5686.c b/drivers/staging/iio/dac/ad5686.c index b8acd7e..86c8691 100644 --- a/drivers/staging/iio/dac/ad5686.c +++ b/drivers/staging/iio/dac/ad5686.c @@ -16,8 +16,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #include "dac.h" #define AD5686_DAC_CHANNELS 4 diff --git a/drivers/staging/iio/dac/ad5764.c b/drivers/staging/iio/dac/ad5764.c index 1c9ff4fc..b01d7ee 100644 --- a/drivers/staging/iio/dac/ad5764.c +++ b/drivers/staging/iio/dac/ad5764.c @@ -16,8 +16,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #include "dac.h" #define AD5764_REG_SF_NOP 0x0 diff --git a/drivers/staging/iio/dac/ad5791.c b/drivers/staging/iio/dac/ad5791.c index cdb7b10..c013868 100644 --- a/drivers/staging/iio/dac/ad5791.c +++ b/drivers/staging/iio/dac/ad5791.c @@ -17,8 +17,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #include "dac.h" #include "ad5791.h" diff --git a/drivers/staging/iio/dac/max517.c b/drivers/staging/iio/dac/max517.c index 41483c7..373127c 100644 --- a/drivers/staging/iio/dac/max517.c +++ b/drivers/staging/iio/dac/max517.c @@ -25,8 +25,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #include "dac.h" #include "max517.h" diff --git a/drivers/staging/iio/dds/ad5930.c b/drivers/staging/iio/dds/ad5930.c index 9c32d1b..6df4d86 100644 --- a/drivers/staging/iio/dds/ad5930.c +++ b/drivers/staging/iio/dds/ad5930.c @@ -16,8 +16,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #define DRV_NAME "ad5930" diff --git a/drivers/staging/iio/dds/ad9832.c b/drivers/staging/iio/dds/ad9832.c index 2ccf25d..57627ff 100644 --- a/drivers/staging/iio/dds/ad9832.c +++ b/drivers/staging/iio/dds/ad9832.c @@ -16,8 +16,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #include "dds.h" #include "ad9832.h" diff --git a/drivers/staging/iio/dds/ad9834.c b/drivers/staging/iio/dds/ad9834.c index 38a2de0..9b2c879 100644 --- a/drivers/staging/iio/dds/ad9834.c +++ b/drivers/staging/iio/dds/ad9834.c @@ -19,8 +19,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #include "dds.h" #include "ad9834.h" diff --git a/drivers/staging/iio/dds/ad9850.c b/drivers/staging/iio/dds/ad9850.c index f4f731b..cc7a87d 100644 --- a/drivers/staging/iio/dds/ad9850.c +++ b/drivers/staging/iio/dds/ad9850.c @@ -16,8 +16,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #define DRV_NAME "ad9850" diff --git a/drivers/staging/iio/dds/ad9852.c b/drivers/staging/iio/dds/ad9852.c index 554266c..2f8df7b 100644 --- a/drivers/staging/iio/dds/ad9852.c +++ b/drivers/staging/iio/dds/ad9852.c @@ -16,8 +16,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #define DRV_NAME "ad9852" diff --git a/drivers/staging/iio/dds/ad9910.c b/drivers/staging/iio/dds/ad9910.c index 3985766..e91efc5 100644 --- a/drivers/staging/iio/dds/ad9910.c +++ b/drivers/staging/iio/dds/ad9910.c @@ -16,8 +16,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #define DRV_NAME "ad9910" diff --git a/drivers/staging/iio/dds/ad9951.c b/drivers/staging/iio/dds/ad9951.c index 4d15004..ca1d311 100644 --- a/drivers/staging/iio/dds/ad9951.c +++ b/drivers/staging/iio/dds/ad9951.c @@ -16,8 +16,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #define DRV_NAME "ad9951" diff --git a/drivers/staging/iio/driver.h b/drivers/staging/iio/driver.h deleted file mode 100644 index a4f8b2e..0000000 --- a/drivers/staging/iio/driver.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Industrial I/O in kernel access map interface. - * - * Copyright (c) 2011 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -#ifndef _IIO_INKERN_H_ -#define _IIO_INKERN_H_ - -struct iio_map; - -/** - * iio_map_array_register() - tell the core about inkernel consumers - * @indio_dev: provider device - * @map: array of mappings specifying association of channel with client - */ -int iio_map_array_register(struct iio_dev *indio_dev, - struct iio_map *map); - -/** - * iio_map_array_unregister() - tell the core to remove consumer mappings - * @indio_dev: provider device - * @map: array of mappings to remove. Note these must have same memory - * addresses as those originally added not just equal parameter - * values. - */ -int iio_map_array_unregister(struct iio_dev *indio_dev, - struct iio_map *map); - -#endif diff --git a/drivers/staging/iio/events.h b/drivers/staging/iio/events.h deleted file mode 100644 index c25f0e3..0000000 --- a/drivers/staging/iio/events.h +++ /dev/null @@ -1,105 +0,0 @@ -/* The industrial I/O - event passing to userspace - * - * Copyright (c) 2008-2011 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ -#ifndef _IIO_EVENTS_H_ -#define _IIO_EVENTS_H_ - -#include -#include -#include "types.h" - -/** - * struct iio_event_data - The actual event being pushed to userspace - * @id: event identifier - * @timestamp: best estimate of time of event occurrence (often from - * the interrupt handler) - */ -struct iio_event_data { - __u64 id; - __s64 timestamp; -}; - -#define IIO_GET_EVENT_FD_IOCTL _IOR('i', 0x90, int) - -enum iio_event_type { - IIO_EV_TYPE_THRESH, - IIO_EV_TYPE_MAG, - IIO_EV_TYPE_ROC, - IIO_EV_TYPE_THRESH_ADAPTIVE, - IIO_EV_TYPE_MAG_ADAPTIVE, -}; - -enum iio_event_direction { - IIO_EV_DIR_EITHER, - IIO_EV_DIR_RISING, - IIO_EV_DIR_FALLING, -}; - -/** - * IIO_EVENT_CODE() - create event identifier - * @chan_type: Type of the channel. Should be one of enum iio_chan_type. - * @diff: Whether the event is for an differential channel or not. - * @modifier: Modifier for the channel. Should be one of enum iio_modifier. - * @direction: Direction of the event. One of enum iio_event_direction. - * @type: Type of the event. Should be one enum iio_event_type. - * @chan: Channel number for non-differential channels. - * @chan1: First channel number for differential channels. - * @chan2: Second channel number for differential channels. - */ - -#define IIO_EVENT_CODE(chan_type, diff, modifier, direction, \ - type, chan, chan1, chan2) \ - (((u64)type << 56) | ((u64)diff << 55) | \ - ((u64)direction << 48) | ((u64)modifier << 40) | \ - ((u64)chan_type << 32) | (((u16)chan2) << 16) | ((u16)chan1) | \ - ((u16)chan)) - - -#define IIO_EV_DIR_MAX 4 -#define IIO_EV_BIT(type, direction) \ - (1 << (type*IIO_EV_DIR_MAX + direction)) - -/** - * IIO_MOD_EVENT_CODE() - create event identifier for modified channels - * @chan_type: Type of the channel. Should be one of enum iio_chan_type. - * @number: Channel number. - * @modifier: Modifier for the channel. Should be one of enum iio_modifier. - * @type: Type of the event. Should be one enum iio_event_type. - * @direction: Direction of the event. One of enum iio_event_direction. - */ - -#define IIO_MOD_EVENT_CODE(chan_type, number, modifier, \ - type, direction) \ - IIO_EVENT_CODE(chan_type, 0, modifier, direction, type, number, 0, 0) - -/** - * IIO_UNMOD_EVENT_CODE() - create event identifier for unmodified channels - * @chan_type: Type of the channel. Should be one of enum iio_chan_type. - * @number: Channel number. - * @type: Type of the event. Should be one enum iio_event_type. - * @direction: Direction of the event. One of enum iio_event_direction. - */ - -#define IIO_UNMOD_EVENT_CODE(chan_type, number, type, direction) \ - IIO_EVENT_CODE(chan_type, 0, 0, direction, type, number, 0, 0) - -#define IIO_EVENT_CODE_EXTRACT_TYPE(mask) ((mask >> 56) & 0xFF) - -#define IIO_EVENT_CODE_EXTRACT_DIR(mask) ((mask >> 48) & 0xCF) - -#define IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(mask) ((mask >> 32) & 0xFF) - -/* Event code number extraction depends on which type of event we have. - * Perhaps review this function in the future*/ -#define IIO_EVENT_CODE_EXTRACT_CHAN(mask) ((__s16)(mask & 0xFFFF)) -#define IIO_EVENT_CODE_EXTRACT_CHAN2(mask) ((__s16)(((mask) >> 16) & 0xFFFF)) - -#define IIO_EVENT_CODE_EXTRACT_MODIFIER(mask) ((mask >> 40) & 0xFF) -#define IIO_EVENT_CODE_EXTRACT_DIFF(mask) (((mask) >> 55) & 0x1) - -#endif diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c index 2f841cb..08aaf27 100644 --- a/drivers/staging/iio/gyro/adis16060_core.c +++ b/drivers/staging/iio/gyro/adis16060_core.c @@ -15,8 +15,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #define ADIS16060_GYRO 0x20 /* Measure Angular Rate (Gyro) */ #define ADIS16060_TEMP_OUT 0x10 /* Measure Temperature */ diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c index 608b93d..7e3695b 100644 --- a/drivers/staging/iio/gyro/adis16080_core.c +++ b/drivers/staging/iio/gyro/adis16080_core.c @@ -14,8 +14,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #define ADIS16080_DIN_GYRO (0 << 10) /* Gyroscope output */ #define ADIS16080_DIN_TEMP (1 << 10) /* Temperature output */ diff --git a/drivers/staging/iio/gyro/adis16130_core.c b/drivers/staging/iio/gyro/adis16130_core.c index 257bdf2..98aa1b9 100644 --- a/drivers/staging/iio/gyro/adis16130_core.c +++ b/drivers/staging/iio/gyro/adis16130_core.c @@ -16,8 +16,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #define ADIS16130_CON 0x0 #define ADIS16130_CON_RD (1 << 6) diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index bb23018..15253be 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -18,9 +18,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include +#include +#include #include "adis16260.h" diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c index 046f84d..2528337 100644 --- a/drivers/staging/iio/gyro/adis16260_ring.c +++ b/drivers/staging/iio/gyro/adis16260_ring.c @@ -5,9 +5,9 @@ #include #include -#include "../iio.h" +#include #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include #include "adis16260.h" /** diff --git a/drivers/staging/iio/gyro/adis16260_trigger.c b/drivers/staging/iio/gyro/adis16260_trigger.c index 8299cd1..dc56f32 100644 --- a/drivers/staging/iio/gyro/adis16260_trigger.c +++ b/drivers/staging/iio/gyro/adis16260_trigger.c @@ -3,8 +3,8 @@ #include #include -#include "../iio.h" -#include "../trigger.h" +#include +#include #include "adis16260.h" /** diff --git a/drivers/staging/iio/gyro/adxrs450_core.c b/drivers/staging/iio/gyro/adxrs450_core.c index 1293505..06a9e97 100644 --- a/drivers/staging/iio/gyro/adxrs450_core.c +++ b/drivers/staging/iio/gyro/adxrs450_core.c @@ -18,8 +18,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #include "adxrs450.h" diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h deleted file mode 100644 index 0770340..0000000 --- a/drivers/staging/iio/iio.h +++ /dev/null @@ -1,463 +0,0 @@ - -/* The industrial I/O core - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ -#ifndef _INDUSTRIAL_IO_H_ -#define _INDUSTRIAL_IO_H_ - -#include -#include -#include "types.h" -/* IIO TODO LIST */ -/* - * Provide means of adjusting timer accuracy. - * Currently assumes nano seconds. - */ - -enum iio_chan_info_enum { - IIO_CHAN_INFO_RAW = 0, - IIO_CHAN_INFO_PROCESSED, - IIO_CHAN_INFO_SCALE, - IIO_CHAN_INFO_OFFSET, - IIO_CHAN_INFO_CALIBSCALE, - IIO_CHAN_INFO_CALIBBIAS, - IIO_CHAN_INFO_PEAK, - IIO_CHAN_INFO_PEAK_SCALE, - IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW, - IIO_CHAN_INFO_AVERAGE_RAW, - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY, - IIO_CHAN_INFO_SAMP_FREQ, -}; - -#define IIO_CHAN_INFO_SHARED_BIT(type) BIT(type*2) -#define IIO_CHAN_INFO_SEPARATE_BIT(type) BIT(type*2 + 1) - -#define IIO_CHAN_INFO_RAW_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_RAW) -#define IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_PROCESSED) -#define IIO_CHAN_INFO_SCALE_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_SCALE) -#define IIO_CHAN_INFO_SCALE_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_SCALE) -#define IIO_CHAN_INFO_OFFSET_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_OFFSET) -#define IIO_CHAN_INFO_OFFSET_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_OFFSET) -#define IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_CALIBSCALE) -#define IIO_CHAN_INFO_CALIBSCALE_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_CALIBSCALE) -#define IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_CALIBBIAS) -#define IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_CALIBBIAS) -#define IIO_CHAN_INFO_PEAK_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_PEAK) -#define IIO_CHAN_INFO_PEAK_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_PEAK) -#define IIO_CHAN_INFO_PEAKSCALE_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_PEAKSCALE) -#define IIO_CHAN_INFO_PEAKSCALE_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_PEAKSCALE) -#define IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT( \ - IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW) -#define IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT( \ - IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW) -#define IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_AVERAGE_RAW) -#define IIO_CHAN_INFO_AVERAGE_RAW_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_AVERAGE_RAW) -#define IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT( \ - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) -#define IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT( \ - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) -#define IIO_CHAN_INFO_SAMP_FREQ_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_SAMP_FREQ) -#define IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_SAMP_FREQ) - -enum iio_endian { - IIO_CPU, - IIO_BE, - IIO_LE, -}; - -struct iio_chan_spec; -struct iio_dev; - -/** - * struct iio_chan_spec_ext_info - Extended channel info attribute - * @name: Info attribute name - * @shared: Whether this attribute is shared between all channels. - * @read: Read callback for this info attribute, may be NULL. - * @write: Write callback for this info attribute, may be NULL. - */ -struct iio_chan_spec_ext_info { - const char *name; - bool shared; - ssize_t (*read)(struct iio_dev *, struct iio_chan_spec const *, - char *buf); - ssize_t (*write)(struct iio_dev *, struct iio_chan_spec const *, - const char *buf, size_t len); -}; - -/** - * struct iio_chan_spec - specification of a single channel - * @type: What type of measurement is the channel making. - * @channel: What number or name do we wish to assign the channel. - * @channel2: If there is a second number for a differential - * channel then this is it. If modified is set then the - * value here specifies the modifier. - * @address: Driver specific identifier. - * @scan_index: Monotonic index to give ordering in scans when read - * from a buffer. - * @scan_type: Sign: 's' or 'u' to specify signed or unsigned - * realbits: Number of valid bits of data - * storage_bits: Realbits + padding - * shift: Shift right by this before masking out - * realbits. - * endianness: little or big endian - * @info_mask: What information is to be exported about this channel. - * This includes calibbias, scale etc. - * @event_mask: What events can this channel produce. - * @ext_info: Array of extended info attributes for this channel. - * The array is NULL terminated, the last element should - * have it's name field set to NULL. - * @extend_name: Allows labeling of channel attributes with an - * informative name. Note this has no effect codes etc, - * unlike modifiers. - * @datasheet_name: A name used in in kernel mapping of channels. It should - * correspond to the first name that the channel is referred - * to by in the datasheet (e.g. IND), or the nearest - * possible compound name (e.g. IND-INC). - * @modified: Does a modifier apply to this channel. What these are - * depends on the channel type. Modifier is set in - * channel2. Examples are IIO_MOD_X for axial sensors about - * the 'x' axis. - * @indexed: Specify the channel has a numerical index. If not, - * the value in channel will be suppressed for attribute - * but not for event codes. Typically set it to 0 when - * the index is false. - * @differential: Channel is differential. - */ -struct iio_chan_spec { - enum iio_chan_type type; - int channel; - int channel2; - unsigned long address; - int scan_index; - struct { - char sign; - u8 realbits; - u8 storagebits; - u8 shift; - enum iio_endian endianness; - } scan_type; - long info_mask; - long event_mask; - const struct iio_chan_spec_ext_info *ext_info; - const char *extend_name; - const char *datasheet_name; - unsigned modified:1; - unsigned indexed:1; - unsigned output:1; - unsigned differential:1; -}; - -#define IIO_ST(si, rb, sb, sh) \ - { .sign = si, .realbits = rb, .storagebits = sb, .shift = sh } - -#define IIO_CHAN_SOFT_TIMESTAMP(_si) \ - { .type = IIO_TIMESTAMP, .channel = -1, \ - .scan_index = _si, .scan_type = IIO_ST('s', 64, 64, 0) } - -/** - * iio_get_time_ns() - utility function to get a time stamp for events etc - **/ -static inline s64 iio_get_time_ns(void) -{ - struct timespec ts; - /* - * calls getnstimeofday. - * If hrtimers then up to ns accurate, if not microsecond. - */ - ktime_get_real_ts(&ts); - - return timespec_to_ns(&ts); -} - -/* Device operating modes */ -#define INDIO_DIRECT_MODE 0x01 -#define INDIO_BUFFER_TRIGGERED 0x02 -#define INDIO_BUFFER_HARDWARE 0x08 - -#define INDIO_ALL_BUFFER_MODES \ - (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE) - -struct iio_trigger; /* forward declaration */ -struct iio_dev; - -/** - * struct iio_info - constant information about device - * @driver_module: module structure used to ensure correct - * ownership of chrdevs etc - * @event_attrs: event control attributes - * @attrs: general purpose device attributes - * @read_raw: function to request a value from the device. - * mask specifies which value. Note 0 means a reading of - * the channel in question. Return value will specify the - * type of value returned by the device. val and val2 will - * contain the elements making up the returned value. - * @write_raw: function to write a value to the device. - * Parameters are the same as for read_raw. - * @write_raw_get_fmt: callback function to query the expected - * format/precision. If not set by the driver, write_raw - * returns IIO_VAL_INT_PLUS_MICRO. - * @read_event_config: find out if the event is enabled. - * @write_event_config: set if the event is enabled. - * @read_event_value: read a value associated with the event. Meaning - * is event dependant. event_code specifies which event. - * @write_event_value: write the value associated with the event. - * Meaning is event dependent. - * @validate_trigger: function to validate the trigger when the - * current trigger gets changed. - **/ -struct iio_info { - struct module *driver_module; - struct attribute_group *event_attrs; - const struct attribute_group *attrs; - - int (*read_raw)(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, - int *val2, - long mask); - - int (*write_raw)(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int val, - int val2, - long mask); - - int (*write_raw_get_fmt)(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - long mask); - - int (*read_event_config)(struct iio_dev *indio_dev, - u64 event_code); - - int (*write_event_config)(struct iio_dev *indio_dev, - u64 event_code, - int state); - - int (*read_event_value)(struct iio_dev *indio_dev, - u64 event_code, - int *val); - int (*write_event_value)(struct iio_dev *indio_dev, - u64 event_code, - int val); - int (*validate_trigger)(struct iio_dev *indio_dev, - struct iio_trigger *trig); - int (*update_scan_mode)(struct iio_dev *indio_dev, - const unsigned long *scan_mask); - int (*debugfs_reg_access)(struct iio_dev *indio_dev, - unsigned reg, unsigned writeval, - unsigned *readval); -}; - -/** - * struct iio_buffer_setup_ops - buffer setup related callbacks - * @preenable: [DRIVER] function to run prior to marking buffer enabled - * @postenable: [DRIVER] function to run after marking buffer enabled - * @predisable: [DRIVER] function to run prior to marking buffer - * disabled - * @postdisable: [DRIVER] function to run after marking buffer disabled - */ -struct iio_buffer_setup_ops { - int (*preenable)(struct iio_dev *); - int (*postenable)(struct iio_dev *); - int (*predisable)(struct iio_dev *); - int (*postdisable)(struct iio_dev *); -}; - -/** - * struct iio_dev - industrial I/O device - * @id: [INTERN] used to identify device internally - * @modes: [DRIVER] operating modes supported by device - * @currentmode: [DRIVER] current operating mode - * @dev: [DRIVER] device structure, should be assigned a parent - * and owner - * @event_interface: [INTERN] event chrdevs associated with interrupt lines - * @buffer: [DRIVER] any buffer present - * @scan_bytes: [INTERN] num bytes captured to be fed to buffer demux - * @mlock: [INTERN] lock used to prevent simultaneous device state - * changes - * @available_scan_masks: [DRIVER] optional array of allowed bitmasks - * @masklength: [INTERN] the length of the mask established from - * channels - * @active_scan_mask: [INTERN] union of all scan masks requested by buffers - * @scan_timestamp: [INTERN] set if any buffers have requested timestamp - * @scan_index_timestamp:[INTERN] cache of the index to the timestamp - * @trig: [INTERN] current device trigger (buffer modes) - * @pollfunc: [DRIVER] function run on trigger being received - * @channels: [DRIVER] channel specification structure table - * @num_channels: [DRIVER] number of chanels specified in @channels. - * @channel_attr_list: [INTERN] keep track of automatically created channel - * attributes - * @chan_attr_group: [INTERN] group for all attrs in base directory - * @name: [DRIVER] name of the device. - * @info: [DRIVER] callbacks and constant info from driver - * @info_exist_lock: [INTERN] lock to prevent use during removal - * @setup_ops: [DRIVER] callbacks to call before and after buffer - * enable/disable - * @chrdev: [INTERN] associated character device - * @groups: [INTERN] attribute groups - * @groupcounter: [INTERN] index of next attribute group - * @flags: [INTERN] file ops related flags including busy flag. - * @debugfs_dentry: [INTERN] device specific debugfs dentry. - * @cached_reg_addr: [INTERN] cached register address for debugfs reads. - */ -struct iio_dev { - int id; - - int modes; - int currentmode; - struct device dev; - - struct iio_event_interface *event_interface; - - struct iio_buffer *buffer; - int scan_bytes; - struct mutex mlock; - - const unsigned long *available_scan_masks; - unsigned masklength; - const unsigned long *active_scan_mask; - bool scan_timestamp; - unsigned scan_index_timestamp; - struct iio_trigger *trig; - struct iio_poll_func *pollfunc; - - struct iio_chan_spec const *channels; - int num_channels; - - struct list_head channel_attr_list; - struct attribute_group chan_attr_group; - const char *name; - const struct iio_info *info; - struct mutex info_exist_lock; - const struct iio_buffer_setup_ops *setup_ops; - struct cdev chrdev; -#define IIO_MAX_GROUPS 6 - const struct attribute_group *groups[IIO_MAX_GROUPS + 1]; - int groupcounter; - - unsigned long flags; -#if defined(CONFIG_DEBUG_FS) - struct dentry *debugfs_dentry; - unsigned cached_reg_addr; -#endif -}; - -/** - * iio_find_channel_from_si() - get channel from its scan index - * @indio_dev: device - * @si: scan index to match - */ -const struct iio_chan_spec -*iio_find_channel_from_si(struct iio_dev *indio_dev, int si); - -/** - * iio_device_register() - register a device with the IIO subsystem - * @indio_dev: Device structure filled by the device driver - **/ -int iio_device_register(struct iio_dev *indio_dev); - -/** - * iio_device_unregister() - unregister a device from the IIO subsystem - * @indio_dev: Device structure representing the device. - **/ -void iio_device_unregister(struct iio_dev *indio_dev); - -/** - * iio_push_event() - try to add event to the list for userspace reading - * @indio_dev: IIO device structure - * @ev_code: What event - * @timestamp: When the event occurred - **/ -int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp); - -extern struct bus_type iio_bus_type; - -/** - * iio_put_device() - reference counted deallocation of struct device - * @dev: the iio_device containing the device - **/ -static inline void iio_put_device(struct iio_dev *indio_dev) -{ - if (indio_dev) - put_device(&indio_dev->dev); -}; - -/* Can we make this smaller? */ -#define IIO_ALIGN L1_CACHE_BYTES -/** - * iio_allocate_device() - allocate an iio_dev from a driver - * @sizeof_priv: Space to allocate for private structure. - **/ -struct iio_dev *iio_allocate_device(int sizeof_priv); - -static inline void *iio_priv(const struct iio_dev *indio_dev) -{ - return (char *)indio_dev + ALIGN(sizeof(struct iio_dev), IIO_ALIGN); -} - -static inline struct iio_dev *iio_priv_to_dev(void *priv) -{ - return (struct iio_dev *)((char *)priv - - ALIGN(sizeof(struct iio_dev), IIO_ALIGN)); -} - -/** - * iio_free_device() - free an iio_dev from a driver - * @dev: the iio_dev associated with the device - **/ -void iio_free_device(struct iio_dev *indio_dev); - -/** - * iio_buffer_enabled() - helper function to test if the buffer is enabled - * @indio_dev: IIO device info structure for device - **/ -static inline bool iio_buffer_enabled(struct iio_dev *indio_dev) -{ - return indio_dev->currentmode - & (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE); -}; - -/** - * iio_get_debugfs_dentry() - helper function to get the debugfs_dentry - * @indio_dev: IIO device info structure for device - **/ -#if defined(CONFIG_DEBUG_FS) -static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev) -{ - return indio_dev->debugfs_dentry; -}; -#else -static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev) -{ - return NULL; -}; -#endif - -#endif /* _INDUSTRIAL_IO_H_ */ diff --git a/drivers/staging/iio/iio_dummy_evgen.c b/drivers/staging/iio/iio_dummy_evgen.c index f39f346..0cd4fe9 100644 --- a/drivers/staging/iio/iio_dummy_evgen.c +++ b/drivers/staging/iio/iio_dummy_evgen.c @@ -22,8 +22,8 @@ #include #include "iio_dummy_evgen.h" -#include "iio.h" -#include "sysfs.h" +#include +#include /* Fiddly bit of faking and irq without hardware */ #define IIO_EVENTGEN_NO 10 diff --git a/drivers/staging/iio/iio_hwmon.c b/drivers/staging/iio/iio_hwmon.c index a603a5f..b03554f 100644 --- a/drivers/staging/iio/iio_hwmon.c +++ b/drivers/staging/iio/iio_hwmon.c @@ -14,8 +14,8 @@ #include #include #include -#include "consumer.h" -#include "types.h" +#include +#include /** * struct iio_hwmon_state - device instance state diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c index dbeb04c..fa4a653 100644 --- a/drivers/staging/iio/iio_simple_dummy.c +++ b/drivers/staging/iio/iio_simple_dummy.c @@ -19,10 +19,10 @@ #include #include -#include "iio.h" -#include "sysfs.h" -#include "events.h" -#include "buffer.h" +#include +#include +#include +#include #include "iio_simple_dummy.h" /* diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c index 49e7aa1..3726065 100644 --- a/drivers/staging/iio/iio_simple_dummy_buffer.c +++ b/drivers/staging/iio/iio_simple_dummy_buffer.c @@ -18,9 +18,9 @@ #include #include -#include "iio.h" -#include "trigger_consumer.h" -#include "kfifo_buf.h" +#include +#include +#include #include "iio_simple_dummy.h" diff --git a/drivers/staging/iio/iio_simple_dummy_events.c b/drivers/staging/iio/iio_simple_dummy_events.c index 449c7a5..f85bd19 100644 --- a/drivers/staging/iio/iio_simple_dummy_events.c +++ b/drivers/staging/iio/iio_simple_dummy_events.c @@ -12,9 +12,9 @@ #include #include -#include "iio.h" -#include "sysfs.h" -#include "events.h" +#include +#include +#include #include "iio_simple_dummy.h" /* Evgen 'fakes' interrupt events for this example */ diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 8a0485e..9d99a7f 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -19,9 +19,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include +#include +#include #include "../ring_sw.h" #include "ad5933.h" diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index 58a150c..68ecc15 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -26,9 +26,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include +#include +#include #include "adis16400.h" enum adis16400_chip_variant { diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c index d964004..e43c0e2 100644 --- a/drivers/staging/iio/imu/adis16400_ring.c +++ b/drivers/staging/iio/imu/adis16400_ring.c @@ -6,9 +6,9 @@ #include #include -#include "../iio.h" +#include #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include #include "adis16400.h" /** diff --git a/drivers/staging/iio/imu/adis16400_trigger.c b/drivers/staging/iio/imu/adis16400_trigger.c index 5bf0007..bd22e6c 100644 --- a/drivers/staging/iio/imu/adis16400_trigger.c +++ b/drivers/staging/iio/imu/adis16400_trigger.c @@ -3,8 +3,8 @@ #include #include -#include "../iio.h" -#include "../trigger.h" +#include +#include #include "adis16400.h" /** diff --git a/drivers/staging/iio/industrialio-buffer.c b/drivers/staging/iio/industrialio-buffer.c index b409b95..b5b2c38 100644 --- a/drivers/staging/iio/industrialio-buffer.c +++ b/drivers/staging/iio/industrialio-buffer.c @@ -21,10 +21,10 @@ #include #include -#include "iio.h" +#include #include "iio_core.h" -#include "sysfs.h" -#include "buffer.h" +#include +#include static const char * const iio_endian_prefix[] = { [IIO_BE] = "be", diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index db55b81..dd1a6a2 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c @@ -23,11 +23,11 @@ #include #include #include -#include "iio.h" +#include #include "iio_core.h" #include "iio_core_trigger.h" -#include "sysfs.h" -#include "events.h" +#include +#include /* IDA to assign each registered device a unique id*/ static DEFINE_IDA(iio_ida); diff --git a/drivers/staging/iio/industrialio-event.c b/drivers/staging/iio/industrialio-event.c index 5fdf739..5fcf50b 100644 --- a/drivers/staging/iio/industrialio-event.c +++ b/drivers/staging/iio/industrialio-event.c @@ -20,10 +20,10 @@ #include #include #include -#include "iio.h" +#include #include "iio_core.h" -#include "sysfs.h" -#include "events.h" +#include +#include /** * struct iio_event_interface - chrdev interface for an event line diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c index 47ecadd..03fee2e 100644 --- a/drivers/staging/iio/industrialio-trigger.c +++ b/drivers/staging/iio/industrialio-trigger.c @@ -15,11 +15,11 @@ #include #include -#include "iio.h" -#include "trigger.h" +#include +#include #include "iio_core.h" #include "iio_core_trigger.h" -#include "trigger_consumer.h" +#include /* RFC - Question of approach * Make the common case (single sensor single trigger) diff --git a/drivers/staging/iio/inkern.c b/drivers/staging/iio/inkern.c index de2c8ea..22ddf62 100644 --- a/drivers/staging/iio/inkern.c +++ b/drivers/staging/iio/inkern.c @@ -11,11 +11,11 @@ #include #include -#include "iio.h" +#include #include "iio_core.h" -#include "machine.h" -#include "driver.h" -#include "consumer.h" +#include +#include +#include struct iio_map_internal { struct iio_dev *indio_dev; diff --git a/drivers/staging/iio/kfifo_buf.c b/drivers/staging/iio/kfifo_buf.c index 9f3bd59..6bf9d05 100644 --- a/drivers/staging/iio/kfifo_buf.c +++ b/drivers/staging/iio/kfifo_buf.c @@ -5,8 +5,7 @@ #include #include #include - -#include "kfifo_buf.h" +#include struct iio_kfifo { struct iio_buffer buffer; diff --git a/drivers/staging/iio/kfifo_buf.h b/drivers/staging/iio/kfifo_buf.h deleted file mode 100644 index 9f7da01..0000000 --- a/drivers/staging/iio/kfifo_buf.h +++ /dev/null @@ -1,8 +0,0 @@ - -#include -#include "iio.h" -#include "buffer.h" - -struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev); -void iio_kfifo_free(struct iio_buffer *r); - diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index 2c894a6..92283eb 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -28,8 +28,8 @@ #include #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #define CONVERSION_TIME_MS 100 diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c index 7057d9b..2ada20e 100644 --- a/drivers/staging/iio/light/isl29028.c +++ b/drivers/staging/iio/light/isl29028.c @@ -24,8 +24,8 @@ #include #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #define CONVERSION_TIME_MS 100 diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c index a1e5cbe..6351360 100644 --- a/drivers/staging/iio/light/tsl2563.c +++ b/drivers/staging/iio/light/tsl2563.c @@ -35,9 +35,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" +#include +#include +#include #include "tsl2563.h" /* Use this many bits for fraction part. */ diff --git a/drivers/staging/iio/light/tsl2583.c b/drivers/staging/iio/light/tsl2583.c index 8671d98..51b6362 100644 --- a/drivers/staging/iio/light/tsl2583.c +++ b/drivers/staging/iio/light/tsl2583.c @@ -28,7 +28,7 @@ #include #include #include -#include "../iio.h" +#include #define TSL258X_MAX_DEVICE_REGS 32 diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c index f3fc85a..dfc3da6 100755 --- a/drivers/staging/iio/light/tsl2x7x_core.c +++ b/drivers/staging/iio/light/tsl2x7x_core.c @@ -28,10 +28,10 @@ #include #include #include +#include +#include +#include #include "tsl2x7x.h" -#include "../events.h" -#include "../iio.h" -#include "../sysfs.h" /* Cal defs*/ #define PROX_STAT_CAL 0 diff --git a/drivers/staging/iio/machine.h b/drivers/staging/iio/machine.h deleted file mode 100644 index 0b1f19b..0000000 --- a/drivers/staging/iio/machine.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Industrial I/O in kernel access map definitions for board files. - * - * Copyright (c) 2011 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -/** - * struct iio_map - description of link between consumer and device channels - * @adc_channel_label: Label used to identify the channel on the provider. - * This is matched against the datasheet_name element - * of struct iio_chan_spec. - * @consumer_dev_name: Name to uniquely identify the consumer device. - * @consumer_channel: Unique name used to idenitify the channel on the - * consumer side. - */ -struct iio_map { - const char *adc_channel_label; - const char *consumer_dev_name; - const char *consumer_channel; -}; diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c index 000886f..d088548c 100644 --- a/drivers/staging/iio/magnetometer/ak8975.c +++ b/drivers/staging/iio/magnetometer/ak8975.c @@ -30,8 +30,8 @@ #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include /* * Register definitions, as well as various shifts and masks to get at the * individual fields of the registers. diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c index 27c2629..3433c41 100644 --- a/drivers/staging/iio/magnetometer/hmc5843.c +++ b/drivers/staging/iio/magnetometer/hmc5843.c @@ -22,8 +22,8 @@ #include #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #define HMC5843_I2C_ADDRESS 0x1E diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c index 57baac6..9b26ae1 100644 --- a/drivers/staging/iio/meter/ade7753.c +++ b/drivers/staging/iio/meter/ade7753.c @@ -18,8 +18,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #include "meter.h" #include "ade7753.h" diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index 8d81c920..02d10df 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c @@ -18,8 +18,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #include "meter.h" #include "ade7754.h" diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c index 729c033..4a3b429 100644 --- a/drivers/staging/iio/meter/ade7758_core.c +++ b/drivers/staging/iio/meter/ade7758_core.c @@ -18,9 +18,9 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include +#include +#include #include "meter.h" #include "ade7758.h" diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c index b37bc98..7b9be8a 100644 --- a/drivers/staging/iio/meter/ade7758_ring.c +++ b/drivers/staging/iio/meter/ade7758_ring.c @@ -12,9 +12,9 @@ #include #include -#include "../iio.h" +#include #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include #include "ade7758.h" /** diff --git a/drivers/staging/iio/meter/ade7758_trigger.c b/drivers/staging/iio/meter/ade7758_trigger.c index b6569c7..5c48d38 100644 --- a/drivers/staging/iio/meter/ade7758_trigger.c +++ b/drivers/staging/iio/meter/ade7758_trigger.c @@ -11,8 +11,8 @@ #include #include -#include "../iio.h" -#include "../trigger.h" +#include +#include #include "ade7758.h" /** diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index 0beab47..1f2b74a 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c @@ -18,8 +18,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #include "meter.h" #include "ade7759.h" diff --git a/drivers/staging/iio/meter/ade7854-i2c.c b/drivers/staging/iio/meter/ade7854-i2c.c index 1e1faa0..c87c86b 100644 --- a/drivers/staging/iio/meter/ade7854-i2c.c +++ b/drivers/staging/iio/meter/ade7854-i2c.c @@ -12,7 +12,7 @@ #include #include -#include "../iio.h" +#include #include "ade7854.h" static int ade7854_i2c_write_reg_8(struct device *dev, diff --git a/drivers/staging/iio/meter/ade7854-spi.c b/drivers/staging/iio/meter/ade7854-spi.c index 8112186..11c2cef 100644 --- a/drivers/staging/iio/meter/ade7854-spi.c +++ b/drivers/staging/iio/meter/ade7854-spi.c @@ -12,7 +12,7 @@ #include #include -#include "../iio.h" +#include #include "ade7854.h" static int ade7854_spi_write_reg_8(struct device *dev, diff --git a/drivers/staging/iio/meter/ade7854.c b/drivers/staging/iio/meter/ade7854.c index 49c01c5..2f3c1e2 100644 --- a/drivers/staging/iio/meter/ade7854.c +++ b/drivers/staging/iio/meter/ade7854.c @@ -17,8 +17,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #include "meter.h" #include "ade7854.h" diff --git a/drivers/staging/iio/meter/meter.h b/drivers/staging/iio/meter/meter.h index 6a3db14..23e1b5f4 100644 --- a/drivers/staging/iio/meter/meter.h +++ b/drivers/staging/iio/meter/meter.h @@ -1,4 +1,4 @@ -#include "../sysfs.h" +#include /* metering ic types of attribute */ diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index 0465e5d..48e70e9 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -19,8 +19,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #define DRV_NAME "ad2s1200" diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c index c6ced16..4d580e2 100644 --- a/drivers/staging/iio/resolver/ad2s1210.c +++ b/drivers/staging/iio/resolver/ad2s1210.c @@ -18,8 +18,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include #include "ad2s1210.h" #define DRV_NAME "ad2s1210" diff --git a/drivers/staging/iio/resolver/ad2s90.c b/drivers/staging/iio/resolver/ad2s90.c index 20ca529..cb68910 100644 --- a/drivers/staging/iio/resolver/ad2s90.c +++ b/drivers/staging/iio/resolver/ad2s90.c @@ -16,8 +16,8 @@ #include #include -#include "../iio.h" -#include "../sysfs.h" +#include +#include struct ad2s90_state { struct mutex lock; diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c index b9945ec..9358c6c 100644 --- a/drivers/staging/iio/ring_sw.c +++ b/drivers/staging/iio/ring_sw.c @@ -15,7 +15,7 @@ #include #include #include "ring_sw.h" -#include "trigger.h" +#include /** * struct iio_sw_ring_buffer - software ring buffer diff --git a/drivers/staging/iio/ring_sw.h b/drivers/staging/iio/ring_sw.h index 7556e21..a5857aa 100644 --- a/drivers/staging/iio/ring_sw.h +++ b/drivers/staging/iio/ring_sw.h @@ -23,7 +23,7 @@ #ifndef _IIO_RING_SW_H_ #define _IIO_RING_SW_H_ -#include "buffer.h" +#include struct iio_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev); void iio_sw_rb_free(struct iio_buffer *ring); diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h deleted file mode 100644 index bfedb73..0000000 --- a/drivers/staging/iio/sysfs.h +++ /dev/null @@ -1,117 +0,0 @@ -/* The industrial I/O core - * - *Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * General attributes - */ - -#ifndef _INDUSTRIAL_IO_SYSFS_H_ -#define _INDUSTRIAL_IO_SYSFS_H_ - -struct iio_chan_spec; - -/** - * struct iio_dev_attr - iio specific device attribute - * @dev_attr: underlying device attribute - * @address: associated register address - * @l: list head for maintaining list of dynamically created attrs. - */ -struct iio_dev_attr { - struct device_attribute dev_attr; - u64 address; - struct list_head l; - struct iio_chan_spec const *c; -}; - -#define to_iio_dev_attr(_dev_attr) \ - container_of(_dev_attr, struct iio_dev_attr, dev_attr) - -ssize_t iio_read_const_attr(struct device *dev, - struct device_attribute *attr, - char *len); - -/** - * struct iio_const_attr - constant device specific attribute - * often used for things like available modes - * @string: attribute string - * @dev_attr: underlying device attribute - */ -struct iio_const_attr { - const char *string; - struct device_attribute dev_attr; -}; - -#define to_iio_const_attr(_dev_attr) \ - container_of(_dev_attr, struct iio_const_attr, dev_attr) - -/* Some attributes will be hard coded (device dependent) and not require an - address, in these cases pass a negative */ -#define IIO_ATTR(_name, _mode, _show, _store, _addr) \ - { .dev_attr = __ATTR(_name, _mode, _show, _store), \ - .address = _addr } - -#define IIO_DEVICE_ATTR(_name, _mode, _show, _store, _addr) \ - struct iio_dev_attr iio_dev_attr_##_name \ - = IIO_ATTR(_name, _mode, _show, _store, _addr) - -#define IIO_DEVICE_ATTR_NAMED(_vname, _name, _mode, _show, _store, _addr) \ - struct iio_dev_attr iio_dev_attr_##_vname \ - = IIO_ATTR(_name, _mode, _show, _store, _addr) - -#define IIO_CONST_ATTR(_name, _string) \ - struct iio_const_attr iio_const_attr_##_name \ - = { .string = _string, \ - .dev_attr = __ATTR(_name, S_IRUGO, iio_read_const_attr, NULL)} - -#define IIO_CONST_ATTR_NAMED(_vname, _name, _string) \ - struct iio_const_attr iio_const_attr_##_vname \ - = { .string = _string, \ - .dev_attr = __ATTR(_name, S_IRUGO, iio_read_const_attr, NULL)} - -/* Generic attributes of onetype or another */ -/** - * IIO_DEV_ATTR_RESET: resets the device - **/ -#define IIO_DEV_ATTR_RESET(_store) \ - IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, _store, 0) - -/** - * IIO_DEV_ATTR_SAMP_FREQ - sets any internal clock frequency - * @_mode: sysfs file mode/permissions - * @_show: output method for the attribute - * @_store: input method for the attribute - **/ -#define IIO_DEV_ATTR_SAMP_FREQ(_mode, _show, _store) \ - IIO_DEVICE_ATTR(sampling_frequency, _mode, _show, _store, 0) - -/** - * IIO_DEV_ATTR_SAMP_FREQ_AVAIL - list available sampling frequencies - * @_show: output method for the attribute - * - * May be mode dependent on some devices - **/ -#define IIO_DEV_ATTR_SAMP_FREQ_AVAIL(_show) \ - IIO_DEVICE_ATTR(sampling_frequency_available, S_IRUGO, _show, NULL, 0) -/** - * IIO_CONST_ATTR_AVAIL_SAMP_FREQ - list available sampling frequencies - * @_string: frequency string for the attribute - * - * Constant version - **/ -#define IIO_CONST_ATTR_SAMP_FREQ_AVAIL(_string) \ - IIO_CONST_ATTR(sampling_frequency_available, _string) - -#define IIO_DEV_ATTR_TEMP_RAW(_show) \ - IIO_DEVICE_ATTR(in_temp_raw, S_IRUGO, _show, NULL, 0) - -#define IIO_CONST_ATTR_TEMP_OFFSET(_string) \ - IIO_CONST_ATTR(in_temp_offset, _string) - -#define IIO_CONST_ATTR_TEMP_SCALE(_string) \ - IIO_CONST_ATTR(in_temp_scale, _string) - -#endif /* _INDUSTRIAL_IO_SYSFS_H_ */ diff --git a/drivers/staging/iio/trigger.h b/drivers/staging/iio/trigger.h deleted file mode 100644 index 1cfca23..0000000 --- a/drivers/staging/iio/trigger.h +++ /dev/null @@ -1,119 +0,0 @@ -/* The industrial I/O core, trigger handling functions - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ -#include -#include - -#ifndef _IIO_TRIGGER_H_ -#define _IIO_TRIGGER_H_ - -struct iio_subirq { - bool enabled; -}; - -/** - * struct iio_trigger_ops - operations structure for an iio_trigger. - * @owner: used to monitor usage count of the trigger. - * @set_trigger_state: switch on/off the trigger on demand - * @try_reenable: function to reenable the trigger when the - * use count is zero (may be NULL) - * @validate_device: function to validate the device when the - * current trigger gets changed. - * - * This is typically static const within a driver and shared by - * instances of a given device. - **/ -struct iio_trigger_ops { - struct module *owner; - int (*set_trigger_state)(struct iio_trigger *trig, bool state); - int (*try_reenable)(struct iio_trigger *trig); - int (*validate_device)(struct iio_trigger *trig, - struct iio_dev *indio_dev); -}; - - -/** - * struct iio_trigger - industrial I/O trigger device - * - * @id: [INTERN] unique id number - * @name: [DRIVER] unique name - * @dev: [DRIVER] associated device (if relevant) - * @private_data: [DRIVER] device specific data - * @list: [INTERN] used in maintenance of global trigger list - * @alloc_list: [DRIVER] used for driver specific trigger list - * @use_count: use count for the trigger - * @subirq_chip: [INTERN] associate 'virtual' irq chip. - * @subirq_base: [INTERN] base number for irqs provided by trigger. - * @subirqs: [INTERN] information about the 'child' irqs. - * @pool: [INTERN] bitmap of irqs currently in use. - * @pool_lock: [INTERN] protection of the irq pool. - **/ -struct iio_trigger { - const struct iio_trigger_ops *ops; - int id; - const char *name; - struct device dev; - - void *private_data; - struct list_head list; - struct list_head alloc_list; - int use_count; - - struct irq_chip subirq_chip; - int subirq_base; - - struct iio_subirq subirqs[CONFIG_IIO_CONSUMERS_PER_TRIGGER]; - unsigned long pool[BITS_TO_LONGS(CONFIG_IIO_CONSUMERS_PER_TRIGGER)]; - struct mutex pool_lock; -}; - - -static inline struct iio_trigger *to_iio_trigger(struct device *d) -{ - return container_of(d, struct iio_trigger, dev); -}; - -static inline void iio_put_trigger(struct iio_trigger *trig) -{ - module_put(trig->ops->owner); - put_device(&trig->dev); -}; - -static inline void iio_get_trigger(struct iio_trigger *trig) -{ - get_device(&trig->dev); - __module_get(trig->ops->owner); -}; - -/** - * iio_trigger_register() - register a trigger with the IIO core - * @trig_info: trigger to be registered - **/ -int iio_trigger_register(struct iio_trigger *trig_info); - -/** - * iio_trigger_unregister() - unregister a trigger from the core - * @trig_info: trigger to be unregistered - **/ -void iio_trigger_unregister(struct iio_trigger *trig_info); - -/** - * iio_trigger_poll() - called on a trigger occurring - * @trig: trigger which occurred - * - * Typically called in relevant hardware interrupt handler. - **/ -void iio_trigger_poll(struct iio_trigger *trig, s64 time); -void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time); - -irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private); - -__printf(1, 2) struct iio_trigger *iio_allocate_trigger(const char *fmt, ...); -void iio_free_trigger(struct iio_trigger *trig); - -#endif /* _IIO_TRIGGER_H_ */ diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c index 665653d..999fd2e 100644 --- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c +++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c @@ -15,8 +15,8 @@ #include -#include "../iio.h" -#include "../trigger.h" +#include +#include struct bfin_timer { unsigned short id, bit; diff --git a/drivers/staging/iio/trigger/iio-trig-gpio.c b/drivers/staging/iio/trigger/iio-trig-gpio.c index a346594..95fd2f7 100644 --- a/drivers/staging/iio/trigger/iio-trig-gpio.c +++ b/drivers/staging/iio/trigger/iio-trig-gpio.c @@ -22,8 +22,8 @@ #include #include -#include "../iio.h" -#include "../trigger.h" +#include +#include static LIST_HEAD(iio_gpio_trigger_list); static DEFINE_MUTEX(iio_gpio_trigger_list_lock); diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c index a80cf67..2c3ccda 100644 --- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c +++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c @@ -16,8 +16,8 @@ #include #include #include -#include "../iio.h" -#include "../trigger.h" +#include +#include static LIST_HEAD(iio_prtc_trigger_list); static DEFINE_MUTEX(iio_prtc_trigger_list_lock); diff --git a/drivers/staging/iio/trigger/iio-trig-sysfs.c b/drivers/staging/iio/trigger/iio-trig-sysfs.c index 174dc65..404ef19 100644 --- a/drivers/staging/iio/trigger/iio-trig-sysfs.c +++ b/drivers/staging/iio/trigger/iio-trig-sysfs.c @@ -11,8 +11,8 @@ #include #include -#include "../iio.h" -#include "../trigger.h" +#include +#include struct iio_sysfs_trig { struct iio_trigger *trig; diff --git a/drivers/staging/iio/trigger_consumer.h b/drivers/staging/iio/trigger_consumer.h deleted file mode 100644 index 60d64b3..0000000 --- a/drivers/staging/iio/trigger_consumer.h +++ /dev/null @@ -1,52 +0,0 @@ -/* The industrial I/O core, trigger consumer functions - * - * Copyright (c) 2008-2011 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -/** - * struct iio_poll_func - poll function pair - * - * @indio_dev: data specific to device (passed into poll func) - * @h: the function that is actually run on trigger - * @thread: threaded interrupt part - * @type: the type of interrupt (basically if oneshot) - * @name: name used to identify the trigger consumer. - * @irq: the corresponding irq as allocated from the - * trigger pool - * @timestamp: some devices need a timestamp grabbed as soon - * as possible after the trigger - hence handler - * passes it via here. - **/ -struct iio_poll_func { - struct iio_dev *indio_dev; - irqreturn_t (*h)(int irq, void *p); - irqreturn_t (*thread)(int irq, void *p); - int type; - char *name; - int irq; - s64 timestamp; -}; - - -struct iio_poll_func -*iio_alloc_pollfunc(irqreturn_t (*h)(int irq, void *p), - irqreturn_t (*thread)(int irq, void *p), - int type, - struct iio_dev *indio_dev, - const char *fmt, - ...); -void iio_dealloc_pollfunc(struct iio_poll_func *pf); -irqreturn_t iio_pollfunc_store_time(int irq, void *p); - -void iio_trigger_notify_done(struct iio_trigger *trig); - -/* - * Two functions for common case where all that happens is a pollfunc - * is attached and detached from a trigger - */ -int iio_triggered_buffer_postenable(struct iio_dev *indio_dev); -int iio_triggered_buffer_predisable(struct iio_dev *indio_dev); diff --git a/drivers/staging/iio/types.h b/drivers/staging/iio/types.h deleted file mode 100644 index 0c32136..0000000 --- a/drivers/staging/iio/types.h +++ /dev/null @@ -1,53 +0,0 @@ -/* industrial I/O data types needed both in and out of kernel - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -#ifndef _IIO_TYPES_H_ -#define _IIO_TYPES_H_ - -enum iio_chan_type { - /* real channel types */ - IIO_VOLTAGE, - IIO_CURRENT, - IIO_POWER, - IIO_ACCEL, - IIO_ANGL_VEL, - IIO_MAGN, - IIO_LIGHT, - IIO_INTENSITY, - IIO_PROXIMITY, - IIO_TEMP, - IIO_INCLI, - IIO_ROT, - IIO_ANGL, - IIO_TIMESTAMP, - IIO_CAPACITANCE, -}; - -enum iio_modifier { - IIO_NO_MOD, - IIO_MOD_X, - IIO_MOD_Y, - IIO_MOD_Z, - IIO_MOD_X_AND_Y, - IIO_MOD_X_AND_Z, - IIO_MOD_Y_AND_Z, - IIO_MOD_X_AND_Y_AND_Z, - IIO_MOD_X_OR_Y, - IIO_MOD_X_OR_Z, - IIO_MOD_Y_OR_Z, - IIO_MOD_X_OR_Y_OR_Z, - IIO_MOD_LIGHT_BOTH, - IIO_MOD_LIGHT_IR, -}; - -#define IIO_VAL_INT 1 -#define IIO_VAL_INT_PLUS_MICRO 2 -#define IIO_VAL_INT_PLUS_NANO 3 - -#endif /* _IIO_TYPES_H_ */ diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h new file mode 100644 index 0000000..fb0fe46 --- /dev/null +++ b/include/linux/iio/buffer.h @@ -0,0 +1,191 @@ +/* The industrial I/O core - generic buffer interfaces. + * + * Copyright (c) 2008 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#ifndef _IIO_BUFFER_GENERIC_H_ +#define _IIO_BUFFER_GENERIC_H_ +#include +#include + +#ifdef CONFIG_IIO_BUFFER + +struct iio_buffer; + +/** + * struct iio_buffer_access_funcs - access functions for buffers. + * @store_to: actually store stuff to the buffer + * @read_first_n: try to get a specified number of bytes (must exist) + * @request_update: if a parameter change has been marked, update underlying + * storage. + * @get_bytes_per_datum:get current bytes per datum + * @set_bytes_per_datum:set number of bytes per datum + * @get_length: get number of datums in buffer + * @set_length: set number of datums in buffer + * + * The purpose of this structure is to make the buffer element + * modular as event for a given driver, different usecases may require + * different buffer designs (space efficiency vs speed for example). + * + * It is worth noting that a given buffer implementation may only support a + * small proportion of these functions. The core code 'should' cope fine with + * any of them not existing. + **/ +struct iio_buffer_access_funcs { + int (*store_to)(struct iio_buffer *buffer, u8 *data, s64 timestamp); + int (*read_first_n)(struct iio_buffer *buffer, + size_t n, + char __user *buf); + + int (*request_update)(struct iio_buffer *buffer); + + int (*get_bytes_per_datum)(struct iio_buffer *buffer); + int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd); + int (*get_length)(struct iio_buffer *buffer); + int (*set_length)(struct iio_buffer *buffer, int length); +}; + +/** + * struct iio_buffer - general buffer structure + * @length: [DEVICE] number of datums in buffer + * @bytes_per_datum: [DEVICE] size of individual datum including timestamp + * @scan_el_attrs: [DRIVER] control of scan elements if that scan mode + * control method is used + * @scan_mask: [INTERN] bitmask used in masking scan mode elements + * @scan_timestamp: [INTERN] does the scan mode include a timestamp + * @access: [DRIVER] buffer access functions associated with the + * implementation. + * @scan_el_dev_attr_list:[INTERN] list of scan element related attributes. + * @scan_el_group: [DRIVER] attribute group for those attributes not + * created from the iio_chan_info array. + * @pollq: [INTERN] wait queue to allow for polling on the buffer. + * @stufftoread: [INTERN] flag to indicate new data. + * @demux_list: [INTERN] list of operations required to demux the scan. + * @demux_bounce: [INTERN] buffer for doing gather from incoming scan. + **/ +struct iio_buffer { + int length; + int bytes_per_datum; + struct attribute_group *scan_el_attrs; + long *scan_mask; + bool scan_timestamp; + const struct iio_buffer_access_funcs *access; + struct list_head scan_el_dev_attr_list; + struct attribute_group scan_el_group; + wait_queue_head_t pollq; + bool stufftoread; + const struct attribute_group *attrs; + struct list_head demux_list; + unsigned char *demux_bounce; +}; + +/** + * iio_buffer_init() - Initialize the buffer structure + * @buffer: buffer to be initialized + **/ +void iio_buffer_init(struct iio_buffer *buffer); + +/** + * __iio_update_buffer() - update common elements of buffers + * @buffer: buffer that is the event source + * @bytes_per_datum: size of individual datum including timestamp + * @length: number of datums in buffer + **/ +static inline void __iio_update_buffer(struct iio_buffer *buffer, + int bytes_per_datum, int length) +{ + buffer->bytes_per_datum = bytes_per_datum; + buffer->length = length; +} + +int iio_scan_mask_query(struct iio_dev *indio_dev, + struct iio_buffer *buffer, int bit); + +/** + * iio_scan_mask_set() - set particular bit in the scan mask + * @buffer: the buffer whose scan mask we are interested in + * @bit: the bit to be set. + **/ +int iio_scan_mask_set(struct iio_dev *indio_dev, + struct iio_buffer *buffer, int bit); + +/** + * iio_push_to_buffer() - push to a registered buffer. + * @buffer: IIO buffer structure for device + * @scan: Full scan. + * @timestamp: + */ +int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data, + s64 timestamp); + +int iio_update_demux(struct iio_dev *indio_dev); + +/** + * iio_buffer_register() - register the buffer with IIO core + * @indio_dev: device with the buffer to be registered + **/ +int iio_buffer_register(struct iio_dev *indio_dev, + const struct iio_chan_spec *channels, + int num_channels); + +/** + * iio_buffer_unregister() - unregister the buffer from IIO core + * @indio_dev: the device with the buffer to be unregistered + **/ +void iio_buffer_unregister(struct iio_dev *indio_dev); + +/** + * iio_buffer_read_length() - attr func to get number of datums in the buffer + **/ +ssize_t iio_buffer_read_length(struct device *dev, + struct device_attribute *attr, + char *buf); +/** + * iio_buffer_write_length() - attr func to set number of datums in the buffer + **/ +ssize_t iio_buffer_write_length(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len); +/** + * iio_buffer_store_enable() - attr to turn the buffer on + **/ +ssize_t iio_buffer_store_enable(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len); +/** + * iio_buffer_show_enable() - attr to see if the buffer is on + **/ +ssize_t iio_buffer_show_enable(struct device *dev, + struct device_attribute *attr, + char *buf); +#define IIO_BUFFER_LENGTH_ATTR DEVICE_ATTR(length, S_IRUGO | S_IWUSR, \ + iio_buffer_read_length, \ + iio_buffer_write_length) + +#define IIO_BUFFER_ENABLE_ATTR DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, \ + iio_buffer_show_enable, \ + iio_buffer_store_enable) + +int iio_sw_buffer_preenable(struct iio_dev *indio_dev); + +#else /* CONFIG_IIO_BUFFER */ + +static inline int iio_buffer_register(struct iio_dev *indio_dev, + struct iio_chan_spec *channels, + int num_channels) +{ + return 0; +} + +static inline void iio_buffer_unregister(struct iio_dev *indio_dev) +{}; + +#endif /* CONFIG_IIO_BUFFER */ + +#endif /* _IIO_BUFFER_GENERIC_H_ */ diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h new file mode 100644 index 0000000..1a15e560 --- /dev/null +++ b/include/linux/iio/consumer.h @@ -0,0 +1,96 @@ +/* + * Industrial I/O in kernel consumer interface + * + * Copyright (c) 2011 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ +#ifndef _IIO_INKERN_CONSUMER_H_ +#define _IIO_INKERN_CONSUMER_H +#include + +struct iio_dev; +struct iio_chan_spec; + +/** + * struct iio_channel - everything needed for a consumer to use a channel + * @indio_dev: Device on which the channel exists. + * @channel: Full description of the channel. + */ +struct iio_channel { + struct iio_dev *indio_dev; + const struct iio_chan_spec *channel; +}; + +/** + * iio_channel_get() - get description of all that is needed to access channel. + * @name: Unique name of the device as provided in the iio_map + * with which the desired provider to consumer mapping + * was registered. + * @consumer_channel: Unique name to identify the channel on the consumer + * side. This typically describes the channels use within + * the consumer. E.g. 'battery_voltage' + */ +struct iio_channel *iio_st_channel_get(const char *name, + const char *consumer_channel); + +/** + * iio_st_channel_release() - release channels obtained via iio_st_channel_get + * @chan: The channel to be released. + */ +void iio_st_channel_release(struct iio_channel *chan); + +/** + * iio_st_channel_get_all() - get all channels associated with a client + * @name: name of consumer device. + * + * Returns an array of iio_channel structures terminated with one with + * null iio_dev pointer. + * This function is used by fairly generic consumers to get all the + * channels registered as having this consumer. + */ +struct iio_channel *iio_st_channel_get_all(const char *name); + +/** + * iio_st_channel_release_all() - reverse iio_st_get_all + * @chan: Array of channels to be released. + */ +void iio_st_channel_release_all(struct iio_channel *chan); + +/** + * iio_st_read_channel_raw() - read from a given channel + * @channel: The channel being queried. + * @val: Value read back. + * + * Note raw reads from iio channels are in adc counts and hence + * scale will need to be applied if standard units required. + */ +int iio_st_read_channel_raw(struct iio_channel *chan, + int *val); + +/** + * iio_st_get_channel_type() - get the type of a channel + * @channel: The channel being queried. + * @type: The type of the channel. + * + * returns the enum iio_chan_type of the channel + */ +int iio_st_get_channel_type(struct iio_channel *channel, + enum iio_chan_type *type); + +/** + * iio_st_read_channel_scale() - read the scale value for a channel + * @channel: The channel being queried. + * @val: First part of value read back. + * @val2: Second part of value read back. + * + * Note returns a description of what is in val and val2, such + * as IIO_VAL_INT_PLUS_MICRO telling us we have a value of val + * + val2/1e6 + */ +int iio_st_read_channel_scale(struct iio_channel *chan, int *val, + int *val2); + +#endif diff --git a/include/linux/iio/driver.h b/include/linux/iio/driver.h new file mode 100644 index 0000000..a4f8b2e --- /dev/null +++ b/include/linux/iio/driver.h @@ -0,0 +1,34 @@ +/* + * Industrial I/O in kernel access map interface. + * + * Copyright (c) 2011 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#ifndef _IIO_INKERN_H_ +#define _IIO_INKERN_H_ + +struct iio_map; + +/** + * iio_map_array_register() - tell the core about inkernel consumers + * @indio_dev: provider device + * @map: array of mappings specifying association of channel with client + */ +int iio_map_array_register(struct iio_dev *indio_dev, + struct iio_map *map); + +/** + * iio_map_array_unregister() - tell the core to remove consumer mappings + * @indio_dev: provider device + * @map: array of mappings to remove. Note these must have same memory + * addresses as those originally added not just equal parameter + * values. + */ +int iio_map_array_unregister(struct iio_dev *indio_dev, + struct iio_map *map); + +#endif diff --git a/include/linux/iio/events.h b/include/linux/iio/events.h new file mode 100644 index 0000000..b5acbf9 --- /dev/null +++ b/include/linux/iio/events.h @@ -0,0 +1,105 @@ +/* The industrial I/O - event passing to userspace + * + * Copyright (c) 2008-2011 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ +#ifndef _IIO_EVENTS_H_ +#define _IIO_EVENTS_H_ + +#include +#include +#include + +/** + * struct iio_event_data - The actual event being pushed to userspace + * @id: event identifier + * @timestamp: best estimate of time of event occurrence (often from + * the interrupt handler) + */ +struct iio_event_data { + __u64 id; + __s64 timestamp; +}; + +#define IIO_GET_EVENT_FD_IOCTL _IOR('i', 0x90, int) + +enum iio_event_type { + IIO_EV_TYPE_THRESH, + IIO_EV_TYPE_MAG, + IIO_EV_TYPE_ROC, + IIO_EV_TYPE_THRESH_ADAPTIVE, + IIO_EV_TYPE_MAG_ADAPTIVE, +}; + +enum iio_event_direction { + IIO_EV_DIR_EITHER, + IIO_EV_DIR_RISING, + IIO_EV_DIR_FALLING, +}; + +/** + * IIO_EVENT_CODE() - create event identifier + * @chan_type: Type of the channel. Should be one of enum iio_chan_type. + * @diff: Whether the event is for an differential channel or not. + * @modifier: Modifier for the channel. Should be one of enum iio_modifier. + * @direction: Direction of the event. One of enum iio_event_direction. + * @type: Type of the event. Should be one enum iio_event_type. + * @chan: Channel number for non-differential channels. + * @chan1: First channel number for differential channels. + * @chan2: Second channel number for differential channels. + */ + +#define IIO_EVENT_CODE(chan_type, diff, modifier, direction, \ + type, chan, chan1, chan2) \ + (((u64)type << 56) | ((u64)diff << 55) | \ + ((u64)direction << 48) | ((u64)modifier << 40) | \ + ((u64)chan_type << 32) | (((u16)chan2) << 16) | ((u16)chan1) | \ + ((u16)chan)) + + +#define IIO_EV_DIR_MAX 4 +#define IIO_EV_BIT(type, direction) \ + (1 << (type*IIO_EV_DIR_MAX + direction)) + +/** + * IIO_MOD_EVENT_CODE() - create event identifier for modified channels + * @chan_type: Type of the channel. Should be one of enum iio_chan_type. + * @number: Channel number. + * @modifier: Modifier for the channel. Should be one of enum iio_modifier. + * @type: Type of the event. Should be one enum iio_event_type. + * @direction: Direction of the event. One of enum iio_event_direction. + */ + +#define IIO_MOD_EVENT_CODE(chan_type, number, modifier, \ + type, direction) \ + IIO_EVENT_CODE(chan_type, 0, modifier, direction, type, number, 0, 0) + +/** + * IIO_UNMOD_EVENT_CODE() - create event identifier for unmodified channels + * @chan_type: Type of the channel. Should be one of enum iio_chan_type. + * @number: Channel number. + * @type: Type of the event. Should be one enum iio_event_type. + * @direction: Direction of the event. One of enum iio_event_direction. + */ + +#define IIO_UNMOD_EVENT_CODE(chan_type, number, type, direction) \ + IIO_EVENT_CODE(chan_type, 0, 0, direction, type, number, 0, 0) + +#define IIO_EVENT_CODE_EXTRACT_TYPE(mask) ((mask >> 56) & 0xFF) + +#define IIO_EVENT_CODE_EXTRACT_DIR(mask) ((mask >> 48) & 0xCF) + +#define IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(mask) ((mask >> 32) & 0xFF) + +/* Event code number extraction depends on which type of event we have. + * Perhaps review this function in the future*/ +#define IIO_EVENT_CODE_EXTRACT_CHAN(mask) ((__s16)(mask & 0xFFFF)) +#define IIO_EVENT_CODE_EXTRACT_CHAN2(mask) ((__s16)(((mask) >> 16) & 0xFFFF)) + +#define IIO_EVENT_CODE_EXTRACT_MODIFIER(mask) ((mask >> 40) & 0xFF) +#define IIO_EVENT_CODE_EXTRACT_DIFF(mask) (((mask) >> 55) & 0x1) + +#endif diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h new file mode 100644 index 0000000..9c0908a --- /dev/null +++ b/include/linux/iio/iio.h @@ -0,0 +1,463 @@ + +/* The industrial I/O core + * + * Copyright (c) 2008 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ +#ifndef _INDUSTRIAL_IO_H_ +#define _INDUSTRIAL_IO_H_ + +#include +#include +#include +/* IIO TODO LIST */ +/* + * Provide means of adjusting timer accuracy. + * Currently assumes nano seconds. + */ + +enum iio_chan_info_enum { + IIO_CHAN_INFO_RAW = 0, + IIO_CHAN_INFO_PROCESSED, + IIO_CHAN_INFO_SCALE, + IIO_CHAN_INFO_OFFSET, + IIO_CHAN_INFO_CALIBSCALE, + IIO_CHAN_INFO_CALIBBIAS, + IIO_CHAN_INFO_PEAK, + IIO_CHAN_INFO_PEAK_SCALE, + IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW, + IIO_CHAN_INFO_AVERAGE_RAW, + IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY, + IIO_CHAN_INFO_SAMP_FREQ, +}; + +#define IIO_CHAN_INFO_SHARED_BIT(type) BIT(type*2) +#define IIO_CHAN_INFO_SEPARATE_BIT(type) BIT(type*2 + 1) + +#define IIO_CHAN_INFO_RAW_SEPARATE_BIT \ + IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_RAW) +#define IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT \ + IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_PROCESSED) +#define IIO_CHAN_INFO_SCALE_SEPARATE_BIT \ + IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_SCALE) +#define IIO_CHAN_INFO_SCALE_SHARED_BIT \ + IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_SCALE) +#define IIO_CHAN_INFO_OFFSET_SEPARATE_BIT \ + IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_OFFSET) +#define IIO_CHAN_INFO_OFFSET_SHARED_BIT \ + IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_OFFSET) +#define IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT \ + IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_CALIBSCALE) +#define IIO_CHAN_INFO_CALIBSCALE_SHARED_BIT \ + IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_CALIBSCALE) +#define IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT \ + IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_CALIBBIAS) +#define IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT \ + IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_CALIBBIAS) +#define IIO_CHAN_INFO_PEAK_SEPARATE_BIT \ + IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_PEAK) +#define IIO_CHAN_INFO_PEAK_SHARED_BIT \ + IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_PEAK) +#define IIO_CHAN_INFO_PEAKSCALE_SEPARATE_BIT \ + IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_PEAKSCALE) +#define IIO_CHAN_INFO_PEAKSCALE_SHARED_BIT \ + IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_PEAKSCALE) +#define IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE_BIT \ + IIO_CHAN_INFO_SEPARATE_BIT( \ + IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW) +#define IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SHARED_BIT \ + IIO_CHAN_INFO_SHARED_BIT( \ + IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW) +#define IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT \ + IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_AVERAGE_RAW) +#define IIO_CHAN_INFO_AVERAGE_RAW_SHARED_BIT \ + IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_AVERAGE_RAW) +#define IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT \ + IIO_CHAN_INFO_SHARED_BIT( \ + IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) +#define IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT \ + IIO_CHAN_INFO_SEPARATE_BIT( \ + IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) +#define IIO_CHAN_INFO_SAMP_FREQ_SEPARATE_BIT \ + IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_SAMP_FREQ) +#define IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT \ + IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_SAMP_FREQ) + +enum iio_endian { + IIO_CPU, + IIO_BE, + IIO_LE, +}; + +struct iio_chan_spec; +struct iio_dev; + +/** + * struct iio_chan_spec_ext_info - Extended channel info attribute + * @name: Info attribute name + * @shared: Whether this attribute is shared between all channels. + * @read: Read callback for this info attribute, may be NULL. + * @write: Write callback for this info attribute, may be NULL. + */ +struct iio_chan_spec_ext_info { + const char *name; + bool shared; + ssize_t (*read)(struct iio_dev *, struct iio_chan_spec const *, + char *buf); + ssize_t (*write)(struct iio_dev *, struct iio_chan_spec const *, + const char *buf, size_t len); +}; + +/** + * struct iio_chan_spec - specification of a single channel + * @type: What type of measurement is the channel making. + * @channel: What number or name do we wish to assign the channel. + * @channel2: If there is a second number for a differential + * channel then this is it. If modified is set then the + * value here specifies the modifier. + * @address: Driver specific identifier. + * @scan_index: Monotonic index to give ordering in scans when read + * from a buffer. + * @scan_type: Sign: 's' or 'u' to specify signed or unsigned + * realbits: Number of valid bits of data + * storage_bits: Realbits + padding + * shift: Shift right by this before masking out + * realbits. + * endianness: little or big endian + * @info_mask: What information is to be exported about this channel. + * This includes calibbias, scale etc. + * @event_mask: What events can this channel produce. + * @ext_info: Array of extended info attributes for this channel. + * The array is NULL terminated, the last element should + * have it's name field set to NULL. + * @extend_name: Allows labeling of channel attributes with an + * informative name. Note this has no effect codes etc, + * unlike modifiers. + * @datasheet_name: A name used in in kernel mapping of channels. It should + * correspond to the first name that the channel is referred + * to by in the datasheet (e.g. IND), or the nearest + * possible compound name (e.g. IND-INC). + * @modified: Does a modifier apply to this channel. What these are + * depends on the channel type. Modifier is set in + * channel2. Examples are IIO_MOD_X for axial sensors about + * the 'x' axis. + * @indexed: Specify the channel has a numerical index. If not, + * the value in channel will be suppressed for attribute + * but not for event codes. Typically set it to 0 when + * the index is false. + * @differential: Channel is differential. + */ +struct iio_chan_spec { + enum iio_chan_type type; + int channel; + int channel2; + unsigned long address; + int scan_index; + struct { + char sign; + u8 realbits; + u8 storagebits; + u8 shift; + enum iio_endian endianness; + } scan_type; + long info_mask; + long event_mask; + const struct iio_chan_spec_ext_info *ext_info; + const char *extend_name; + const char *datasheet_name; + unsigned modified:1; + unsigned indexed:1; + unsigned output:1; + unsigned differential:1; +}; + +#define IIO_ST(si, rb, sb, sh) \ + { .sign = si, .realbits = rb, .storagebits = sb, .shift = sh } + +#define IIO_CHAN_SOFT_TIMESTAMP(_si) \ + { .type = IIO_TIMESTAMP, .channel = -1, \ + .scan_index = _si, .scan_type = IIO_ST('s', 64, 64, 0) } + +/** + * iio_get_time_ns() - utility function to get a time stamp for events etc + **/ +static inline s64 iio_get_time_ns(void) +{ + struct timespec ts; + /* + * calls getnstimeofday. + * If hrtimers then up to ns accurate, if not microsecond. + */ + ktime_get_real_ts(&ts); + + return timespec_to_ns(&ts); +} + +/* Device operating modes */ +#define INDIO_DIRECT_MODE 0x01 +#define INDIO_BUFFER_TRIGGERED 0x02 +#define INDIO_BUFFER_HARDWARE 0x08 + +#define INDIO_ALL_BUFFER_MODES \ + (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE) + +struct iio_trigger; /* forward declaration */ +struct iio_dev; + +/** + * struct iio_info - constant information about device + * @driver_module: module structure used to ensure correct + * ownership of chrdevs etc + * @event_attrs: event control attributes + * @attrs: general purpose device attributes + * @read_raw: function to request a value from the device. + * mask specifies which value. Note 0 means a reading of + * the channel in question. Return value will specify the + * type of value returned by the device. val and val2 will + * contain the elements making up the returned value. + * @write_raw: function to write a value to the device. + * Parameters are the same as for read_raw. + * @write_raw_get_fmt: callback function to query the expected + * format/precision. If not set by the driver, write_raw + * returns IIO_VAL_INT_PLUS_MICRO. + * @read_event_config: find out if the event is enabled. + * @write_event_config: set if the event is enabled. + * @read_event_value: read a value associated with the event. Meaning + * is event dependant. event_code specifies which event. + * @write_event_value: write the value associated with the event. + * Meaning is event dependent. + * @validate_trigger: function to validate the trigger when the + * current trigger gets changed. + **/ +struct iio_info { + struct module *driver_module; + struct attribute_group *event_attrs; + const struct attribute_group *attrs; + + int (*read_raw)(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long mask); + + int (*write_raw)(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask); + + int (*write_raw_get_fmt)(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long mask); + + int (*read_event_config)(struct iio_dev *indio_dev, + u64 event_code); + + int (*write_event_config)(struct iio_dev *indio_dev, + u64 event_code, + int state); + + int (*read_event_value)(struct iio_dev *indio_dev, + u64 event_code, + int *val); + int (*write_event_value)(struct iio_dev *indio_dev, + u64 event_code, + int val); + int (*validate_trigger)(struct iio_dev *indio_dev, + struct iio_trigger *trig); + int (*update_scan_mode)(struct iio_dev *indio_dev, + const unsigned long *scan_mask); + int (*debugfs_reg_access)(struct iio_dev *indio_dev, + unsigned reg, unsigned writeval, + unsigned *readval); +}; + +/** + * struct iio_buffer_setup_ops - buffer setup related callbacks + * @preenable: [DRIVER] function to run prior to marking buffer enabled + * @postenable: [DRIVER] function to run after marking buffer enabled + * @predisable: [DRIVER] function to run prior to marking buffer + * disabled + * @postdisable: [DRIVER] function to run after marking buffer disabled + */ +struct iio_buffer_setup_ops { + int (*preenable)(struct iio_dev *); + int (*postenable)(struct iio_dev *); + int (*predisable)(struct iio_dev *); + int (*postdisable)(struct iio_dev *); +}; + +/** + * struct iio_dev - industrial I/O device + * @id: [INTERN] used to identify device internally + * @modes: [DRIVER] operating modes supported by device + * @currentmode: [DRIVER] current operating mode + * @dev: [DRIVER] device structure, should be assigned a parent + * and owner + * @event_interface: [INTERN] event chrdevs associated with interrupt lines + * @buffer: [DRIVER] any buffer present + * @scan_bytes: [INTERN] num bytes captured to be fed to buffer demux + * @mlock: [INTERN] lock used to prevent simultaneous device state + * changes + * @available_scan_masks: [DRIVER] optional array of allowed bitmasks + * @masklength: [INTERN] the length of the mask established from + * channels + * @active_scan_mask: [INTERN] union of all scan masks requested by buffers + * @scan_timestamp: [INTERN] set if any buffers have requested timestamp + * @scan_index_timestamp:[INTERN] cache of the index to the timestamp + * @trig: [INTERN] current device trigger (buffer modes) + * @pollfunc: [DRIVER] function run on trigger being received + * @channels: [DRIVER] channel specification structure table + * @num_channels: [DRIVER] number of chanels specified in @channels. + * @channel_attr_list: [INTERN] keep track of automatically created channel + * attributes + * @chan_attr_group: [INTERN] group for all attrs in base directory + * @name: [DRIVER] name of the device. + * @info: [DRIVER] callbacks and constant info from driver + * @info_exist_lock: [INTERN] lock to prevent use during removal + * @setup_ops: [DRIVER] callbacks to call before and after buffer + * enable/disable + * @chrdev: [INTERN] associated character device + * @groups: [INTERN] attribute groups + * @groupcounter: [INTERN] index of next attribute group + * @flags: [INTERN] file ops related flags including busy flag. + * @debugfs_dentry: [INTERN] device specific debugfs dentry. + * @cached_reg_addr: [INTERN] cached register address for debugfs reads. + */ +struct iio_dev { + int id; + + int modes; + int currentmode; + struct device dev; + + struct iio_event_interface *event_interface; + + struct iio_buffer *buffer; + int scan_bytes; + struct mutex mlock; + + const unsigned long *available_scan_masks; + unsigned masklength; + const unsigned long *active_scan_mask; + bool scan_timestamp; + unsigned scan_index_timestamp; + struct iio_trigger *trig; + struct iio_poll_func *pollfunc; + + struct iio_chan_spec const *channels; + int num_channels; + + struct list_head channel_attr_list; + struct attribute_group chan_attr_group; + const char *name; + const struct iio_info *info; + struct mutex info_exist_lock; + const struct iio_buffer_setup_ops *setup_ops; + struct cdev chrdev; +#define IIO_MAX_GROUPS 6 + const struct attribute_group *groups[IIO_MAX_GROUPS + 1]; + int groupcounter; + + unsigned long flags; +#if defined(CONFIG_DEBUG_FS) + struct dentry *debugfs_dentry; + unsigned cached_reg_addr; +#endif +}; + +/** + * iio_find_channel_from_si() - get channel from its scan index + * @indio_dev: device + * @si: scan index to match + */ +const struct iio_chan_spec +*iio_find_channel_from_si(struct iio_dev *indio_dev, int si); + +/** + * iio_device_register() - register a device with the IIO subsystem + * @indio_dev: Device structure filled by the device driver + **/ +int iio_device_register(struct iio_dev *indio_dev); + +/** + * iio_device_unregister() - unregister a device from the IIO subsystem + * @indio_dev: Device structure representing the device. + **/ +void iio_device_unregister(struct iio_dev *indio_dev); + +/** + * iio_push_event() - try to add event to the list for userspace reading + * @indio_dev: IIO device structure + * @ev_code: What event + * @timestamp: When the event occurred + **/ +int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp); + +extern struct bus_type iio_bus_type; + +/** + * iio_put_device() - reference counted deallocation of struct device + * @dev: the iio_device containing the device + **/ +static inline void iio_put_device(struct iio_dev *indio_dev) +{ + if (indio_dev) + put_device(&indio_dev->dev); +}; + +/* Can we make this smaller? */ +#define IIO_ALIGN L1_CACHE_BYTES +/** + * iio_allocate_device() - allocate an iio_dev from a driver + * @sizeof_priv: Space to allocate for private structure. + **/ +struct iio_dev *iio_allocate_device(int sizeof_priv); + +static inline void *iio_priv(const struct iio_dev *indio_dev) +{ + return (char *)indio_dev + ALIGN(sizeof(struct iio_dev), IIO_ALIGN); +} + +static inline struct iio_dev *iio_priv_to_dev(void *priv) +{ + return (struct iio_dev *)((char *)priv - + ALIGN(sizeof(struct iio_dev), IIO_ALIGN)); +} + +/** + * iio_free_device() - free an iio_dev from a driver + * @dev: the iio_dev associated with the device + **/ +void iio_free_device(struct iio_dev *indio_dev); + +/** + * iio_buffer_enabled() - helper function to test if the buffer is enabled + * @indio_dev: IIO device info structure for device + **/ +static inline bool iio_buffer_enabled(struct iio_dev *indio_dev) +{ + return indio_dev->currentmode + & (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE); +}; + +/** + * iio_get_debugfs_dentry() - helper function to get the debugfs_dentry + * @indio_dev: IIO device info structure for device + **/ +#if defined(CONFIG_DEBUG_FS) +static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev) +{ + return indio_dev->debugfs_dentry; +}; +#else +static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev) +{ + return NULL; +}; +#endif + +#endif /* _INDUSTRIAL_IO_H_ */ diff --git a/include/linux/iio/kfifo_buf.h b/include/linux/iio/kfifo_buf.h new file mode 100644 index 0000000..014d5a1 --- /dev/null +++ b/include/linux/iio/kfifo_buf.h @@ -0,0 +1,8 @@ + +#include +#include +#include + +struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev); +void iio_kfifo_free(struct iio_buffer *r); + diff --git a/include/linux/iio/machine.h b/include/linux/iio/machine.h new file mode 100644 index 0000000..0b1f19b --- /dev/null +++ b/include/linux/iio/machine.h @@ -0,0 +1,24 @@ +/* + * Industrial I/O in kernel access map definitions for board files. + * + * Copyright (c) 2011 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +/** + * struct iio_map - description of link between consumer and device channels + * @adc_channel_label: Label used to identify the channel on the provider. + * This is matched against the datasheet_name element + * of struct iio_chan_spec. + * @consumer_dev_name: Name to uniquely identify the consumer device. + * @consumer_channel: Unique name used to idenitify the channel on the + * consumer side. + */ +struct iio_map { + const char *adc_channel_label; + const char *consumer_dev_name; + const char *consumer_channel; +}; diff --git a/include/linux/iio/sysfs.h b/include/linux/iio/sysfs.h new file mode 100644 index 0000000..bfedb73 --- /dev/null +++ b/include/linux/iio/sysfs.h @@ -0,0 +1,117 @@ +/* The industrial I/O core + * + *Copyright (c) 2008 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * General attributes + */ + +#ifndef _INDUSTRIAL_IO_SYSFS_H_ +#define _INDUSTRIAL_IO_SYSFS_H_ + +struct iio_chan_spec; + +/** + * struct iio_dev_attr - iio specific device attribute + * @dev_attr: underlying device attribute + * @address: associated register address + * @l: list head for maintaining list of dynamically created attrs. + */ +struct iio_dev_attr { + struct device_attribute dev_attr; + u64 address; + struct list_head l; + struct iio_chan_spec const *c; +}; + +#define to_iio_dev_attr(_dev_attr) \ + container_of(_dev_attr, struct iio_dev_attr, dev_attr) + +ssize_t iio_read_const_attr(struct device *dev, + struct device_attribute *attr, + char *len); + +/** + * struct iio_const_attr - constant device specific attribute + * often used for things like available modes + * @string: attribute string + * @dev_attr: underlying device attribute + */ +struct iio_const_attr { + const char *string; + struct device_attribute dev_attr; +}; + +#define to_iio_const_attr(_dev_attr) \ + container_of(_dev_attr, struct iio_const_attr, dev_attr) + +/* Some attributes will be hard coded (device dependent) and not require an + address, in these cases pass a negative */ +#define IIO_ATTR(_name, _mode, _show, _store, _addr) \ + { .dev_attr = __ATTR(_name, _mode, _show, _store), \ + .address = _addr } + +#define IIO_DEVICE_ATTR(_name, _mode, _show, _store, _addr) \ + struct iio_dev_attr iio_dev_attr_##_name \ + = IIO_ATTR(_name, _mode, _show, _store, _addr) + +#define IIO_DEVICE_ATTR_NAMED(_vname, _name, _mode, _show, _store, _addr) \ + struct iio_dev_attr iio_dev_attr_##_vname \ + = IIO_ATTR(_name, _mode, _show, _store, _addr) + +#define IIO_CONST_ATTR(_name, _string) \ + struct iio_const_attr iio_const_attr_##_name \ + = { .string = _string, \ + .dev_attr = __ATTR(_name, S_IRUGO, iio_read_const_attr, NULL)} + +#define IIO_CONST_ATTR_NAMED(_vname, _name, _string) \ + struct iio_const_attr iio_const_attr_##_vname \ + = { .string = _string, \ + .dev_attr = __ATTR(_name, S_IRUGO, iio_read_const_attr, NULL)} + +/* Generic attributes of onetype or another */ +/** + * IIO_DEV_ATTR_RESET: resets the device + **/ +#define IIO_DEV_ATTR_RESET(_store) \ + IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, _store, 0) + +/** + * IIO_DEV_ATTR_SAMP_FREQ - sets any internal clock frequency + * @_mode: sysfs file mode/permissions + * @_show: output method for the attribute + * @_store: input method for the attribute + **/ +#define IIO_DEV_ATTR_SAMP_FREQ(_mode, _show, _store) \ + IIO_DEVICE_ATTR(sampling_frequency, _mode, _show, _store, 0) + +/** + * IIO_DEV_ATTR_SAMP_FREQ_AVAIL - list available sampling frequencies + * @_show: output method for the attribute + * + * May be mode dependent on some devices + **/ +#define IIO_DEV_ATTR_SAMP_FREQ_AVAIL(_show) \ + IIO_DEVICE_ATTR(sampling_frequency_available, S_IRUGO, _show, NULL, 0) +/** + * IIO_CONST_ATTR_AVAIL_SAMP_FREQ - list available sampling frequencies + * @_string: frequency string for the attribute + * + * Constant version + **/ +#define IIO_CONST_ATTR_SAMP_FREQ_AVAIL(_string) \ + IIO_CONST_ATTR(sampling_frequency_available, _string) + +#define IIO_DEV_ATTR_TEMP_RAW(_show) \ + IIO_DEVICE_ATTR(in_temp_raw, S_IRUGO, _show, NULL, 0) + +#define IIO_CONST_ATTR_TEMP_OFFSET(_string) \ + IIO_CONST_ATTR(in_temp_offset, _string) + +#define IIO_CONST_ATTR_TEMP_SCALE(_string) \ + IIO_CONST_ATTR(in_temp_scale, _string) + +#endif /* _INDUSTRIAL_IO_SYSFS_H_ */ diff --git a/include/linux/iio/trigger.h b/include/linux/iio/trigger.h new file mode 100644 index 0000000..1cfca23 --- /dev/null +++ b/include/linux/iio/trigger.h @@ -0,0 +1,119 @@ +/* The industrial I/O core, trigger handling functions + * + * Copyright (c) 2008 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ +#include +#include + +#ifndef _IIO_TRIGGER_H_ +#define _IIO_TRIGGER_H_ + +struct iio_subirq { + bool enabled; +}; + +/** + * struct iio_trigger_ops - operations structure for an iio_trigger. + * @owner: used to monitor usage count of the trigger. + * @set_trigger_state: switch on/off the trigger on demand + * @try_reenable: function to reenable the trigger when the + * use count is zero (may be NULL) + * @validate_device: function to validate the device when the + * current trigger gets changed. + * + * This is typically static const within a driver and shared by + * instances of a given device. + **/ +struct iio_trigger_ops { + struct module *owner; + int (*set_trigger_state)(struct iio_trigger *trig, bool state); + int (*try_reenable)(struct iio_trigger *trig); + int (*validate_device)(struct iio_trigger *trig, + struct iio_dev *indio_dev); +}; + + +/** + * struct iio_trigger - industrial I/O trigger device + * + * @id: [INTERN] unique id number + * @name: [DRIVER] unique name + * @dev: [DRIVER] associated device (if relevant) + * @private_data: [DRIVER] device specific data + * @list: [INTERN] used in maintenance of global trigger list + * @alloc_list: [DRIVER] used for driver specific trigger list + * @use_count: use count for the trigger + * @subirq_chip: [INTERN] associate 'virtual' irq chip. + * @subirq_base: [INTERN] base number for irqs provided by trigger. + * @subirqs: [INTERN] information about the 'child' irqs. + * @pool: [INTERN] bitmap of irqs currently in use. + * @pool_lock: [INTERN] protection of the irq pool. + **/ +struct iio_trigger { + const struct iio_trigger_ops *ops; + int id; + const char *name; + struct device dev; + + void *private_data; + struct list_head list; + struct list_head alloc_list; + int use_count; + + struct irq_chip subirq_chip; + int subirq_base; + + struct iio_subirq subirqs[CONFIG_IIO_CONSUMERS_PER_TRIGGER]; + unsigned long pool[BITS_TO_LONGS(CONFIG_IIO_CONSUMERS_PER_TRIGGER)]; + struct mutex pool_lock; +}; + + +static inline struct iio_trigger *to_iio_trigger(struct device *d) +{ + return container_of(d, struct iio_trigger, dev); +}; + +static inline void iio_put_trigger(struct iio_trigger *trig) +{ + module_put(trig->ops->owner); + put_device(&trig->dev); +}; + +static inline void iio_get_trigger(struct iio_trigger *trig) +{ + get_device(&trig->dev); + __module_get(trig->ops->owner); +}; + +/** + * iio_trigger_register() - register a trigger with the IIO core + * @trig_info: trigger to be registered + **/ +int iio_trigger_register(struct iio_trigger *trig_info); + +/** + * iio_trigger_unregister() - unregister a trigger from the core + * @trig_info: trigger to be unregistered + **/ +void iio_trigger_unregister(struct iio_trigger *trig_info); + +/** + * iio_trigger_poll() - called on a trigger occurring + * @trig: trigger which occurred + * + * Typically called in relevant hardware interrupt handler. + **/ +void iio_trigger_poll(struct iio_trigger *trig, s64 time); +void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time); + +irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private); + +__printf(1, 2) struct iio_trigger *iio_allocate_trigger(const char *fmt, ...); +void iio_free_trigger(struct iio_trigger *trig); + +#endif /* _IIO_TRIGGER_H_ */ diff --git a/include/linux/iio/trigger_consumer.h b/include/linux/iio/trigger_consumer.h new file mode 100644 index 0000000..60d64b3 --- /dev/null +++ b/include/linux/iio/trigger_consumer.h @@ -0,0 +1,52 @@ +/* The industrial I/O core, trigger consumer functions + * + * Copyright (c) 2008-2011 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +/** + * struct iio_poll_func - poll function pair + * + * @indio_dev: data specific to device (passed into poll func) + * @h: the function that is actually run on trigger + * @thread: threaded interrupt part + * @type: the type of interrupt (basically if oneshot) + * @name: name used to identify the trigger consumer. + * @irq: the corresponding irq as allocated from the + * trigger pool + * @timestamp: some devices need a timestamp grabbed as soon + * as possible after the trigger - hence handler + * passes it via here. + **/ +struct iio_poll_func { + struct iio_dev *indio_dev; + irqreturn_t (*h)(int irq, void *p); + irqreturn_t (*thread)(int irq, void *p); + int type; + char *name; + int irq; + s64 timestamp; +}; + + +struct iio_poll_func +*iio_alloc_pollfunc(irqreturn_t (*h)(int irq, void *p), + irqreturn_t (*thread)(int irq, void *p), + int type, + struct iio_dev *indio_dev, + const char *fmt, + ...); +void iio_dealloc_pollfunc(struct iio_poll_func *pf); +irqreturn_t iio_pollfunc_store_time(int irq, void *p); + +void iio_trigger_notify_done(struct iio_trigger *trig); + +/* + * Two functions for common case where all that happens is a pollfunc + * is attached and detached from a trigger + */ +int iio_triggered_buffer_postenable(struct iio_dev *indio_dev); +int iio_triggered_buffer_predisable(struct iio_dev *indio_dev); diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h new file mode 100644 index 0000000..0c32136 --- /dev/null +++ b/include/linux/iio/types.h @@ -0,0 +1,53 @@ +/* industrial I/O data types needed both in and out of kernel + * + * Copyright (c) 2008 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#ifndef _IIO_TYPES_H_ +#define _IIO_TYPES_H_ + +enum iio_chan_type { + /* real channel types */ + IIO_VOLTAGE, + IIO_CURRENT, + IIO_POWER, + IIO_ACCEL, + IIO_ANGL_VEL, + IIO_MAGN, + IIO_LIGHT, + IIO_INTENSITY, + IIO_PROXIMITY, + IIO_TEMP, + IIO_INCLI, + IIO_ROT, + IIO_ANGL, + IIO_TIMESTAMP, + IIO_CAPACITANCE, +}; + +enum iio_modifier { + IIO_NO_MOD, + IIO_MOD_X, + IIO_MOD_Y, + IIO_MOD_Z, + IIO_MOD_X_AND_Y, + IIO_MOD_X_AND_Z, + IIO_MOD_Y_AND_Z, + IIO_MOD_X_AND_Y_AND_Z, + IIO_MOD_X_OR_Y, + IIO_MOD_X_OR_Z, + IIO_MOD_Y_OR_Z, + IIO_MOD_X_OR_Y_OR_Z, + IIO_MOD_LIGHT_BOTH, + IIO_MOD_LIGHT_IR, +}; + +#define IIO_VAL_INT 1 +#define IIO_VAL_INT_PLUS_MICRO 2 +#define IIO_VAL_INT_PLUS_NANO 3 + +#endif /* _IIO_TYPES_H_ */ -- cgit v0.10.2 From a980e046098b0a40eaff5e4e7fcde6cf035b7c06 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 25 Apr 2012 15:54:59 +0100 Subject: IIO: Move the core files to drivers/iio Take the core support + the kfifo buffer implentation out of staging. Whilst we are far from done in improving this subsystem it is now at a stage where the userspae interfaces (provided by the core) can be considered stable. Drivers will follow over a longer time scale. Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/Kconfig b/drivers/Kconfig index d236aef..0265cb1 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -140,4 +140,6 @@ source "drivers/virt/Kconfig" source "drivers/devfreq/Kconfig" +source "drivers/iio/Kconfig" + endmenu diff --git a/drivers/Makefile b/drivers/Makefile index 95952c8..cdbe362 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -134,3 +134,4 @@ obj-$(CONFIG_VIRT_DRIVERS) += virt/ obj-$(CONFIG_HYPERV) += hv/ obj-$(CONFIG_PM_DEVFREQ) += devfreq/ +obj-$(CONFIG_IIO) += iio/ diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig new file mode 100644 index 0000000..3ab7d48 --- /dev/null +++ b/drivers/iio/Kconfig @@ -0,0 +1,51 @@ +# +# Industrial I/O subsytem configuration +# + +menuconfig IIO + tristate "Industrial I/O support" + depends on GENERIC_HARDIRQS + help + The industrial I/O subsystem provides a unified framework for + drivers for many different types of embedded sensors using a + number of different physical interfaces (i2c, spi, etc). See + Documentation/iio for more information. + +if IIO + +config IIO_BUFFER + bool "Enable buffer support within IIO" + help + Provide core support for various buffer based data + acquisition methods. + +if IIO_BUFFER + +config IIO_KFIFO_BUF + select IIO_TRIGGER + tristate "Industrial I/O buffering based on kfifo" + help + A simple fifo based on kfifo. Use this if you want a fifo + rather than a ring buffer. Note that this currently provides + no buffer events so it is up to userspace to work out how + often to read from the buffer. + +endif # IIO_BUFFER + +config IIO_TRIGGER + boolean "Enable triggered sampling support" + help + Provides IIO core support for triggers. Currently these + are used to initialize capture of samples to push into + ring buffers. The triggers are effectively a 'capture + data now' interrupt. + +config IIO_CONSUMERS_PER_TRIGGER + int "Maximum number of consumers per trigger" + depends on IIO_TRIGGER + default "2" + help + This value controls the maximum number of consumers that a + given trigger may handle. Default is 2. + +endif # IIO diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile new file mode 100644 index 0000000..d5fc57d --- /dev/null +++ b/drivers/iio/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for the industrial I/O core. +# + +obj-$(CONFIG_IIO) += industrialio.o +industrialio-y := industrialio-core.o industrialio-event.o inkern.o +industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o +industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o + +obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o diff --git a/drivers/iio/iio_core.h b/drivers/iio/iio_core.h new file mode 100644 index 0000000..f652e6a --- /dev/null +++ b/drivers/iio/iio_core.h @@ -0,0 +1,62 @@ +/* The industrial I/O core function defs. + * + * Copyright (c) 2008 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * These definitions are meant for use only within the IIO core, not individual + * drivers. + */ + +#ifndef _IIO_CORE_H_ +#define _IIO_CORE_H_ +#include +#include + +struct iio_chan_spec; +struct iio_dev; + + +int __iio_add_chan_devattr(const char *postfix, + struct iio_chan_spec const *chan, + ssize_t (*func)(struct device *dev, + struct device_attribute *attr, + char *buf), + ssize_t (*writefunc)(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len), + u64 mask, + bool generic, + struct device *dev, + struct list_head *attr_list); + +/* Event interface flags */ +#define IIO_BUSY_BIT_POS 1 + +#ifdef CONFIG_IIO_BUFFER +struct poll_table_struct; + +unsigned int iio_buffer_poll(struct file *filp, + struct poll_table_struct *wait); +ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf, + size_t n, loff_t *f_ps); + + +#define iio_buffer_poll_addr (&iio_buffer_poll) +#define iio_buffer_read_first_n_outer_addr (&iio_buffer_read_first_n_outer) + +#else + +#define iio_buffer_poll_addr NULL +#define iio_buffer_read_first_n_outer_addr NULL + +#endif + +int iio_device_register_eventset(struct iio_dev *indio_dev); +void iio_device_unregister_eventset(struct iio_dev *indio_dev); +int iio_event_getfd(struct iio_dev *indio_dev); + +#endif diff --git a/drivers/iio/iio_core_trigger.h b/drivers/iio/iio_core_trigger.h new file mode 100644 index 0000000..6f7c56f --- /dev/null +++ b/drivers/iio/iio_core_trigger.h @@ -0,0 +1,46 @@ + +/* The industrial I/O core, trigger consumer handling functions + * + * Copyright (c) 2008 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#ifdef CONFIG_IIO_TRIGGER +/** + * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers + * @indio_dev: iio_dev associated with the device that will consume the trigger + **/ +void iio_device_register_trigger_consumer(struct iio_dev *indio_dev); + +/** + * iio_device_unregister_trigger_consumer() - reverse the registration process + * @indio_dev: iio_dev associated with the device that consumed the trigger + **/ +void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev); + +#else + +/** + * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers + * @indio_dev: iio_dev associated with the device that will consume the trigger + **/ +static int iio_device_register_trigger_consumer(struct iio_dev *indio_dev) +{ + return 0; +}; + +/** + * iio_device_unregister_trigger_consumer() - reverse the registration process + * @indio_dev: iio_dev associated with the device that consumed the trigger + **/ +static void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev) +{ +}; + +#endif /* CONFIG_TRIGGER_CONSUMER */ + + + diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c new file mode 100644 index 0000000..b5b2c38 --- /dev/null +++ b/drivers/iio/industrialio-buffer.c @@ -0,0 +1,755 @@ +/* The industrial I/O core + * + * Copyright (c) 2008 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * Handling of buffer allocation / resizing. + * + * + * Things to look at here. + * - Better memory allocation techniques? + * - Alternative access techniques? + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include "iio_core.h" +#include +#include + +static const char * const iio_endian_prefix[] = { + [IIO_BE] = "be", + [IIO_LE] = "le", +}; + +/** + * iio_buffer_read_first_n_outer() - chrdev read for buffer access + * + * This function relies on all buffer implementations having an + * iio_buffer as their first element. + **/ +ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf, + size_t n, loff_t *f_ps) +{ + struct iio_dev *indio_dev = filp->private_data; + struct iio_buffer *rb = indio_dev->buffer; + + if (!rb || !rb->access->read_first_n) + return -EINVAL; + return rb->access->read_first_n(rb, n, buf); +} + +/** + * iio_buffer_poll() - poll the buffer to find out if it has data + */ +unsigned int iio_buffer_poll(struct file *filp, + struct poll_table_struct *wait) +{ + struct iio_dev *indio_dev = filp->private_data; + struct iio_buffer *rb = indio_dev->buffer; + + poll_wait(filp, &rb->pollq, wait); + if (rb->stufftoread) + return POLLIN | POLLRDNORM; + /* need a way of knowing if there may be enough data... */ + return 0; +} + +void iio_buffer_init(struct iio_buffer *buffer) +{ + INIT_LIST_HEAD(&buffer->demux_list); + init_waitqueue_head(&buffer->pollq); +} +EXPORT_SYMBOL(iio_buffer_init); + +static ssize_t iio_show_scan_index(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%u\n", to_iio_dev_attr(attr)->c->scan_index); +} + +static ssize_t iio_show_fixed_type(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + u8 type = this_attr->c->scan_type.endianness; + + if (type == IIO_CPU) { +#ifdef __LITTLE_ENDIAN + type = IIO_LE; +#else + type = IIO_BE; +#endif + } + return sprintf(buf, "%s:%c%d/%d>>%u\n", + iio_endian_prefix[type], + this_attr->c->scan_type.sign, + this_attr->c->scan_type.realbits, + this_attr->c->scan_type.storagebits, + this_attr->c->scan_type.shift); +} + +static ssize_t iio_scan_el_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + + ret = test_bit(to_iio_dev_attr(attr)->address, + indio_dev->buffer->scan_mask); + + return sprintf(buf, "%d\n", ret); +} + +static int iio_scan_mask_clear(struct iio_buffer *buffer, int bit) +{ + clear_bit(bit, buffer->scan_mask); + return 0; +} + +static ssize_t iio_scan_el_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + int ret; + bool state; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_buffer *buffer = indio_dev->buffer; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = strtobool(buf, &state); + if (ret < 0) + return ret; + mutex_lock(&indio_dev->mlock); + if (iio_buffer_enabled(indio_dev)) { + ret = -EBUSY; + goto error_ret; + } + ret = iio_scan_mask_query(indio_dev, buffer, this_attr->address); + if (ret < 0) + goto error_ret; + if (!state && ret) { + ret = iio_scan_mask_clear(buffer, this_attr->address); + if (ret) + goto error_ret; + } else if (state && !ret) { + ret = iio_scan_mask_set(indio_dev, buffer, this_attr->address); + if (ret) + goto error_ret; + } + +error_ret: + mutex_unlock(&indio_dev->mlock); + + return ret < 0 ? ret : len; + +} + +static ssize_t iio_scan_el_ts_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + return sprintf(buf, "%d\n", indio_dev->buffer->scan_timestamp); +} + +static ssize_t iio_scan_el_ts_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + bool state; + + ret = strtobool(buf, &state); + if (ret < 0) + return ret; + + mutex_lock(&indio_dev->mlock); + if (iio_buffer_enabled(indio_dev)) { + ret = -EBUSY; + goto error_ret; + } + indio_dev->buffer->scan_timestamp = state; + indio_dev->scan_timestamp = state; +error_ret: + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} + +static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + int ret, attrcount = 0; + struct iio_buffer *buffer = indio_dev->buffer; + + ret = __iio_add_chan_devattr("index", + chan, + &iio_show_scan_index, + NULL, + 0, + 0, + &indio_dev->dev, + &buffer->scan_el_dev_attr_list); + if (ret) + goto error_ret; + attrcount++; + ret = __iio_add_chan_devattr("type", + chan, + &iio_show_fixed_type, + NULL, + 0, + 0, + &indio_dev->dev, + &buffer->scan_el_dev_attr_list); + if (ret) + goto error_ret; + attrcount++; + if (chan->type != IIO_TIMESTAMP) + ret = __iio_add_chan_devattr("en", + chan, + &iio_scan_el_show, + &iio_scan_el_store, + chan->scan_index, + 0, + &indio_dev->dev, + &buffer->scan_el_dev_attr_list); + else + ret = __iio_add_chan_devattr("en", + chan, + &iio_scan_el_ts_show, + &iio_scan_el_ts_store, + chan->scan_index, + 0, + &indio_dev->dev, + &buffer->scan_el_dev_attr_list); + attrcount++; + ret = attrcount; +error_ret: + return ret; +} + +static void iio_buffer_remove_and_free_scan_dev_attr(struct iio_dev *indio_dev, + struct iio_dev_attr *p) +{ + kfree(p->dev_attr.attr.name); + kfree(p); +} + +static void __iio_buffer_attr_cleanup(struct iio_dev *indio_dev) +{ + struct iio_dev_attr *p, *n; + struct iio_buffer *buffer = indio_dev->buffer; + + list_for_each_entry_safe(p, n, + &buffer->scan_el_dev_attr_list, l) + iio_buffer_remove_and_free_scan_dev_attr(indio_dev, p); +} + +static const char * const iio_scan_elements_group_name = "scan_elements"; + +int iio_buffer_register(struct iio_dev *indio_dev, + const struct iio_chan_spec *channels, + int num_channels) +{ + struct iio_dev_attr *p; + struct attribute **attr; + struct iio_buffer *buffer = indio_dev->buffer; + int ret, i, attrn, attrcount, attrcount_orig = 0; + + if (buffer->attrs) + indio_dev->groups[indio_dev->groupcounter++] = buffer->attrs; + + if (buffer->scan_el_attrs != NULL) { + attr = buffer->scan_el_attrs->attrs; + while (*attr++ != NULL) + attrcount_orig++; + } + attrcount = attrcount_orig; + INIT_LIST_HEAD(&buffer->scan_el_dev_attr_list); + if (channels) { + /* new magic */ + for (i = 0; i < num_channels; i++) { + /* Establish necessary mask length */ + if (channels[i].scan_index > + (int)indio_dev->masklength - 1) + indio_dev->masklength + = indio_dev->channels[i].scan_index + 1; + + ret = iio_buffer_add_channel_sysfs(indio_dev, + &channels[i]); + if (ret < 0) + goto error_cleanup_dynamic; + attrcount += ret; + if (channels[i].type == IIO_TIMESTAMP) + indio_dev->scan_index_timestamp = + channels[i].scan_index; + } + if (indio_dev->masklength && buffer->scan_mask == NULL) { + buffer->scan_mask = kcalloc(BITS_TO_LONGS(indio_dev->masklength), + sizeof(*buffer->scan_mask), + GFP_KERNEL); + if (buffer->scan_mask == NULL) { + ret = -ENOMEM; + goto error_cleanup_dynamic; + } + } + } + + buffer->scan_el_group.name = iio_scan_elements_group_name; + + buffer->scan_el_group.attrs = kcalloc(attrcount + 1, + sizeof(buffer->scan_el_group.attrs[0]), + GFP_KERNEL); + if (buffer->scan_el_group.attrs == NULL) { + ret = -ENOMEM; + goto error_free_scan_mask; + } + if (buffer->scan_el_attrs) + memcpy(buffer->scan_el_group.attrs, buffer->scan_el_attrs, + sizeof(buffer->scan_el_group.attrs[0])*attrcount_orig); + attrn = attrcount_orig; + + list_for_each_entry(p, &buffer->scan_el_dev_attr_list, l) + buffer->scan_el_group.attrs[attrn++] = &p->dev_attr.attr; + indio_dev->groups[indio_dev->groupcounter++] = &buffer->scan_el_group; + + return 0; + +error_free_scan_mask: + kfree(buffer->scan_mask); +error_cleanup_dynamic: + __iio_buffer_attr_cleanup(indio_dev); + + return ret; +} +EXPORT_SYMBOL(iio_buffer_register); + +void iio_buffer_unregister(struct iio_dev *indio_dev) +{ + kfree(indio_dev->buffer->scan_mask); + kfree(indio_dev->buffer->scan_el_group.attrs); + __iio_buffer_attr_cleanup(indio_dev); +} +EXPORT_SYMBOL(iio_buffer_unregister); + +ssize_t iio_buffer_read_length(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_buffer *buffer = indio_dev->buffer; + + if (buffer->access->get_length) + return sprintf(buf, "%d\n", + buffer->access->get_length(buffer)); + + return 0; +} +EXPORT_SYMBOL(iio_buffer_read_length); + +ssize_t iio_buffer_write_length(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + int ret; + ulong val; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_buffer *buffer = indio_dev->buffer; + + ret = strict_strtoul(buf, 10, &val); + if (ret) + return ret; + + if (buffer->access->get_length) + if (val == buffer->access->get_length(buffer)) + return len; + + mutex_lock(&indio_dev->mlock); + if (iio_buffer_enabled(indio_dev)) { + ret = -EBUSY; + } else { + if (buffer->access->set_length) + buffer->access->set_length(buffer, val); + ret = 0; + } + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} +EXPORT_SYMBOL(iio_buffer_write_length); + +ssize_t iio_buffer_store_enable(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + int ret; + bool requested_state, current_state; + int previous_mode; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_buffer *buffer = indio_dev->buffer; + + mutex_lock(&indio_dev->mlock); + previous_mode = indio_dev->currentmode; + requested_state = !(buf[0] == '0'); + current_state = iio_buffer_enabled(indio_dev); + if (current_state == requested_state) { + printk(KERN_INFO "iio-buffer, current state requested again\n"); + goto done; + } + if (requested_state) { + if (indio_dev->setup_ops->preenable) { + ret = indio_dev->setup_ops->preenable(indio_dev); + if (ret) { + printk(KERN_ERR + "Buffer not started:" + "buffer preenable failed\n"); + goto error_ret; + } + } + if (buffer->access->request_update) { + ret = buffer->access->request_update(buffer); + if (ret) { + printk(KERN_INFO + "Buffer not started:" + "buffer parameter update failed\n"); + goto error_ret; + } + } + /* Definitely possible for devices to support both of these.*/ + if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) { + if (!indio_dev->trig) { + printk(KERN_INFO + "Buffer not started: no trigger\n"); + ret = -EINVAL; + goto error_ret; + } + indio_dev->currentmode = INDIO_BUFFER_TRIGGERED; + } else if (indio_dev->modes & INDIO_BUFFER_HARDWARE) + indio_dev->currentmode = INDIO_BUFFER_HARDWARE; + else { /* should never be reached */ + ret = -EINVAL; + goto error_ret; + } + + if (indio_dev->setup_ops->postenable) { + ret = indio_dev->setup_ops->postenable(indio_dev); + if (ret) { + printk(KERN_INFO + "Buffer not started:" + "postenable failed\n"); + indio_dev->currentmode = previous_mode; + if (indio_dev->setup_ops->postdisable) + indio_dev->setup_ops-> + postdisable(indio_dev); + goto error_ret; + } + } + } else { + if (indio_dev->setup_ops->predisable) { + ret = indio_dev->setup_ops->predisable(indio_dev); + if (ret) + goto error_ret; + } + indio_dev->currentmode = INDIO_DIRECT_MODE; + if (indio_dev->setup_ops->postdisable) { + ret = indio_dev->setup_ops->postdisable(indio_dev); + if (ret) + goto error_ret; + } + } +done: + mutex_unlock(&indio_dev->mlock); + return len; + +error_ret: + mutex_unlock(&indio_dev->mlock); + return ret; +} +EXPORT_SYMBOL(iio_buffer_store_enable); + +ssize_t iio_buffer_show_enable(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + return sprintf(buf, "%d\n", iio_buffer_enabled(indio_dev)); +} +EXPORT_SYMBOL(iio_buffer_show_enable); + +/* note NULL used as error indicator as it doesn't make sense. */ +static const unsigned long *iio_scan_mask_match(const unsigned long *av_masks, + unsigned int masklength, + const unsigned long *mask) +{ + if (bitmap_empty(mask, masklength)) + return NULL; + while (*av_masks) { + if (bitmap_subset(mask, av_masks, masklength)) + return av_masks; + av_masks += BITS_TO_LONGS(masklength); + } + return NULL; +} + +static int iio_compute_scan_bytes(struct iio_dev *indio_dev, const long *mask, + bool timestamp) +{ + const struct iio_chan_spec *ch; + unsigned bytes = 0; + int length, i; + + /* How much space will the demuxed element take? */ + for_each_set_bit(i, mask, + indio_dev->masklength) { + ch = iio_find_channel_from_si(indio_dev, i); + length = ch->scan_type.storagebits / 8; + bytes = ALIGN(bytes, length); + bytes += length; + } + if (timestamp) { + ch = iio_find_channel_from_si(indio_dev, + indio_dev->scan_index_timestamp); + length = ch->scan_type.storagebits / 8; + bytes = ALIGN(bytes, length); + bytes += length; + } + return bytes; +} + +int iio_sw_buffer_preenable(struct iio_dev *indio_dev) +{ + struct iio_buffer *buffer = indio_dev->buffer; + dev_dbg(&indio_dev->dev, "%s\n", __func__); + + /* How much space will the demuxed element take? */ + indio_dev->scan_bytes = + iio_compute_scan_bytes(indio_dev, buffer->scan_mask, + buffer->scan_timestamp); + buffer->access->set_bytes_per_datum(buffer, indio_dev->scan_bytes); + + /* What scan mask do we actually have ?*/ + if (indio_dev->available_scan_masks) + indio_dev->active_scan_mask = + iio_scan_mask_match(indio_dev->available_scan_masks, + indio_dev->masklength, + buffer->scan_mask); + else + indio_dev->active_scan_mask = buffer->scan_mask; + iio_update_demux(indio_dev); + + if (indio_dev->info->update_scan_mode) + return indio_dev->info + ->update_scan_mode(indio_dev, + indio_dev->active_scan_mask); + return 0; +} +EXPORT_SYMBOL(iio_sw_buffer_preenable); + +/** + * iio_scan_mask_set() - set particular bit in the scan mask + * @buffer: the buffer whose scan mask we are interested in + * @bit: the bit to be set. + **/ +int iio_scan_mask_set(struct iio_dev *indio_dev, + struct iio_buffer *buffer, int bit) +{ + const unsigned long *mask; + unsigned long *trialmask; + + trialmask = kmalloc(sizeof(*trialmask)* + BITS_TO_LONGS(indio_dev->masklength), + GFP_KERNEL); + + if (trialmask == NULL) + return -ENOMEM; + if (!indio_dev->masklength) { + WARN_ON("trying to set scanmask prior to registering buffer\n"); + kfree(trialmask); + return -EINVAL; + } + bitmap_copy(trialmask, buffer->scan_mask, indio_dev->masklength); + set_bit(bit, trialmask); + + if (indio_dev->available_scan_masks) { + mask = iio_scan_mask_match(indio_dev->available_scan_masks, + indio_dev->masklength, + trialmask); + if (!mask) { + kfree(trialmask); + return -EINVAL; + } + } + bitmap_copy(buffer->scan_mask, trialmask, indio_dev->masklength); + + kfree(trialmask); + + return 0; +}; +EXPORT_SYMBOL_GPL(iio_scan_mask_set); + +int iio_scan_mask_query(struct iio_dev *indio_dev, + struct iio_buffer *buffer, int bit) +{ + if (bit > indio_dev->masklength) + return -EINVAL; + + if (!buffer->scan_mask) + return 0; + + return test_bit(bit, buffer->scan_mask); +}; +EXPORT_SYMBOL_GPL(iio_scan_mask_query); + +/** + * struct iio_demux_table() - table describing demux memcpy ops + * @from: index to copy from + * @to: index to copy to + * @length: how many bytes to copy + * @l: list head used for management + */ +struct iio_demux_table { + unsigned from; + unsigned to; + unsigned length; + struct list_head l; +}; + +static unsigned char *iio_demux(struct iio_buffer *buffer, + unsigned char *datain) +{ + struct iio_demux_table *t; + + if (list_empty(&buffer->demux_list)) + return datain; + list_for_each_entry(t, &buffer->demux_list, l) + memcpy(buffer->demux_bounce + t->to, + datain + t->from, t->length); + + return buffer->demux_bounce; +} + +int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data, + s64 timestamp) +{ + unsigned char *dataout = iio_demux(buffer, data); + + return buffer->access->store_to(buffer, dataout, timestamp); +} +EXPORT_SYMBOL_GPL(iio_push_to_buffer); + +static void iio_buffer_demux_free(struct iio_buffer *buffer) +{ + struct iio_demux_table *p, *q; + list_for_each_entry_safe(p, q, &buffer->demux_list, l) { + list_del(&p->l); + kfree(p); + } +} + +int iio_update_demux(struct iio_dev *indio_dev) +{ + const struct iio_chan_spec *ch; + struct iio_buffer *buffer = indio_dev->buffer; + int ret, in_ind = -1, out_ind, length; + unsigned in_loc = 0, out_loc = 0; + struct iio_demux_table *p; + + /* Clear out any old demux */ + iio_buffer_demux_free(buffer); + kfree(buffer->demux_bounce); + buffer->demux_bounce = NULL; + + /* First work out which scan mode we will actually have */ + if (bitmap_equal(indio_dev->active_scan_mask, + buffer->scan_mask, + indio_dev->masklength)) + return 0; + + /* Now we have the two masks, work from least sig and build up sizes */ + for_each_set_bit(out_ind, + indio_dev->active_scan_mask, + indio_dev->masklength) { + in_ind = find_next_bit(indio_dev->active_scan_mask, + indio_dev->masklength, + in_ind + 1); + while (in_ind != out_ind) { + in_ind = find_next_bit(indio_dev->active_scan_mask, + indio_dev->masklength, + in_ind + 1); + ch = iio_find_channel_from_si(indio_dev, in_ind); + length = ch->scan_type.storagebits/8; + /* Make sure we are aligned */ + in_loc += length; + if (in_loc % length) + in_loc += length - in_loc % length; + } + p = kmalloc(sizeof(*p), GFP_KERNEL); + if (p == NULL) { + ret = -ENOMEM; + goto error_clear_mux_table; + } + ch = iio_find_channel_from_si(indio_dev, in_ind); + length = ch->scan_type.storagebits/8; + if (out_loc % length) + out_loc += length - out_loc % length; + if (in_loc % length) + in_loc += length - in_loc % length; + p->from = in_loc; + p->to = out_loc; + p->length = length; + list_add_tail(&p->l, &buffer->demux_list); + out_loc += length; + in_loc += length; + } + /* Relies on scan_timestamp being last */ + if (buffer->scan_timestamp) { + p = kmalloc(sizeof(*p), GFP_KERNEL); + if (p == NULL) { + ret = -ENOMEM; + goto error_clear_mux_table; + } + ch = iio_find_channel_from_si(indio_dev, + indio_dev->scan_index_timestamp); + length = ch->scan_type.storagebits/8; + if (out_loc % length) + out_loc += length - out_loc % length; + if (in_loc % length) + in_loc += length - in_loc % length; + p->from = in_loc; + p->to = out_loc; + p->length = length; + list_add_tail(&p->l, &buffer->demux_list); + out_loc += length; + in_loc += length; + } + buffer->demux_bounce = kzalloc(out_loc, GFP_KERNEL); + if (buffer->demux_bounce == NULL) { + ret = -ENOMEM; + goto error_clear_mux_table; + } + return 0; + +error_clear_mux_table: + iio_buffer_demux_free(buffer); + + return ret; +} +EXPORT_SYMBOL_GPL(iio_update_demux); diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c new file mode 100644 index 0000000..dd1a6a2 --- /dev/null +++ b/drivers/iio/industrialio-core.c @@ -0,0 +1,912 @@ +/* The industrial I/O core + * + * Copyright (c) 2008 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * Based on elements of hwmon and input subsystems. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "iio_core.h" +#include "iio_core_trigger.h" +#include +#include + +/* IDA to assign each registered device a unique id*/ +static DEFINE_IDA(iio_ida); + +static dev_t iio_devt; + +#define IIO_DEV_MAX 256 +struct bus_type iio_bus_type = { + .name = "iio", +}; +EXPORT_SYMBOL(iio_bus_type); + +static struct dentry *iio_debugfs_dentry; + +static const char * const iio_direction[] = { + [0] = "in", + [1] = "out", +}; + +static const char * const iio_chan_type_name_spec[] = { + [IIO_VOLTAGE] = "voltage", + [IIO_CURRENT] = "current", + [IIO_POWER] = "power", + [IIO_ACCEL] = "accel", + [IIO_ANGL_VEL] = "anglvel", + [IIO_MAGN] = "magn", + [IIO_LIGHT] = "illuminance", + [IIO_INTENSITY] = "intensity", + [IIO_PROXIMITY] = "proximity", + [IIO_TEMP] = "temp", + [IIO_INCLI] = "incli", + [IIO_ROT] = "rot", + [IIO_ANGL] = "angl", + [IIO_TIMESTAMP] = "timestamp", + [IIO_CAPACITANCE] = "capacitance", +}; + +static const char * const iio_modifier_names[] = { + [IIO_MOD_X] = "x", + [IIO_MOD_Y] = "y", + [IIO_MOD_Z] = "z", + [IIO_MOD_LIGHT_BOTH] = "both", + [IIO_MOD_LIGHT_IR] = "ir", +}; + +/* relies on pairs of these shared then separate */ +static const char * const iio_chan_info_postfix[] = { + [IIO_CHAN_INFO_RAW] = "raw", + [IIO_CHAN_INFO_PROCESSED] = "input", + [IIO_CHAN_INFO_SCALE] = "scale", + [IIO_CHAN_INFO_OFFSET] = "offset", + [IIO_CHAN_INFO_CALIBSCALE] = "calibscale", + [IIO_CHAN_INFO_CALIBBIAS] = "calibbias", + [IIO_CHAN_INFO_PEAK] = "peak_raw", + [IIO_CHAN_INFO_PEAK_SCALE] = "peak_scale", + [IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW] = "quadrature_correction_raw", + [IIO_CHAN_INFO_AVERAGE_RAW] = "mean_raw", + [IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY] + = "filter_low_pass_3db_frequency", + [IIO_CHAN_INFO_SAMP_FREQ] = "sampling_frequency", +}; + +const struct iio_chan_spec +*iio_find_channel_from_si(struct iio_dev *indio_dev, int si) +{ + int i; + + for (i = 0; i < indio_dev->num_channels; i++) + if (indio_dev->channels[i].scan_index == si) + return &indio_dev->channels[i]; + return NULL; +} + +/* This turns up an awful lot */ +ssize_t iio_read_const_attr(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%s\n", to_iio_const_attr(attr)->string); +} +EXPORT_SYMBOL(iio_read_const_attr); + +static int __init iio_init(void) +{ + int ret; + + /* Register sysfs bus */ + ret = bus_register(&iio_bus_type); + if (ret < 0) { + printk(KERN_ERR + "%s could not register bus type\n", + __FILE__); + goto error_nothing; + } + + ret = alloc_chrdev_region(&iio_devt, 0, IIO_DEV_MAX, "iio"); + if (ret < 0) { + printk(KERN_ERR "%s: failed to allocate char dev region\n", + __FILE__); + goto error_unregister_bus_type; + } + + iio_debugfs_dentry = debugfs_create_dir("iio", NULL); + + return 0; + +error_unregister_bus_type: + bus_unregister(&iio_bus_type); +error_nothing: + return ret; +} + +static void __exit iio_exit(void) +{ + if (iio_devt) + unregister_chrdev_region(iio_devt, IIO_DEV_MAX); + bus_unregister(&iio_bus_type); + debugfs_remove(iio_debugfs_dentry); +} + +#if defined(CONFIG_DEBUG_FS) +static int iio_debugfs_open(struct inode *inode, struct file *file) +{ + if (inode->i_private) + file->private_data = inode->i_private; + + return 0; +} + +static ssize_t iio_debugfs_read_reg(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct iio_dev *indio_dev = file->private_data; + char buf[20]; + unsigned val = 0; + ssize_t len; + int ret; + + ret = indio_dev->info->debugfs_reg_access(indio_dev, + indio_dev->cached_reg_addr, + 0, &val); + if (ret) + dev_err(indio_dev->dev.parent, "%s: read failed\n", __func__); + + len = snprintf(buf, sizeof(buf), "0x%X\n", val); + + return simple_read_from_buffer(userbuf, count, ppos, buf, len); +} + +static ssize_t iio_debugfs_write_reg(struct file *file, + const char __user *userbuf, size_t count, loff_t *ppos) +{ + struct iio_dev *indio_dev = file->private_data; + unsigned reg, val; + char buf[80]; + int ret; + + count = min_t(size_t, count, (sizeof(buf)-1)); + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + + buf[count] = 0; + + ret = sscanf(buf, "%i %i", ®, &val); + + switch (ret) { + case 1: + indio_dev->cached_reg_addr = reg; + break; + case 2: + indio_dev->cached_reg_addr = reg; + ret = indio_dev->info->debugfs_reg_access(indio_dev, reg, + val, NULL); + if (ret) { + dev_err(indio_dev->dev.parent, "%s: write failed\n", + __func__); + return ret; + } + break; + default: + return -EINVAL; + } + + return count; +} + +static const struct file_operations iio_debugfs_reg_fops = { + .open = iio_debugfs_open, + .read = iio_debugfs_read_reg, + .write = iio_debugfs_write_reg, +}; + +static void iio_device_unregister_debugfs(struct iio_dev *indio_dev) +{ + debugfs_remove_recursive(indio_dev->debugfs_dentry); +} + +static int iio_device_register_debugfs(struct iio_dev *indio_dev) +{ + struct dentry *d; + + if (indio_dev->info->debugfs_reg_access == NULL) + return 0; + + if (IS_ERR(iio_debugfs_dentry)) + return 0; + + indio_dev->debugfs_dentry = + debugfs_create_dir(dev_name(&indio_dev->dev), + iio_debugfs_dentry); + if (IS_ERR(indio_dev->debugfs_dentry)) + return PTR_ERR(indio_dev->debugfs_dentry); + + if (indio_dev->debugfs_dentry == NULL) { + dev_warn(indio_dev->dev.parent, + "Failed to create debugfs directory\n"); + return -EFAULT; + } + + d = debugfs_create_file("direct_reg_access", 0644, + indio_dev->debugfs_dentry, + indio_dev, &iio_debugfs_reg_fops); + if (!d) { + iio_device_unregister_debugfs(indio_dev); + return -ENOMEM; + } + + return 0; +} +#else +static int iio_device_register_debugfs(struct iio_dev *indio_dev) +{ + return 0; +} + +static void iio_device_unregister_debugfs(struct iio_dev *indio_dev) +{ +} +#endif /* CONFIG_DEBUG_FS */ + +static ssize_t iio_read_channel_ext_info(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + const struct iio_chan_spec_ext_info *ext_info; + + ext_info = &this_attr->c->ext_info[this_attr->address]; + + return ext_info->read(indio_dev, this_attr->c, buf); +} + +static ssize_t iio_write_channel_ext_info(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + const struct iio_chan_spec_ext_info *ext_info; + + ext_info = &this_attr->c->ext_info[this_attr->address]; + + return ext_info->write(indio_dev, this_attr->c, buf, len); +} + +static ssize_t iio_read_channel_info(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int val, val2; + int ret = indio_dev->info->read_raw(indio_dev, this_attr->c, + &val, &val2, this_attr->address); + + if (ret < 0) + return ret; + + if (ret == IIO_VAL_INT) + return sprintf(buf, "%d\n", val); + else if (ret == IIO_VAL_INT_PLUS_MICRO) { + if (val2 < 0) + return sprintf(buf, "-%d.%06u\n", val, -val2); + else + return sprintf(buf, "%d.%06u\n", val, val2); + } else if (ret == IIO_VAL_INT_PLUS_NANO) { + if (val2 < 0) + return sprintf(buf, "-%d.%09u\n", val, -val2); + else + return sprintf(buf, "%d.%09u\n", val, val2); + } else + return 0; +} + +static ssize_t iio_write_channel_info(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret, integer = 0, fract = 0, fract_mult = 100000; + bool integer_part = true, negative = false; + + /* Assumes decimal - precision based on number of digits */ + if (!indio_dev->info->write_raw) + return -EINVAL; + + if (indio_dev->info->write_raw_get_fmt) + switch (indio_dev->info->write_raw_get_fmt(indio_dev, + this_attr->c, this_attr->address)) { + case IIO_VAL_INT_PLUS_MICRO: + fract_mult = 100000; + break; + case IIO_VAL_INT_PLUS_NANO: + fract_mult = 100000000; + break; + default: + return -EINVAL; + } + + if (buf[0] == '-') { + negative = true; + buf++; + } + + while (*buf) { + if ('0' <= *buf && *buf <= '9') { + if (integer_part) + integer = integer*10 + *buf - '0'; + else { + fract += fract_mult*(*buf - '0'); + if (fract_mult == 1) + break; + fract_mult /= 10; + } + } else if (*buf == '\n') { + if (*(buf + 1) == '\0') + break; + else + return -EINVAL; + } else if (*buf == '.') { + integer_part = false; + } else { + return -EINVAL; + } + buf++; + } + if (negative) { + if (integer) + integer = -integer; + else + fract = -fract; + } + + ret = indio_dev->info->write_raw(indio_dev, this_attr->c, + integer, fract, this_attr->address); + if (ret) + return ret; + + return len; +} + +static +int __iio_device_attr_init(struct device_attribute *dev_attr, + const char *postfix, + struct iio_chan_spec const *chan, + ssize_t (*readfunc)(struct device *dev, + struct device_attribute *attr, + char *buf), + ssize_t (*writefunc)(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len), + bool generic) +{ + int ret; + char *name_format, *full_postfix; + sysfs_attr_init(&dev_attr->attr); + + /* Build up postfix of __postfix */ + if (chan->modified && !generic) { + if (chan->extend_name) + full_postfix = kasprintf(GFP_KERNEL, "%s_%s_%s", + iio_modifier_names[chan + ->channel2], + chan->extend_name, + postfix); + else + full_postfix = kasprintf(GFP_KERNEL, "%s_%s", + iio_modifier_names[chan + ->channel2], + postfix); + } else { + if (chan->extend_name == NULL) + full_postfix = kstrdup(postfix, GFP_KERNEL); + else + full_postfix = kasprintf(GFP_KERNEL, + "%s_%s", + chan->extend_name, + postfix); + } + if (full_postfix == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + if (chan->differential) { /* Differential can not have modifier */ + if (generic) + name_format + = kasprintf(GFP_KERNEL, "%s_%s-%s_%s", + iio_direction[chan->output], + iio_chan_type_name_spec[chan->type], + iio_chan_type_name_spec[chan->type], + full_postfix); + else if (chan->indexed) + name_format + = kasprintf(GFP_KERNEL, "%s_%s%d-%s%d_%s", + iio_direction[chan->output], + iio_chan_type_name_spec[chan->type], + chan->channel, + iio_chan_type_name_spec[chan->type], + chan->channel2, + full_postfix); + else { + WARN_ON("Differential channels must be indexed\n"); + ret = -EINVAL; + goto error_free_full_postfix; + } + } else { /* Single ended */ + if (generic) + name_format + = kasprintf(GFP_KERNEL, "%s_%s_%s", + iio_direction[chan->output], + iio_chan_type_name_spec[chan->type], + full_postfix); + else if (chan->indexed) + name_format + = kasprintf(GFP_KERNEL, "%s_%s%d_%s", + iio_direction[chan->output], + iio_chan_type_name_spec[chan->type], + chan->channel, + full_postfix); + else + name_format + = kasprintf(GFP_KERNEL, "%s_%s_%s", + iio_direction[chan->output], + iio_chan_type_name_spec[chan->type], + full_postfix); + } + if (name_format == NULL) { + ret = -ENOMEM; + goto error_free_full_postfix; + } + dev_attr->attr.name = kasprintf(GFP_KERNEL, + name_format, + chan->channel, + chan->channel2); + if (dev_attr->attr.name == NULL) { + ret = -ENOMEM; + goto error_free_name_format; + } + + if (readfunc) { + dev_attr->attr.mode |= S_IRUGO; + dev_attr->show = readfunc; + } + + if (writefunc) { + dev_attr->attr.mode |= S_IWUSR; + dev_attr->store = writefunc; + } + kfree(name_format); + kfree(full_postfix); + + return 0; + +error_free_name_format: + kfree(name_format); +error_free_full_postfix: + kfree(full_postfix); +error_ret: + return ret; +} + +static void __iio_device_attr_deinit(struct device_attribute *dev_attr) +{ + kfree(dev_attr->attr.name); +} + +int __iio_add_chan_devattr(const char *postfix, + struct iio_chan_spec const *chan, + ssize_t (*readfunc)(struct device *dev, + struct device_attribute *attr, + char *buf), + ssize_t (*writefunc)(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len), + u64 mask, + bool generic, + struct device *dev, + struct list_head *attr_list) +{ + int ret; + struct iio_dev_attr *iio_attr, *t; + + iio_attr = kzalloc(sizeof *iio_attr, GFP_KERNEL); + if (iio_attr == NULL) { + ret = -ENOMEM; + goto error_ret; + } + ret = __iio_device_attr_init(&iio_attr->dev_attr, + postfix, chan, + readfunc, writefunc, generic); + if (ret) + goto error_iio_dev_attr_free; + iio_attr->c = chan; + iio_attr->address = mask; + list_for_each_entry(t, attr_list, l) + if (strcmp(t->dev_attr.attr.name, + iio_attr->dev_attr.attr.name) == 0) { + if (!generic) + dev_err(dev, "tried to double register : %s\n", + t->dev_attr.attr.name); + ret = -EBUSY; + goto error_device_attr_deinit; + } + list_add(&iio_attr->l, attr_list); + + return 0; + +error_device_attr_deinit: + __iio_device_attr_deinit(&iio_attr->dev_attr); +error_iio_dev_attr_free: + kfree(iio_attr); +error_ret: + return ret; +} + +static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan) +{ + int ret, attrcount = 0; + int i; + const struct iio_chan_spec_ext_info *ext_info; + + if (chan->channel < 0) + return 0; + for_each_set_bit(i, &chan->info_mask, sizeof(long)*8) { + ret = __iio_add_chan_devattr(iio_chan_info_postfix[i/2], + chan, + &iio_read_channel_info, + &iio_write_channel_info, + i/2, + !(i%2), + &indio_dev->dev, + &indio_dev->channel_attr_list); + if (ret == -EBUSY && (i%2 == 0)) { + ret = 0; + continue; + } + if (ret < 0) + goto error_ret; + attrcount++; + } + + if (chan->ext_info) { + unsigned int i = 0; + for (ext_info = chan->ext_info; ext_info->name; ext_info++) { + ret = __iio_add_chan_devattr(ext_info->name, + chan, + ext_info->read ? + &iio_read_channel_ext_info : NULL, + ext_info->write ? + &iio_write_channel_ext_info : NULL, + i, + ext_info->shared, + &indio_dev->dev, + &indio_dev->channel_attr_list); + i++; + if (ret == -EBUSY && ext_info->shared) + continue; + + if (ret) + goto error_ret; + + attrcount++; + } + } + + ret = attrcount; +error_ret: + return ret; +} + +static void iio_device_remove_and_free_read_attr(struct iio_dev *indio_dev, + struct iio_dev_attr *p) +{ + kfree(p->dev_attr.attr.name); + kfree(p); +} + +static ssize_t iio_show_dev_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + return sprintf(buf, "%s\n", indio_dev->name); +} + +static DEVICE_ATTR(name, S_IRUGO, iio_show_dev_name, NULL); + +static int iio_device_register_sysfs(struct iio_dev *indio_dev) +{ + int i, ret = 0, attrcount, attrn, attrcount_orig = 0; + struct iio_dev_attr *p, *n; + struct attribute **attr; + + /* First count elements in any existing group */ + if (indio_dev->info->attrs) { + attr = indio_dev->info->attrs->attrs; + while (*attr++ != NULL) + attrcount_orig++; + } + attrcount = attrcount_orig; + /* + * New channel registration method - relies on the fact a group does + * not need to be initialized if it is name is NULL. + */ + INIT_LIST_HEAD(&indio_dev->channel_attr_list); + if (indio_dev->channels) + for (i = 0; i < indio_dev->num_channels; i++) { + ret = iio_device_add_channel_sysfs(indio_dev, + &indio_dev + ->channels[i]); + if (ret < 0) + goto error_clear_attrs; + attrcount += ret; + } + + if (indio_dev->name) + attrcount++; + + indio_dev->chan_attr_group.attrs = kcalloc(attrcount + 1, + sizeof(indio_dev->chan_attr_group.attrs[0]), + GFP_KERNEL); + if (indio_dev->chan_attr_group.attrs == NULL) { + ret = -ENOMEM; + goto error_clear_attrs; + } + /* Copy across original attributes */ + if (indio_dev->info->attrs) + memcpy(indio_dev->chan_attr_group.attrs, + indio_dev->info->attrs->attrs, + sizeof(indio_dev->chan_attr_group.attrs[0]) + *attrcount_orig); + attrn = attrcount_orig; + /* Add all elements from the list. */ + list_for_each_entry(p, &indio_dev->channel_attr_list, l) + indio_dev->chan_attr_group.attrs[attrn++] = &p->dev_attr.attr; + if (indio_dev->name) + indio_dev->chan_attr_group.attrs[attrn++] = &dev_attr_name.attr; + + indio_dev->groups[indio_dev->groupcounter++] = + &indio_dev->chan_attr_group; + + return 0; + +error_clear_attrs: + list_for_each_entry_safe(p, n, + &indio_dev->channel_attr_list, l) { + list_del(&p->l); + iio_device_remove_and_free_read_attr(indio_dev, p); + } + + return ret; +} + +static void iio_device_unregister_sysfs(struct iio_dev *indio_dev) +{ + + struct iio_dev_attr *p, *n; + + list_for_each_entry_safe(p, n, &indio_dev->channel_attr_list, l) { + list_del(&p->l); + iio_device_remove_and_free_read_attr(indio_dev, p); + } + kfree(indio_dev->chan_attr_group.attrs); +} + +static void iio_dev_release(struct device *device) +{ + struct iio_dev *indio_dev = container_of(device, struct iio_dev, dev); + cdev_del(&indio_dev->chrdev); + if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) + iio_device_unregister_trigger_consumer(indio_dev); + iio_device_unregister_eventset(indio_dev); + iio_device_unregister_sysfs(indio_dev); + iio_device_unregister_debugfs(indio_dev); +} + +static struct device_type iio_dev_type = { + .name = "iio_device", + .release = iio_dev_release, +}; + +struct iio_dev *iio_allocate_device(int sizeof_priv) +{ + struct iio_dev *dev; + size_t alloc_size; + + alloc_size = sizeof(struct iio_dev); + if (sizeof_priv) { + alloc_size = ALIGN(alloc_size, IIO_ALIGN); + alloc_size += sizeof_priv; + } + /* ensure 32-byte alignment of whole construct ? */ + alloc_size += IIO_ALIGN - 1; + + dev = kzalloc(alloc_size, GFP_KERNEL); + + if (dev) { + dev->dev.groups = dev->groups; + dev->dev.type = &iio_dev_type; + dev->dev.bus = &iio_bus_type; + device_initialize(&dev->dev); + dev_set_drvdata(&dev->dev, (void *)dev); + mutex_init(&dev->mlock); + mutex_init(&dev->info_exist_lock); + + dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL); + if (dev->id < 0) { + /* cannot use a dev_err as the name isn't available */ + printk(KERN_ERR "Failed to get id\n"); + kfree(dev); + return NULL; + } + dev_set_name(&dev->dev, "iio:device%d", dev->id); + } + + return dev; +} +EXPORT_SYMBOL(iio_allocate_device); + +void iio_free_device(struct iio_dev *dev) +{ + if (dev) { + ida_simple_remove(&iio_ida, dev->id); + kfree(dev); + } +} +EXPORT_SYMBOL(iio_free_device); + +/** + * iio_chrdev_open() - chrdev file open for buffer access and ioctls + **/ +static int iio_chrdev_open(struct inode *inode, struct file *filp) +{ + struct iio_dev *indio_dev = container_of(inode->i_cdev, + struct iio_dev, chrdev); + + if (test_and_set_bit(IIO_BUSY_BIT_POS, &indio_dev->flags)) + return -EBUSY; + + filp->private_data = indio_dev; + + return 0; +} + +/** + * iio_chrdev_release() - chrdev file close buffer access and ioctls + **/ +static int iio_chrdev_release(struct inode *inode, struct file *filp) +{ + struct iio_dev *indio_dev = container_of(inode->i_cdev, + struct iio_dev, chrdev); + clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags); + return 0; +} + +/* Somewhat of a cross file organization violation - ioctls here are actually + * event related */ +static long iio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct iio_dev *indio_dev = filp->private_data; + int __user *ip = (int __user *)arg; + int fd; + + if (cmd == IIO_GET_EVENT_FD_IOCTL) { + fd = iio_event_getfd(indio_dev); + if (copy_to_user(ip, &fd, sizeof(fd))) + return -EFAULT; + return 0; + } + return -EINVAL; +} + +static const struct file_operations iio_buffer_fileops = { + .read = iio_buffer_read_first_n_outer_addr, + .release = iio_chrdev_release, + .open = iio_chrdev_open, + .poll = iio_buffer_poll_addr, + .owner = THIS_MODULE, + .llseek = noop_llseek, + .unlocked_ioctl = iio_ioctl, + .compat_ioctl = iio_ioctl, +}; + +static const struct iio_buffer_setup_ops noop_ring_setup_ops; + +int iio_device_register(struct iio_dev *indio_dev) +{ + int ret; + + /* configure elements for the chrdev */ + indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), indio_dev->id); + + ret = iio_device_register_debugfs(indio_dev); + if (ret) { + dev_err(indio_dev->dev.parent, + "Failed to register debugfs interfaces\n"); + goto error_ret; + } + ret = iio_device_register_sysfs(indio_dev); + if (ret) { + dev_err(indio_dev->dev.parent, + "Failed to register sysfs interfaces\n"); + goto error_unreg_debugfs; + } + ret = iio_device_register_eventset(indio_dev); + if (ret) { + dev_err(indio_dev->dev.parent, + "Failed to register event set\n"); + goto error_free_sysfs; + } + if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) + iio_device_register_trigger_consumer(indio_dev); + + if ((indio_dev->modes & INDIO_ALL_BUFFER_MODES) && + indio_dev->setup_ops == NULL) + indio_dev->setup_ops = &noop_ring_setup_ops; + + ret = device_add(&indio_dev->dev); + if (ret < 0) + goto error_unreg_eventset; + cdev_init(&indio_dev->chrdev, &iio_buffer_fileops); + indio_dev->chrdev.owner = indio_dev->info->driver_module; + ret = cdev_add(&indio_dev->chrdev, indio_dev->dev.devt, 1); + if (ret < 0) + goto error_del_device; + return 0; + +error_del_device: + device_del(&indio_dev->dev); +error_unreg_eventset: + iio_device_unregister_eventset(indio_dev); +error_free_sysfs: + iio_device_unregister_sysfs(indio_dev); +error_unreg_debugfs: + iio_device_unregister_debugfs(indio_dev); +error_ret: + return ret; +} +EXPORT_SYMBOL(iio_device_register); + +void iio_device_unregister(struct iio_dev *indio_dev) +{ + mutex_lock(&indio_dev->info_exist_lock); + indio_dev->info = NULL; + mutex_unlock(&indio_dev->info_exist_lock); + device_unregister(&indio_dev->dev); +} +EXPORT_SYMBOL(iio_device_unregister); +subsys_initcall(iio_init); +module_exit(iio_exit); + +MODULE_AUTHOR("Jonathan Cameron "); +MODULE_DESCRIPTION("Industrial I/O core"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c new file mode 100644 index 0000000..5fcf50b --- /dev/null +++ b/drivers/iio/industrialio-event.c @@ -0,0 +1,453 @@ +/* Industrial I/O event handling + * + * Copyright (c) 2008 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * Based on elements of hwmon and input subsystems. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "iio_core.h" +#include +#include + +/** + * struct iio_event_interface - chrdev interface for an event line + * @wait: wait queue to allow blocking reads of events + * @det_events: list of detected events + * @dev_attr_list: list of event interface sysfs attribute + * @flags: file operations related flags including busy flag. + * @group: event interface sysfs attribute group + */ +struct iio_event_interface { + wait_queue_head_t wait; + DECLARE_KFIFO(det_events, struct iio_event_data, 16); + + struct list_head dev_attr_list; + unsigned long flags; + struct attribute_group group; +}; + +int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp) +{ + struct iio_event_interface *ev_int = indio_dev->event_interface; + struct iio_event_data ev; + int copied; + + /* Does anyone care? */ + spin_lock(&ev_int->wait.lock); + if (test_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { + + ev.id = ev_code; + ev.timestamp = timestamp; + + copied = kfifo_put(&ev_int->det_events, &ev); + if (copied != 0) + wake_up_locked_poll(&ev_int->wait, POLLIN); + } + spin_unlock(&ev_int->wait.lock); + + return 0; +} +EXPORT_SYMBOL(iio_push_event); + +/** + * iio_event_poll() - poll the event queue to find out if it has data + */ +static unsigned int iio_event_poll(struct file *filep, + struct poll_table_struct *wait) +{ + struct iio_event_interface *ev_int = filep->private_data; + unsigned int events = 0; + + poll_wait(filep, &ev_int->wait, wait); + + spin_lock(&ev_int->wait.lock); + if (!kfifo_is_empty(&ev_int->det_events)) + events = POLLIN | POLLRDNORM; + spin_unlock(&ev_int->wait.lock); + + return events; +} + +static ssize_t iio_event_chrdev_read(struct file *filep, + char __user *buf, + size_t count, + loff_t *f_ps) +{ + struct iio_event_interface *ev_int = filep->private_data; + unsigned int copied; + int ret; + + if (count < sizeof(struct iio_event_data)) + return -EINVAL; + + spin_lock(&ev_int->wait.lock); + if (kfifo_is_empty(&ev_int->det_events)) { + if (filep->f_flags & O_NONBLOCK) { + ret = -EAGAIN; + goto error_unlock; + } + /* Blocking on device; waiting for something to be there */ + ret = wait_event_interruptible_locked(ev_int->wait, + !kfifo_is_empty(&ev_int->det_events)); + if (ret) + goto error_unlock; + /* Single access device so no one else can get the data */ + } + + ret = kfifo_to_user(&ev_int->det_events, buf, count, &copied); + +error_unlock: + spin_unlock(&ev_int->wait.lock); + + return ret ? ret : copied; +} + +static int iio_event_chrdev_release(struct inode *inode, struct file *filep) +{ + struct iio_event_interface *ev_int = filep->private_data; + + spin_lock(&ev_int->wait.lock); + __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); + /* + * In order to maintain a clean state for reopening, + * clear out any awaiting events. The mask will prevent + * any new __iio_push_event calls running. + */ + kfifo_reset_out(&ev_int->det_events); + spin_unlock(&ev_int->wait.lock); + + return 0; +} + +static const struct file_operations iio_event_chrdev_fileops = { + .read = iio_event_chrdev_read, + .poll = iio_event_poll, + .release = iio_event_chrdev_release, + .owner = THIS_MODULE, + .llseek = noop_llseek, +}; + +int iio_event_getfd(struct iio_dev *indio_dev) +{ + struct iio_event_interface *ev_int = indio_dev->event_interface; + int fd; + + if (ev_int == NULL) + return -ENODEV; + + spin_lock(&ev_int->wait.lock); + if (__test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { + spin_unlock(&ev_int->wait.lock); + return -EBUSY; + } + spin_unlock(&ev_int->wait.lock); + fd = anon_inode_getfd("iio:event", + &iio_event_chrdev_fileops, ev_int, O_RDONLY); + if (fd < 0) { + spin_lock(&ev_int->wait.lock); + __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); + spin_unlock(&ev_int->wait.lock); + } + return fd; +} + +static const char * const iio_ev_type_text[] = { + [IIO_EV_TYPE_THRESH] = "thresh", + [IIO_EV_TYPE_MAG] = "mag", + [IIO_EV_TYPE_ROC] = "roc", + [IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive", + [IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive", +}; + +static const char * const iio_ev_dir_text[] = { + [IIO_EV_DIR_EITHER] = "either", + [IIO_EV_DIR_RISING] = "rising", + [IIO_EV_DIR_FALLING] = "falling" +}; + +static ssize_t iio_ev_state_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + bool val; + + ret = strtobool(buf, &val); + if (ret < 0) + return ret; + + ret = indio_dev->info->write_event_config(indio_dev, + this_attr->address, + val); + return (ret < 0) ? ret : len; +} + +static ssize_t iio_ev_state_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int val = indio_dev->info->read_event_config(indio_dev, + this_attr->address); + + if (val < 0) + return val; + else + return sprintf(buf, "%d\n", val); +} + +static ssize_t iio_ev_value_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int val, ret; + + ret = indio_dev->info->read_event_value(indio_dev, + this_attr->address, &val); + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", val); +} + +static ssize_t iio_ev_value_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + unsigned long val; + int ret; + + if (!indio_dev->info->write_event_value) + return -EINVAL; + + ret = strict_strtoul(buf, 10, &val); + if (ret) + return ret; + + ret = indio_dev->info->write_event_value(indio_dev, this_attr->address, + val); + if (ret < 0) + return ret; + + return len; +} + +static int iio_device_add_event_sysfs(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan) +{ + int ret = 0, i, attrcount = 0; + u64 mask = 0; + char *postfix; + if (!chan->event_mask) + return 0; + + for_each_set_bit(i, &chan->event_mask, sizeof(chan->event_mask)*8) { + postfix = kasprintf(GFP_KERNEL, "%s_%s_en", + iio_ev_type_text[i/IIO_EV_DIR_MAX], + iio_ev_dir_text[i%IIO_EV_DIR_MAX]); + if (postfix == NULL) { + ret = -ENOMEM; + goto error_ret; + } + if (chan->modified) + mask = IIO_MOD_EVENT_CODE(chan->type, 0, chan->channel, + i/IIO_EV_DIR_MAX, + i%IIO_EV_DIR_MAX); + else if (chan->differential) + mask = IIO_EVENT_CODE(chan->type, + 0, 0, + i%IIO_EV_DIR_MAX, + i/IIO_EV_DIR_MAX, + 0, + chan->channel, + chan->channel2); + else + mask = IIO_UNMOD_EVENT_CODE(chan->type, + chan->channel, + i/IIO_EV_DIR_MAX, + i%IIO_EV_DIR_MAX); + + ret = __iio_add_chan_devattr(postfix, + chan, + &iio_ev_state_show, + iio_ev_state_store, + mask, + 0, + &indio_dev->dev, + &indio_dev->event_interface-> + dev_attr_list); + kfree(postfix); + if (ret) + goto error_ret; + attrcount++; + postfix = kasprintf(GFP_KERNEL, "%s_%s_value", + iio_ev_type_text[i/IIO_EV_DIR_MAX], + iio_ev_dir_text[i%IIO_EV_DIR_MAX]); + if (postfix == NULL) { + ret = -ENOMEM; + goto error_ret; + } + ret = __iio_add_chan_devattr(postfix, chan, + iio_ev_value_show, + iio_ev_value_store, + mask, + 0, + &indio_dev->dev, + &indio_dev->event_interface-> + dev_attr_list); + kfree(postfix); + if (ret) + goto error_ret; + attrcount++; + } + ret = attrcount; +error_ret: + return ret; +} + +static inline void __iio_remove_event_config_attrs(struct iio_dev *indio_dev) +{ + struct iio_dev_attr *p, *n; + list_for_each_entry_safe(p, n, + &indio_dev->event_interface-> + dev_attr_list, l) { + kfree(p->dev_attr.attr.name); + kfree(p); + } +} + +static inline int __iio_add_event_config_attrs(struct iio_dev *indio_dev) +{ + int j, ret, attrcount = 0; + + INIT_LIST_HEAD(&indio_dev->event_interface->dev_attr_list); + /* Dynically created from the channels array */ + for (j = 0; j < indio_dev->num_channels; j++) { + ret = iio_device_add_event_sysfs(indio_dev, + &indio_dev->channels[j]); + if (ret < 0) + goto error_clear_attrs; + attrcount += ret; + } + return attrcount; + +error_clear_attrs: + __iio_remove_event_config_attrs(indio_dev); + + return ret; +} + +static bool iio_check_for_dynamic_events(struct iio_dev *indio_dev) +{ + int j; + + for (j = 0; j < indio_dev->num_channels; j++) + if (indio_dev->channels[j].event_mask != 0) + return true; + return false; +} + +static void iio_setup_ev_int(struct iio_event_interface *ev_int) +{ + INIT_KFIFO(ev_int->det_events); + init_waitqueue_head(&ev_int->wait); +} + +static const char *iio_event_group_name = "events"; +int iio_device_register_eventset(struct iio_dev *indio_dev) +{ + struct iio_dev_attr *p; + int ret = 0, attrcount_orig = 0, attrcount, attrn; + struct attribute **attr; + + if (!(indio_dev->info->event_attrs || + iio_check_for_dynamic_events(indio_dev))) + return 0; + + indio_dev->event_interface = + kzalloc(sizeof(struct iio_event_interface), GFP_KERNEL); + if (indio_dev->event_interface == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + iio_setup_ev_int(indio_dev->event_interface); + if (indio_dev->info->event_attrs != NULL) { + attr = indio_dev->info->event_attrs->attrs; + while (*attr++ != NULL) + attrcount_orig++; + } + attrcount = attrcount_orig; + if (indio_dev->channels) { + ret = __iio_add_event_config_attrs(indio_dev); + if (ret < 0) + goto error_free_setup_event_lines; + attrcount += ret; + } + + indio_dev->event_interface->group.name = iio_event_group_name; + indio_dev->event_interface->group.attrs = kcalloc(attrcount + 1, + sizeof(indio_dev->event_interface->group.attrs[0]), + GFP_KERNEL); + if (indio_dev->event_interface->group.attrs == NULL) { + ret = -ENOMEM; + goto error_free_setup_event_lines; + } + if (indio_dev->info->event_attrs) + memcpy(indio_dev->event_interface->group.attrs, + indio_dev->info->event_attrs->attrs, + sizeof(indio_dev->event_interface->group.attrs[0]) + *attrcount_orig); + attrn = attrcount_orig; + /* Add all elements from the list. */ + list_for_each_entry(p, + &indio_dev->event_interface->dev_attr_list, + l) + indio_dev->event_interface->group.attrs[attrn++] = + &p->dev_attr.attr; + indio_dev->groups[indio_dev->groupcounter++] = + &indio_dev->event_interface->group; + + return 0; + +error_free_setup_event_lines: + __iio_remove_event_config_attrs(indio_dev); + kfree(indio_dev->event_interface); +error_ret: + + return ret; +} + +void iio_device_unregister_eventset(struct iio_dev *indio_dev) +{ + if (indio_dev->event_interface == NULL) + return; + __iio_remove_event_config_attrs(indio_dev); + kfree(indio_dev->event_interface->group.attrs); + kfree(indio_dev->event_interface); +} diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c new file mode 100644 index 0000000..03fee2e --- /dev/null +++ b/drivers/iio/industrialio-trigger.c @@ -0,0 +1,509 @@ +/* The industrial I/O core, trigger handling functions + * + * Copyright (c) 2008 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "iio_core.h" +#include "iio_core_trigger.h" +#include + +/* RFC - Question of approach + * Make the common case (single sensor single trigger) + * simple by starting trigger capture from when first sensors + * is added. + * + * Complex simultaneous start requires use of 'hold' functionality + * of the trigger. (not implemented) + * + * Any other suggestions? + */ + +static DEFINE_IDA(iio_trigger_ida); + +/* Single list of all available triggers */ +static LIST_HEAD(iio_trigger_list); +static DEFINE_MUTEX(iio_trigger_list_lock); + +/** + * iio_trigger_read_name() - retrieve useful identifying name + **/ +static ssize_t iio_trigger_read_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_trigger *trig = dev_get_drvdata(dev); + return sprintf(buf, "%s\n", trig->name); +} + +static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL); + +/** + * iio_trigger_register_sysfs() - create a device for this trigger + * @trig_info: the trigger + * + * Also adds any control attribute registered by the trigger driver + **/ +static int iio_trigger_register_sysfs(struct iio_trigger *trig_info) +{ + return sysfs_add_file_to_group(&trig_info->dev.kobj, + &dev_attr_name.attr, + NULL); +} + +static void iio_trigger_unregister_sysfs(struct iio_trigger *trig_info) +{ + sysfs_remove_file_from_group(&trig_info->dev.kobj, + &dev_attr_name.attr, + NULL); +} + +int iio_trigger_register(struct iio_trigger *trig_info) +{ + int ret; + + trig_info->id = ida_simple_get(&iio_trigger_ida, 0, 0, GFP_KERNEL); + if (trig_info->id < 0) { + ret = trig_info->id; + goto error_ret; + } + /* Set the name used for the sysfs directory etc */ + dev_set_name(&trig_info->dev, "trigger%ld", + (unsigned long) trig_info->id); + + ret = device_add(&trig_info->dev); + if (ret) + goto error_unregister_id; + + ret = iio_trigger_register_sysfs(trig_info); + if (ret) + goto error_device_del; + + /* Add to list of available triggers held by the IIO core */ + mutex_lock(&iio_trigger_list_lock); + list_add_tail(&trig_info->list, &iio_trigger_list); + mutex_unlock(&iio_trigger_list_lock); + + return 0; + +error_device_del: + device_del(&trig_info->dev); +error_unregister_id: + ida_simple_remove(&iio_trigger_ida, trig_info->id); +error_ret: + return ret; +} +EXPORT_SYMBOL(iio_trigger_register); + +void iio_trigger_unregister(struct iio_trigger *trig_info) +{ + mutex_lock(&iio_trigger_list_lock); + list_del(&trig_info->list); + mutex_unlock(&iio_trigger_list_lock); + + iio_trigger_unregister_sysfs(trig_info); + ida_simple_remove(&iio_trigger_ida, trig_info->id); + /* Possible issue in here */ + device_unregister(&trig_info->dev); +} +EXPORT_SYMBOL(iio_trigger_unregister); + +static struct iio_trigger *iio_trigger_find_by_name(const char *name, + size_t len) +{ + struct iio_trigger *trig = NULL, *iter; + + mutex_lock(&iio_trigger_list_lock); + list_for_each_entry(iter, &iio_trigger_list, list) + if (sysfs_streq(iter->name, name)) { + trig = iter; + break; + } + mutex_unlock(&iio_trigger_list_lock); + + return trig; +} + +void iio_trigger_poll(struct iio_trigger *trig, s64 time) +{ + int i; + if (!trig->use_count) + for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) + if (trig->subirqs[i].enabled) { + trig->use_count++; + generic_handle_irq(trig->subirq_base + i); + } +} +EXPORT_SYMBOL(iio_trigger_poll); + +irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private) +{ + iio_trigger_poll(private, iio_get_time_ns()); + return IRQ_HANDLED; +} +EXPORT_SYMBOL(iio_trigger_generic_data_rdy_poll); + +void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time) +{ + int i; + if (!trig->use_count) + for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) + if (trig->subirqs[i].enabled) { + trig->use_count++; + handle_nested_irq(trig->subirq_base + i); + } +} +EXPORT_SYMBOL(iio_trigger_poll_chained); + +void iio_trigger_notify_done(struct iio_trigger *trig) +{ + trig->use_count--; + if (trig->use_count == 0 && trig->ops && trig->ops->try_reenable) + if (trig->ops->try_reenable(trig)) + /* Missed and interrupt so launch new poll now */ + iio_trigger_poll(trig, 0); +} +EXPORT_SYMBOL(iio_trigger_notify_done); + +/* Trigger Consumer related functions */ +static int iio_trigger_get_irq(struct iio_trigger *trig) +{ + int ret; + mutex_lock(&trig->pool_lock); + ret = bitmap_find_free_region(trig->pool, + CONFIG_IIO_CONSUMERS_PER_TRIGGER, + ilog2(1)); + mutex_unlock(&trig->pool_lock); + if (ret >= 0) + ret += trig->subirq_base; + + return ret; +} + +static void iio_trigger_put_irq(struct iio_trigger *trig, int irq) +{ + mutex_lock(&trig->pool_lock); + clear_bit(irq - trig->subirq_base, trig->pool); + mutex_unlock(&trig->pool_lock); +} + +/* Complexity in here. With certain triggers (datardy) an acknowledgement + * may be needed if the pollfuncs do not include the data read for the + * triggering device. + * This is not currently handled. Alternative of not enabling trigger unless + * the relevant function is in there may be the best option. + */ +/* Worth protecting against double additions?*/ +static int iio_trigger_attach_poll_func(struct iio_trigger *trig, + struct iio_poll_func *pf) +{ + int ret = 0; + bool notinuse + = bitmap_empty(trig->pool, CONFIG_IIO_CONSUMERS_PER_TRIGGER); + + /* Prevent the module being removed whilst attached to a trigger */ + __module_get(pf->indio_dev->info->driver_module); + pf->irq = iio_trigger_get_irq(trig); + ret = request_threaded_irq(pf->irq, pf->h, pf->thread, + pf->type, pf->name, + pf); + if (ret < 0) { + module_put(pf->indio_dev->info->driver_module); + return ret; + } + + if (trig->ops && trig->ops->set_trigger_state && notinuse) { + ret = trig->ops->set_trigger_state(trig, true); + if (ret < 0) + module_put(pf->indio_dev->info->driver_module); + } + + return ret; +} + +static int iio_trigger_dettach_poll_func(struct iio_trigger *trig, + struct iio_poll_func *pf) +{ + int ret = 0; + bool no_other_users + = (bitmap_weight(trig->pool, + CONFIG_IIO_CONSUMERS_PER_TRIGGER) + == 1); + if (trig->ops && trig->ops->set_trigger_state && no_other_users) { + ret = trig->ops->set_trigger_state(trig, false); + if (ret) + goto error_ret; + } + iio_trigger_put_irq(trig, pf->irq); + free_irq(pf->irq, pf); + module_put(pf->indio_dev->info->driver_module); + +error_ret: + return ret; +} + +irqreturn_t iio_pollfunc_store_time(int irq, void *p) +{ + struct iio_poll_func *pf = p; + pf->timestamp = iio_get_time_ns(); + return IRQ_WAKE_THREAD; +} +EXPORT_SYMBOL(iio_pollfunc_store_time); + +struct iio_poll_func +*iio_alloc_pollfunc(irqreturn_t (*h)(int irq, void *p), + irqreturn_t (*thread)(int irq, void *p), + int type, + struct iio_dev *indio_dev, + const char *fmt, + ...) +{ + va_list vargs; + struct iio_poll_func *pf; + + pf = kmalloc(sizeof *pf, GFP_KERNEL); + if (pf == NULL) + return NULL; + va_start(vargs, fmt); + pf->name = kvasprintf(GFP_KERNEL, fmt, vargs); + va_end(vargs); + if (pf->name == NULL) { + kfree(pf); + return NULL; + } + pf->h = h; + pf->thread = thread; + pf->type = type; + pf->indio_dev = indio_dev; + + return pf; +} +EXPORT_SYMBOL_GPL(iio_alloc_pollfunc); + +void iio_dealloc_pollfunc(struct iio_poll_func *pf) +{ + kfree(pf->name); + kfree(pf); +} +EXPORT_SYMBOL_GPL(iio_dealloc_pollfunc); + +/** + * iio_trigger_read_current() - trigger consumer sysfs query which trigger + * + * For trigger consumers the current_trigger interface allows the trigger + * used by the device to be queried. + **/ +static ssize_t iio_trigger_read_current(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + + if (indio_dev->trig) + return sprintf(buf, "%s\n", indio_dev->trig->name); + return 0; +} + +/** + * iio_trigger_write_current() trigger consumer sysfs set current trigger + * + * For trigger consumers the current_trigger interface allows the trigger + * used for this device to be specified at run time based on the triggers + * name. + **/ +static ssize_t iio_trigger_write_current(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_trigger *oldtrig = indio_dev->trig; + struct iio_trigger *trig; + int ret; + + mutex_lock(&indio_dev->mlock); + if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) { + mutex_unlock(&indio_dev->mlock); + return -EBUSY; + } + mutex_unlock(&indio_dev->mlock); + + trig = iio_trigger_find_by_name(buf, len); + if (oldtrig == trig) + return len; + + if (trig && indio_dev->info->validate_trigger) { + ret = indio_dev->info->validate_trigger(indio_dev, trig); + if (ret) + return ret; + } + + if (trig && trig->ops && trig->ops->validate_device) { + ret = trig->ops->validate_device(trig, indio_dev); + if (ret) + return ret; + } + + indio_dev->trig = trig; + + if (oldtrig && indio_dev->trig != oldtrig) + iio_put_trigger(oldtrig); + if (indio_dev->trig) + iio_get_trigger(indio_dev->trig); + + return len; +} + +static DEVICE_ATTR(current_trigger, S_IRUGO | S_IWUSR, + iio_trigger_read_current, + iio_trigger_write_current); + +static struct attribute *iio_trigger_consumer_attrs[] = { + &dev_attr_current_trigger.attr, + NULL, +}; + +static const struct attribute_group iio_trigger_consumer_attr_group = { + .name = "trigger", + .attrs = iio_trigger_consumer_attrs, +}; + +static void iio_trig_release(struct device *device) +{ + struct iio_trigger *trig = to_iio_trigger(device); + int i; + + if (trig->subirq_base) { + for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) { + irq_modify_status(trig->subirq_base + i, + IRQ_NOAUTOEN, + IRQ_NOREQUEST | IRQ_NOPROBE); + irq_set_chip(trig->subirq_base + i, + NULL); + irq_set_handler(trig->subirq_base + i, + NULL); + } + + irq_free_descs(trig->subirq_base, + CONFIG_IIO_CONSUMERS_PER_TRIGGER); + } + kfree(trig->name); + kfree(trig); +} + +static struct device_type iio_trig_type = { + .release = iio_trig_release, +}; + +static void iio_trig_subirqmask(struct irq_data *d) +{ + struct irq_chip *chip = irq_data_get_irq_chip(d); + struct iio_trigger *trig + = container_of(chip, + struct iio_trigger, subirq_chip); + trig->subirqs[d->irq - trig->subirq_base].enabled = false; +} + +static void iio_trig_subirqunmask(struct irq_data *d) +{ + struct irq_chip *chip = irq_data_get_irq_chip(d); + struct iio_trigger *trig + = container_of(chip, + struct iio_trigger, subirq_chip); + trig->subirqs[d->irq - trig->subirq_base].enabled = true; +} + +struct iio_trigger *iio_allocate_trigger(const char *fmt, ...) +{ + va_list vargs; + struct iio_trigger *trig; + trig = kzalloc(sizeof *trig, GFP_KERNEL); + if (trig) { + int i; + trig->dev.type = &iio_trig_type; + trig->dev.bus = &iio_bus_type; + device_initialize(&trig->dev); + dev_set_drvdata(&trig->dev, (void *)trig); + + mutex_init(&trig->pool_lock); + trig->subirq_base + = irq_alloc_descs(-1, 0, + CONFIG_IIO_CONSUMERS_PER_TRIGGER, + 0); + if (trig->subirq_base < 0) { + kfree(trig); + return NULL; + } + va_start(vargs, fmt); + trig->name = kvasprintf(GFP_KERNEL, fmt, vargs); + va_end(vargs); + if (trig->name == NULL) { + irq_free_descs(trig->subirq_base, + CONFIG_IIO_CONSUMERS_PER_TRIGGER); + kfree(trig); + return NULL; + } + trig->subirq_chip.name = trig->name; + trig->subirq_chip.irq_mask = &iio_trig_subirqmask; + trig->subirq_chip.irq_unmask = &iio_trig_subirqunmask; + for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) { + irq_set_chip(trig->subirq_base + i, + &trig->subirq_chip); + irq_set_handler(trig->subirq_base + i, + &handle_simple_irq); + irq_modify_status(trig->subirq_base + i, + IRQ_NOREQUEST | IRQ_NOAUTOEN, + IRQ_NOPROBE); + } + get_device(&trig->dev); + } + return trig; +} +EXPORT_SYMBOL(iio_allocate_trigger); + +void iio_free_trigger(struct iio_trigger *trig) +{ + if (trig) + put_device(&trig->dev); +} +EXPORT_SYMBOL(iio_free_trigger); + +void iio_device_register_trigger_consumer(struct iio_dev *indio_dev) +{ + indio_dev->groups[indio_dev->groupcounter++] = + &iio_trigger_consumer_attr_group; +} + +void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev) +{ + /* Clean up and associated but not attached triggers references */ + if (indio_dev->trig) + iio_put_trigger(indio_dev->trig); +} + +int iio_triggered_buffer_postenable(struct iio_dev *indio_dev) +{ + return iio_trigger_attach_poll_func(indio_dev->trig, + indio_dev->pollfunc); +} +EXPORT_SYMBOL(iio_triggered_buffer_postenable); + +int iio_triggered_buffer_predisable(struct iio_dev *indio_dev) +{ + return iio_trigger_dettach_poll_func(indio_dev->trig, + indio_dev->pollfunc); +} +EXPORT_SYMBOL(iio_triggered_buffer_predisable); diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c new file mode 100644 index 0000000..22ddf62 --- /dev/null +++ b/drivers/iio/inkern.c @@ -0,0 +1,292 @@ +/* The industrial I/O core in kernel channel mapping + * + * Copyright (c) 2011 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ +#include +#include +#include +#include + +#include +#include "iio_core.h" +#include +#include +#include + +struct iio_map_internal { + struct iio_dev *indio_dev; + struct iio_map *map; + struct list_head l; +}; + +static LIST_HEAD(iio_map_list); +static DEFINE_MUTEX(iio_map_list_lock); + +int iio_map_array_register(struct iio_dev *indio_dev, struct iio_map *maps) +{ + int i = 0, ret = 0; + struct iio_map_internal *mapi; + + if (maps == NULL) + return 0; + + mutex_lock(&iio_map_list_lock); + while (maps[i].consumer_dev_name != NULL) { + mapi = kzalloc(sizeof(*mapi), GFP_KERNEL); + if (mapi == NULL) { + ret = -ENOMEM; + goto error_ret; + } + mapi->map = &maps[i]; + mapi->indio_dev = indio_dev; + list_add(&mapi->l, &iio_map_list); + i++; + } +error_ret: + mutex_unlock(&iio_map_list_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(iio_map_array_register); + + +/* Assumes the exact same array (e.g. memory locations) + * used at unregistration as used at registration rather than + * more complex checking of contents. + */ +int iio_map_array_unregister(struct iio_dev *indio_dev, + struct iio_map *maps) +{ + int i = 0, ret = 0; + bool found_it; + struct iio_map_internal *mapi; + + if (maps == NULL) + return 0; + + mutex_lock(&iio_map_list_lock); + while (maps[i].consumer_dev_name != NULL) { + found_it = false; + list_for_each_entry(mapi, &iio_map_list, l) + if (&maps[i] == mapi->map) { + list_del(&mapi->l); + kfree(mapi); + found_it = true; + break; + } + if (found_it == false) { + ret = -ENODEV; + goto error_ret; + } + } +error_ret: + mutex_unlock(&iio_map_list_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(iio_map_array_unregister); + +static const struct iio_chan_spec +*iio_chan_spec_from_name(const struct iio_dev *indio_dev, + const char *name) +{ + int i; + const struct iio_chan_spec *chan = NULL; + + for (i = 0; i < indio_dev->num_channels; i++) + if (indio_dev->channels[i].datasheet_name && + strcmp(name, indio_dev->channels[i].datasheet_name) == 0) { + chan = &indio_dev->channels[i]; + break; + } + return chan; +} + + +struct iio_channel *iio_st_channel_get(const char *name, + const char *channel_name) +{ + struct iio_map_internal *c_i = NULL, *c = NULL; + struct iio_channel *channel; + + if (name == NULL && channel_name == NULL) + return ERR_PTR(-ENODEV); + + /* first find matching entry the channel map */ + mutex_lock(&iio_map_list_lock); + list_for_each_entry(c_i, &iio_map_list, l) { + if ((name && strcmp(name, c_i->map->consumer_dev_name) != 0) || + (channel_name && + strcmp(channel_name, c_i->map->consumer_channel) != 0)) + continue; + c = c_i; + get_device(&c->indio_dev->dev); + break; + } + mutex_unlock(&iio_map_list_lock); + if (c == NULL) + return ERR_PTR(-ENODEV); + + channel = kmalloc(sizeof(*channel), GFP_KERNEL); + if (channel == NULL) + return ERR_PTR(-ENOMEM); + + channel->indio_dev = c->indio_dev; + + if (c->map->adc_channel_label) + channel->channel = + iio_chan_spec_from_name(channel->indio_dev, + c->map->adc_channel_label); + + return channel; +} +EXPORT_SYMBOL_GPL(iio_st_channel_get); + +void iio_st_channel_release(struct iio_channel *channel) +{ + put_device(&channel->indio_dev->dev); + kfree(channel); +} +EXPORT_SYMBOL_GPL(iio_st_channel_release); + +struct iio_channel *iio_st_channel_get_all(const char *name) +{ + struct iio_channel *chans; + struct iio_map_internal *c = NULL; + int nummaps = 0; + int mapind = 0; + int i, ret; + + if (name == NULL) + return ERR_PTR(-EINVAL); + + mutex_lock(&iio_map_list_lock); + /* first count the matching maps */ + list_for_each_entry(c, &iio_map_list, l) + if (name && strcmp(name, c->map->consumer_dev_name) != 0) + continue; + else + nummaps++; + + if (nummaps == 0) { + ret = -ENODEV; + goto error_ret; + } + + /* NULL terminated array to save passing size */ + chans = kzalloc(sizeof(*chans)*(nummaps + 1), GFP_KERNEL); + if (chans == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + /* for each map fill in the chans element */ + list_for_each_entry(c, &iio_map_list, l) { + if (name && strcmp(name, c->map->consumer_dev_name) != 0) + continue; + chans[mapind].indio_dev = c->indio_dev; + chans[mapind].channel = + iio_chan_spec_from_name(chans[mapind].indio_dev, + c->map->adc_channel_label); + if (chans[mapind].channel == NULL) { + ret = -EINVAL; + put_device(&chans[mapind].indio_dev->dev); + goto error_free_chans; + } + get_device(&chans[mapind].indio_dev->dev); + mapind++; + } + mutex_unlock(&iio_map_list_lock); + if (mapind == 0) { + ret = -ENODEV; + goto error_free_chans; + } + return chans; + +error_free_chans: + for (i = 0; i < nummaps; i++) + if (chans[i].indio_dev) + put_device(&chans[i].indio_dev->dev); + kfree(chans); +error_ret: + mutex_unlock(&iio_map_list_lock); + + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(iio_st_channel_get_all); + +void iio_st_channel_release_all(struct iio_channel *channels) +{ + struct iio_channel *chan = &channels[0]; + + while (chan->indio_dev) { + put_device(&chan->indio_dev->dev); + chan++; + } + kfree(channels); +} +EXPORT_SYMBOL_GPL(iio_st_channel_release_all); + +int iio_st_read_channel_raw(struct iio_channel *chan, int *val) +{ + int val2, ret; + + mutex_lock(&chan->indio_dev->info_exist_lock); + if (chan->indio_dev->info == NULL) { + ret = -ENODEV; + goto err_unlock; + } + + ret = chan->indio_dev->info->read_raw(chan->indio_dev, chan->channel, + val, &val2, 0); +err_unlock: + mutex_unlock(&chan->indio_dev->info_exist_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(iio_st_read_channel_raw); + +int iio_st_read_channel_scale(struct iio_channel *chan, int *val, int *val2) +{ + int ret; + + mutex_lock(&chan->indio_dev->info_exist_lock); + if (chan->indio_dev->info == NULL) { + ret = -ENODEV; + goto err_unlock; + } + + ret = chan->indio_dev->info->read_raw(chan->indio_dev, + chan->channel, + val, val2, + IIO_CHAN_INFO_SCALE); +err_unlock: + mutex_unlock(&chan->indio_dev->info_exist_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(iio_st_read_channel_scale); + +int iio_st_get_channel_type(struct iio_channel *chan, + enum iio_chan_type *type) +{ + int ret = 0; + /* Need to verify underlying driver has not gone away */ + + mutex_lock(&chan->indio_dev->info_exist_lock); + if (chan->indio_dev->info == NULL) { + ret = -ENODEV; + goto err_unlock; + } + + *type = chan->channel->type; +err_unlock: + mutex_unlock(&chan->indio_dev->info_exist_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(iio_st_get_channel_type); diff --git a/drivers/iio/kfifo_buf.c b/drivers/iio/kfifo_buf.c new file mode 100644 index 0000000..6bf9d05 --- /dev/null +++ b/drivers/iio/kfifo_buf.c @@ -0,0 +1,150 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +struct iio_kfifo { + struct iio_buffer buffer; + struct kfifo kf; + int update_needed; +}; + +#define iio_to_kfifo(r) container_of(r, struct iio_kfifo, buffer) + +static inline int __iio_allocate_kfifo(struct iio_kfifo *buf, + int bytes_per_datum, int length) +{ + if ((length == 0) || (bytes_per_datum == 0)) + return -EINVAL; + + __iio_update_buffer(&buf->buffer, bytes_per_datum, length); + return kfifo_alloc(&buf->kf, bytes_per_datum*length, GFP_KERNEL); +} + +static int iio_request_update_kfifo(struct iio_buffer *r) +{ + int ret = 0; + struct iio_kfifo *buf = iio_to_kfifo(r); + + if (!buf->update_needed) + goto error_ret; + kfifo_free(&buf->kf); + ret = __iio_allocate_kfifo(buf, buf->buffer.bytes_per_datum, + buf->buffer.length); +error_ret: + return ret; +} + +static int iio_get_length_kfifo(struct iio_buffer *r) +{ + return r->length; +} + +static IIO_BUFFER_ENABLE_ATTR; +static IIO_BUFFER_LENGTH_ATTR; + +static struct attribute *iio_kfifo_attributes[] = { + &dev_attr_length.attr, + &dev_attr_enable.attr, + NULL, +}; + +static struct attribute_group iio_kfifo_attribute_group = { + .attrs = iio_kfifo_attributes, + .name = "buffer", +}; + +static int iio_get_bytes_per_datum_kfifo(struct iio_buffer *r) +{ + return r->bytes_per_datum; +} + +static int iio_mark_update_needed_kfifo(struct iio_buffer *r) +{ + struct iio_kfifo *kf = iio_to_kfifo(r); + kf->update_needed = true; + return 0; +} + +static int iio_set_bytes_per_datum_kfifo(struct iio_buffer *r, size_t bpd) +{ + if (r->bytes_per_datum != bpd) { + r->bytes_per_datum = bpd; + iio_mark_update_needed_kfifo(r); + } + return 0; +} + +static int iio_set_length_kfifo(struct iio_buffer *r, int length) +{ + if (r->length != length) { + r->length = length; + iio_mark_update_needed_kfifo(r); + } + return 0; +} + +static int iio_store_to_kfifo(struct iio_buffer *r, + u8 *data, + s64 timestamp) +{ + int ret; + struct iio_kfifo *kf = iio_to_kfifo(r); + ret = kfifo_in(&kf->kf, data, r->bytes_per_datum); + if (ret != r->bytes_per_datum) + return -EBUSY; + return 0; +} + +static int iio_read_first_n_kfifo(struct iio_buffer *r, + size_t n, char __user *buf) +{ + int ret, copied; + struct iio_kfifo *kf = iio_to_kfifo(r); + + if (n < r->bytes_per_datum) + return -EINVAL; + + n = rounddown(n, r->bytes_per_datum); + ret = kfifo_to_user(&kf->kf, buf, n, &copied); + + return copied; +} + +static const struct iio_buffer_access_funcs kfifo_access_funcs = { + .store_to = &iio_store_to_kfifo, + .read_first_n = &iio_read_first_n_kfifo, + .request_update = &iio_request_update_kfifo, + .get_bytes_per_datum = &iio_get_bytes_per_datum_kfifo, + .set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo, + .get_length = &iio_get_length_kfifo, + .set_length = &iio_set_length_kfifo, +}; + +struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev) +{ + struct iio_kfifo *kf; + + kf = kzalloc(sizeof *kf, GFP_KERNEL); + if (!kf) + return NULL; + kf->update_needed = true; + iio_buffer_init(&kf->buffer); + kf->buffer.attrs = &iio_kfifo_attribute_group; + kf->buffer.access = &kfifo_access_funcs; + + return &kf->buffer; +} +EXPORT_SYMBOL(iio_kfifo_allocate); + +void iio_kfifo_free(struct iio_buffer *r) +{ + kfree(iio_to_kfifo(r)); +} +EXPORT_SYMBOL(iio_kfifo_free); + +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index fe1586718..c1054a1 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig @@ -1,16 +1,9 @@ # # Industrial I/O subsytem configuration # +menu "IIO staging drivers" + depends on IIO -menuconfig IIO - tristate "Industrial I/O support" - depends on GENERIC_HARDIRQS - help - The industrial I/O subsystem provides a unified framework for - drivers for many different types of embedded sensors using a - number of different physical interfaces (i2c, spi, etc). See - drivers/staging/iio/Documentation for more information. -if IIO config IIO_ST_HWMON tristate "Hwmon driver that uses channels specified via iio maps" depends on HWMON @@ -19,12 +12,6 @@ config IIO_ST_HWMON map allows IIO devices to provide basic hwmon functionality for those channels specified in the map. -config IIO_BUFFER - bool "Enable buffer support within IIO" - help - Provide core support for various buffer based data - acquisition methods. - if IIO_BUFFER config IIO_SW_RING @@ -36,33 +23,8 @@ config IIO_SW_RING with the intention that some devices would be able to write in interrupt context. -config IIO_KFIFO_BUF - select IIO_TRIGGER - tristate "Industrial I/O buffering based on kfifo" - help - A simple fifo based on kfifo. Use this if you want a fifo - rather than a ring buffer. Note that this currently provides - no buffer events so it is up to userspace to work out how - often to read from the buffer. - endif # IIO_BUFFER -config IIO_TRIGGER - boolean "Enable triggered sampling support" - help - Provides IIO core support for triggers. Currently these - are used to initialize capture of samples to push into - ring buffers. The triggers are effectively a 'capture - data now' interrupt. - -config IIO_CONSUMERS_PER_TRIGGER - int "Maximum number of consumers per trigger" - depends on IIO_TRIGGER - default "2" - help - This value controls the maximum number of consumers that a - given trigger may handle. Default is 2. - source "drivers/staging/iio/accel/Kconfig" source "drivers/staging/iio/adc/Kconfig" source "drivers/staging/iio/addac/Kconfig" @@ -104,4 +66,4 @@ config IIO_SIMPLE_DUMMY_BUFFER endif # IIO_SIMPLE_DUMMY -endif # IIO +endmenu diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile index 5075291..2acd42f 100644 --- a/drivers/staging/iio/Makefile +++ b/drivers/staging/iio/Makefile @@ -2,13 +2,7 @@ # Makefile for the industrial I/O core. # -obj-$(CONFIG_IIO) += industrialio.o -industrialio-y := industrialio-core.o industrialio-event.o inkern.o -industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o -industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o - obj-$(CONFIG_IIO_SW_RING) += ring_sw.o -obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o obj-$(CONFIG_IIO_SIMPLE_DUMMY) += iio_dummy.o iio_dummy-y := iio_simple_dummy.o diff --git a/drivers/staging/iio/iio_core.h b/drivers/staging/iio/iio_core.h deleted file mode 100644 index f652e6a..0000000 --- a/drivers/staging/iio/iio_core.h +++ /dev/null @@ -1,62 +0,0 @@ -/* The industrial I/O core function defs. - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * These definitions are meant for use only within the IIO core, not individual - * drivers. - */ - -#ifndef _IIO_CORE_H_ -#define _IIO_CORE_H_ -#include -#include - -struct iio_chan_spec; -struct iio_dev; - - -int __iio_add_chan_devattr(const char *postfix, - struct iio_chan_spec const *chan, - ssize_t (*func)(struct device *dev, - struct device_attribute *attr, - char *buf), - ssize_t (*writefunc)(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len), - u64 mask, - bool generic, - struct device *dev, - struct list_head *attr_list); - -/* Event interface flags */ -#define IIO_BUSY_BIT_POS 1 - -#ifdef CONFIG_IIO_BUFFER -struct poll_table_struct; - -unsigned int iio_buffer_poll(struct file *filp, - struct poll_table_struct *wait); -ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf, - size_t n, loff_t *f_ps); - - -#define iio_buffer_poll_addr (&iio_buffer_poll) -#define iio_buffer_read_first_n_outer_addr (&iio_buffer_read_first_n_outer) - -#else - -#define iio_buffer_poll_addr NULL -#define iio_buffer_read_first_n_outer_addr NULL - -#endif - -int iio_device_register_eventset(struct iio_dev *indio_dev); -void iio_device_unregister_eventset(struct iio_dev *indio_dev); -int iio_event_getfd(struct iio_dev *indio_dev); - -#endif diff --git a/drivers/staging/iio/iio_core_trigger.h b/drivers/staging/iio/iio_core_trigger.h deleted file mode 100644 index 6f7c56f..0000000 --- a/drivers/staging/iio/iio_core_trigger.h +++ /dev/null @@ -1,46 +0,0 @@ - -/* The industrial I/O core, trigger consumer handling functions - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -#ifdef CONFIG_IIO_TRIGGER -/** - * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers - * @indio_dev: iio_dev associated with the device that will consume the trigger - **/ -void iio_device_register_trigger_consumer(struct iio_dev *indio_dev); - -/** - * iio_device_unregister_trigger_consumer() - reverse the registration process - * @indio_dev: iio_dev associated with the device that consumed the trigger - **/ -void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev); - -#else - -/** - * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers - * @indio_dev: iio_dev associated with the device that will consume the trigger - **/ -static int iio_device_register_trigger_consumer(struct iio_dev *indio_dev) -{ - return 0; -}; - -/** - * iio_device_unregister_trigger_consumer() - reverse the registration process - * @indio_dev: iio_dev associated with the device that consumed the trigger - **/ -static void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev) -{ -}; - -#endif /* CONFIG_TRIGGER_CONSUMER */ - - - diff --git a/drivers/staging/iio/industrialio-buffer.c b/drivers/staging/iio/industrialio-buffer.c deleted file mode 100644 index b5b2c38..0000000 --- a/drivers/staging/iio/industrialio-buffer.c +++ /dev/null @@ -1,755 +0,0 @@ -/* The industrial I/O core - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * Handling of buffer allocation / resizing. - * - * - * Things to look at here. - * - Better memory allocation techniques? - * - Alternative access techniques? - */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include "iio_core.h" -#include -#include - -static const char * const iio_endian_prefix[] = { - [IIO_BE] = "be", - [IIO_LE] = "le", -}; - -/** - * iio_buffer_read_first_n_outer() - chrdev read for buffer access - * - * This function relies on all buffer implementations having an - * iio_buffer as their first element. - **/ -ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf, - size_t n, loff_t *f_ps) -{ - struct iio_dev *indio_dev = filp->private_data; - struct iio_buffer *rb = indio_dev->buffer; - - if (!rb || !rb->access->read_first_n) - return -EINVAL; - return rb->access->read_first_n(rb, n, buf); -} - -/** - * iio_buffer_poll() - poll the buffer to find out if it has data - */ -unsigned int iio_buffer_poll(struct file *filp, - struct poll_table_struct *wait) -{ - struct iio_dev *indio_dev = filp->private_data; - struct iio_buffer *rb = indio_dev->buffer; - - poll_wait(filp, &rb->pollq, wait); - if (rb->stufftoread) - return POLLIN | POLLRDNORM; - /* need a way of knowing if there may be enough data... */ - return 0; -} - -void iio_buffer_init(struct iio_buffer *buffer) -{ - INIT_LIST_HEAD(&buffer->demux_list); - init_waitqueue_head(&buffer->pollq); -} -EXPORT_SYMBOL(iio_buffer_init); - -static ssize_t iio_show_scan_index(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "%u\n", to_iio_dev_attr(attr)->c->scan_index); -} - -static ssize_t iio_show_fixed_type(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - u8 type = this_attr->c->scan_type.endianness; - - if (type == IIO_CPU) { -#ifdef __LITTLE_ENDIAN - type = IIO_LE; -#else - type = IIO_BE; -#endif - } - return sprintf(buf, "%s:%c%d/%d>>%u\n", - iio_endian_prefix[type], - this_attr->c->scan_type.sign, - this_attr->c->scan_type.realbits, - this_attr->c->scan_type.storagebits, - this_attr->c->scan_type.shift); -} - -static ssize_t iio_scan_el_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - - ret = test_bit(to_iio_dev_attr(attr)->address, - indio_dev->buffer->scan_mask); - - return sprintf(buf, "%d\n", ret); -} - -static int iio_scan_mask_clear(struct iio_buffer *buffer, int bit) -{ - clear_bit(bit, buffer->scan_mask); - return 0; -} - -static ssize_t iio_scan_el_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - int ret; - bool state; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_buffer *buffer = indio_dev->buffer; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - - ret = strtobool(buf, &state); - if (ret < 0) - return ret; - mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) { - ret = -EBUSY; - goto error_ret; - } - ret = iio_scan_mask_query(indio_dev, buffer, this_attr->address); - if (ret < 0) - goto error_ret; - if (!state && ret) { - ret = iio_scan_mask_clear(buffer, this_attr->address); - if (ret) - goto error_ret; - } else if (state && !ret) { - ret = iio_scan_mask_set(indio_dev, buffer, this_attr->address); - if (ret) - goto error_ret; - } - -error_ret: - mutex_unlock(&indio_dev->mlock); - - return ret < 0 ? ret : len; - -} - -static ssize_t iio_scan_el_ts_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - return sprintf(buf, "%d\n", indio_dev->buffer->scan_timestamp); -} - -static ssize_t iio_scan_el_ts_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - bool state; - - ret = strtobool(buf, &state); - if (ret < 0) - return ret; - - mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) { - ret = -EBUSY; - goto error_ret; - } - indio_dev->buffer->scan_timestamp = state; - indio_dev->scan_timestamp = state; -error_ret: - mutex_unlock(&indio_dev->mlock); - - return ret ? ret : len; -} - -static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev, - const struct iio_chan_spec *chan) -{ - int ret, attrcount = 0; - struct iio_buffer *buffer = indio_dev->buffer; - - ret = __iio_add_chan_devattr("index", - chan, - &iio_show_scan_index, - NULL, - 0, - 0, - &indio_dev->dev, - &buffer->scan_el_dev_attr_list); - if (ret) - goto error_ret; - attrcount++; - ret = __iio_add_chan_devattr("type", - chan, - &iio_show_fixed_type, - NULL, - 0, - 0, - &indio_dev->dev, - &buffer->scan_el_dev_attr_list); - if (ret) - goto error_ret; - attrcount++; - if (chan->type != IIO_TIMESTAMP) - ret = __iio_add_chan_devattr("en", - chan, - &iio_scan_el_show, - &iio_scan_el_store, - chan->scan_index, - 0, - &indio_dev->dev, - &buffer->scan_el_dev_attr_list); - else - ret = __iio_add_chan_devattr("en", - chan, - &iio_scan_el_ts_show, - &iio_scan_el_ts_store, - chan->scan_index, - 0, - &indio_dev->dev, - &buffer->scan_el_dev_attr_list); - attrcount++; - ret = attrcount; -error_ret: - return ret; -} - -static void iio_buffer_remove_and_free_scan_dev_attr(struct iio_dev *indio_dev, - struct iio_dev_attr *p) -{ - kfree(p->dev_attr.attr.name); - kfree(p); -} - -static void __iio_buffer_attr_cleanup(struct iio_dev *indio_dev) -{ - struct iio_dev_attr *p, *n; - struct iio_buffer *buffer = indio_dev->buffer; - - list_for_each_entry_safe(p, n, - &buffer->scan_el_dev_attr_list, l) - iio_buffer_remove_and_free_scan_dev_attr(indio_dev, p); -} - -static const char * const iio_scan_elements_group_name = "scan_elements"; - -int iio_buffer_register(struct iio_dev *indio_dev, - const struct iio_chan_spec *channels, - int num_channels) -{ - struct iio_dev_attr *p; - struct attribute **attr; - struct iio_buffer *buffer = indio_dev->buffer; - int ret, i, attrn, attrcount, attrcount_orig = 0; - - if (buffer->attrs) - indio_dev->groups[indio_dev->groupcounter++] = buffer->attrs; - - if (buffer->scan_el_attrs != NULL) { - attr = buffer->scan_el_attrs->attrs; - while (*attr++ != NULL) - attrcount_orig++; - } - attrcount = attrcount_orig; - INIT_LIST_HEAD(&buffer->scan_el_dev_attr_list); - if (channels) { - /* new magic */ - for (i = 0; i < num_channels; i++) { - /* Establish necessary mask length */ - if (channels[i].scan_index > - (int)indio_dev->masklength - 1) - indio_dev->masklength - = indio_dev->channels[i].scan_index + 1; - - ret = iio_buffer_add_channel_sysfs(indio_dev, - &channels[i]); - if (ret < 0) - goto error_cleanup_dynamic; - attrcount += ret; - if (channels[i].type == IIO_TIMESTAMP) - indio_dev->scan_index_timestamp = - channels[i].scan_index; - } - if (indio_dev->masklength && buffer->scan_mask == NULL) { - buffer->scan_mask = kcalloc(BITS_TO_LONGS(indio_dev->masklength), - sizeof(*buffer->scan_mask), - GFP_KERNEL); - if (buffer->scan_mask == NULL) { - ret = -ENOMEM; - goto error_cleanup_dynamic; - } - } - } - - buffer->scan_el_group.name = iio_scan_elements_group_name; - - buffer->scan_el_group.attrs = kcalloc(attrcount + 1, - sizeof(buffer->scan_el_group.attrs[0]), - GFP_KERNEL); - if (buffer->scan_el_group.attrs == NULL) { - ret = -ENOMEM; - goto error_free_scan_mask; - } - if (buffer->scan_el_attrs) - memcpy(buffer->scan_el_group.attrs, buffer->scan_el_attrs, - sizeof(buffer->scan_el_group.attrs[0])*attrcount_orig); - attrn = attrcount_orig; - - list_for_each_entry(p, &buffer->scan_el_dev_attr_list, l) - buffer->scan_el_group.attrs[attrn++] = &p->dev_attr.attr; - indio_dev->groups[indio_dev->groupcounter++] = &buffer->scan_el_group; - - return 0; - -error_free_scan_mask: - kfree(buffer->scan_mask); -error_cleanup_dynamic: - __iio_buffer_attr_cleanup(indio_dev); - - return ret; -} -EXPORT_SYMBOL(iio_buffer_register); - -void iio_buffer_unregister(struct iio_dev *indio_dev) -{ - kfree(indio_dev->buffer->scan_mask); - kfree(indio_dev->buffer->scan_el_group.attrs); - __iio_buffer_attr_cleanup(indio_dev); -} -EXPORT_SYMBOL(iio_buffer_unregister); - -ssize_t iio_buffer_read_length(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_buffer *buffer = indio_dev->buffer; - - if (buffer->access->get_length) - return sprintf(buf, "%d\n", - buffer->access->get_length(buffer)); - - return 0; -} -EXPORT_SYMBOL(iio_buffer_read_length); - -ssize_t iio_buffer_write_length(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - int ret; - ulong val; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_buffer *buffer = indio_dev->buffer; - - ret = strict_strtoul(buf, 10, &val); - if (ret) - return ret; - - if (buffer->access->get_length) - if (val == buffer->access->get_length(buffer)) - return len; - - mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) { - ret = -EBUSY; - } else { - if (buffer->access->set_length) - buffer->access->set_length(buffer, val); - ret = 0; - } - mutex_unlock(&indio_dev->mlock); - - return ret ? ret : len; -} -EXPORT_SYMBOL(iio_buffer_write_length); - -ssize_t iio_buffer_store_enable(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - int ret; - bool requested_state, current_state; - int previous_mode; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_buffer *buffer = indio_dev->buffer; - - mutex_lock(&indio_dev->mlock); - previous_mode = indio_dev->currentmode; - requested_state = !(buf[0] == '0'); - current_state = iio_buffer_enabled(indio_dev); - if (current_state == requested_state) { - printk(KERN_INFO "iio-buffer, current state requested again\n"); - goto done; - } - if (requested_state) { - if (indio_dev->setup_ops->preenable) { - ret = indio_dev->setup_ops->preenable(indio_dev); - if (ret) { - printk(KERN_ERR - "Buffer not started:" - "buffer preenable failed\n"); - goto error_ret; - } - } - if (buffer->access->request_update) { - ret = buffer->access->request_update(buffer); - if (ret) { - printk(KERN_INFO - "Buffer not started:" - "buffer parameter update failed\n"); - goto error_ret; - } - } - /* Definitely possible for devices to support both of these.*/ - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) { - if (!indio_dev->trig) { - printk(KERN_INFO - "Buffer not started: no trigger\n"); - ret = -EINVAL; - goto error_ret; - } - indio_dev->currentmode = INDIO_BUFFER_TRIGGERED; - } else if (indio_dev->modes & INDIO_BUFFER_HARDWARE) - indio_dev->currentmode = INDIO_BUFFER_HARDWARE; - else { /* should never be reached */ - ret = -EINVAL; - goto error_ret; - } - - if (indio_dev->setup_ops->postenable) { - ret = indio_dev->setup_ops->postenable(indio_dev); - if (ret) { - printk(KERN_INFO - "Buffer not started:" - "postenable failed\n"); - indio_dev->currentmode = previous_mode; - if (indio_dev->setup_ops->postdisable) - indio_dev->setup_ops-> - postdisable(indio_dev); - goto error_ret; - } - } - } else { - if (indio_dev->setup_ops->predisable) { - ret = indio_dev->setup_ops->predisable(indio_dev); - if (ret) - goto error_ret; - } - indio_dev->currentmode = INDIO_DIRECT_MODE; - if (indio_dev->setup_ops->postdisable) { - ret = indio_dev->setup_ops->postdisable(indio_dev); - if (ret) - goto error_ret; - } - } -done: - mutex_unlock(&indio_dev->mlock); - return len; - -error_ret: - mutex_unlock(&indio_dev->mlock); - return ret; -} -EXPORT_SYMBOL(iio_buffer_store_enable); - -ssize_t iio_buffer_show_enable(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - return sprintf(buf, "%d\n", iio_buffer_enabled(indio_dev)); -} -EXPORT_SYMBOL(iio_buffer_show_enable); - -/* note NULL used as error indicator as it doesn't make sense. */ -static const unsigned long *iio_scan_mask_match(const unsigned long *av_masks, - unsigned int masklength, - const unsigned long *mask) -{ - if (bitmap_empty(mask, masklength)) - return NULL; - while (*av_masks) { - if (bitmap_subset(mask, av_masks, masklength)) - return av_masks; - av_masks += BITS_TO_LONGS(masklength); - } - return NULL; -} - -static int iio_compute_scan_bytes(struct iio_dev *indio_dev, const long *mask, - bool timestamp) -{ - const struct iio_chan_spec *ch; - unsigned bytes = 0; - int length, i; - - /* How much space will the demuxed element take? */ - for_each_set_bit(i, mask, - indio_dev->masklength) { - ch = iio_find_channel_from_si(indio_dev, i); - length = ch->scan_type.storagebits / 8; - bytes = ALIGN(bytes, length); - bytes += length; - } - if (timestamp) { - ch = iio_find_channel_from_si(indio_dev, - indio_dev->scan_index_timestamp); - length = ch->scan_type.storagebits / 8; - bytes = ALIGN(bytes, length); - bytes += length; - } - return bytes; -} - -int iio_sw_buffer_preenable(struct iio_dev *indio_dev) -{ - struct iio_buffer *buffer = indio_dev->buffer; - dev_dbg(&indio_dev->dev, "%s\n", __func__); - - /* How much space will the demuxed element take? */ - indio_dev->scan_bytes = - iio_compute_scan_bytes(indio_dev, buffer->scan_mask, - buffer->scan_timestamp); - buffer->access->set_bytes_per_datum(buffer, indio_dev->scan_bytes); - - /* What scan mask do we actually have ?*/ - if (indio_dev->available_scan_masks) - indio_dev->active_scan_mask = - iio_scan_mask_match(indio_dev->available_scan_masks, - indio_dev->masklength, - buffer->scan_mask); - else - indio_dev->active_scan_mask = buffer->scan_mask; - iio_update_demux(indio_dev); - - if (indio_dev->info->update_scan_mode) - return indio_dev->info - ->update_scan_mode(indio_dev, - indio_dev->active_scan_mask); - return 0; -} -EXPORT_SYMBOL(iio_sw_buffer_preenable); - -/** - * iio_scan_mask_set() - set particular bit in the scan mask - * @buffer: the buffer whose scan mask we are interested in - * @bit: the bit to be set. - **/ -int iio_scan_mask_set(struct iio_dev *indio_dev, - struct iio_buffer *buffer, int bit) -{ - const unsigned long *mask; - unsigned long *trialmask; - - trialmask = kmalloc(sizeof(*trialmask)* - BITS_TO_LONGS(indio_dev->masklength), - GFP_KERNEL); - - if (trialmask == NULL) - return -ENOMEM; - if (!indio_dev->masklength) { - WARN_ON("trying to set scanmask prior to registering buffer\n"); - kfree(trialmask); - return -EINVAL; - } - bitmap_copy(trialmask, buffer->scan_mask, indio_dev->masklength); - set_bit(bit, trialmask); - - if (indio_dev->available_scan_masks) { - mask = iio_scan_mask_match(indio_dev->available_scan_masks, - indio_dev->masklength, - trialmask); - if (!mask) { - kfree(trialmask); - return -EINVAL; - } - } - bitmap_copy(buffer->scan_mask, trialmask, indio_dev->masklength); - - kfree(trialmask); - - return 0; -}; -EXPORT_SYMBOL_GPL(iio_scan_mask_set); - -int iio_scan_mask_query(struct iio_dev *indio_dev, - struct iio_buffer *buffer, int bit) -{ - if (bit > indio_dev->masklength) - return -EINVAL; - - if (!buffer->scan_mask) - return 0; - - return test_bit(bit, buffer->scan_mask); -}; -EXPORT_SYMBOL_GPL(iio_scan_mask_query); - -/** - * struct iio_demux_table() - table describing demux memcpy ops - * @from: index to copy from - * @to: index to copy to - * @length: how many bytes to copy - * @l: list head used for management - */ -struct iio_demux_table { - unsigned from; - unsigned to; - unsigned length; - struct list_head l; -}; - -static unsigned char *iio_demux(struct iio_buffer *buffer, - unsigned char *datain) -{ - struct iio_demux_table *t; - - if (list_empty(&buffer->demux_list)) - return datain; - list_for_each_entry(t, &buffer->demux_list, l) - memcpy(buffer->demux_bounce + t->to, - datain + t->from, t->length); - - return buffer->demux_bounce; -} - -int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data, - s64 timestamp) -{ - unsigned char *dataout = iio_demux(buffer, data); - - return buffer->access->store_to(buffer, dataout, timestamp); -} -EXPORT_SYMBOL_GPL(iio_push_to_buffer); - -static void iio_buffer_demux_free(struct iio_buffer *buffer) -{ - struct iio_demux_table *p, *q; - list_for_each_entry_safe(p, q, &buffer->demux_list, l) { - list_del(&p->l); - kfree(p); - } -} - -int iio_update_demux(struct iio_dev *indio_dev) -{ - const struct iio_chan_spec *ch; - struct iio_buffer *buffer = indio_dev->buffer; - int ret, in_ind = -1, out_ind, length; - unsigned in_loc = 0, out_loc = 0; - struct iio_demux_table *p; - - /* Clear out any old demux */ - iio_buffer_demux_free(buffer); - kfree(buffer->demux_bounce); - buffer->demux_bounce = NULL; - - /* First work out which scan mode we will actually have */ - if (bitmap_equal(indio_dev->active_scan_mask, - buffer->scan_mask, - indio_dev->masklength)) - return 0; - - /* Now we have the two masks, work from least sig and build up sizes */ - for_each_set_bit(out_ind, - indio_dev->active_scan_mask, - indio_dev->masklength) { - in_ind = find_next_bit(indio_dev->active_scan_mask, - indio_dev->masklength, - in_ind + 1); - while (in_ind != out_ind) { - in_ind = find_next_bit(indio_dev->active_scan_mask, - indio_dev->masklength, - in_ind + 1); - ch = iio_find_channel_from_si(indio_dev, in_ind); - length = ch->scan_type.storagebits/8; - /* Make sure we are aligned */ - in_loc += length; - if (in_loc % length) - in_loc += length - in_loc % length; - } - p = kmalloc(sizeof(*p), GFP_KERNEL); - if (p == NULL) { - ret = -ENOMEM; - goto error_clear_mux_table; - } - ch = iio_find_channel_from_si(indio_dev, in_ind); - length = ch->scan_type.storagebits/8; - if (out_loc % length) - out_loc += length - out_loc % length; - if (in_loc % length) - in_loc += length - in_loc % length; - p->from = in_loc; - p->to = out_loc; - p->length = length; - list_add_tail(&p->l, &buffer->demux_list); - out_loc += length; - in_loc += length; - } - /* Relies on scan_timestamp being last */ - if (buffer->scan_timestamp) { - p = kmalloc(sizeof(*p), GFP_KERNEL); - if (p == NULL) { - ret = -ENOMEM; - goto error_clear_mux_table; - } - ch = iio_find_channel_from_si(indio_dev, - indio_dev->scan_index_timestamp); - length = ch->scan_type.storagebits/8; - if (out_loc % length) - out_loc += length - out_loc % length; - if (in_loc % length) - in_loc += length - in_loc % length; - p->from = in_loc; - p->to = out_loc; - p->length = length; - list_add_tail(&p->l, &buffer->demux_list); - out_loc += length; - in_loc += length; - } - buffer->demux_bounce = kzalloc(out_loc, GFP_KERNEL); - if (buffer->demux_bounce == NULL) { - ret = -ENOMEM; - goto error_clear_mux_table; - } - return 0; - -error_clear_mux_table: - iio_buffer_demux_free(buffer); - - return ret; -} -EXPORT_SYMBOL_GPL(iio_update_demux); diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c deleted file mode 100644 index dd1a6a2..0000000 --- a/drivers/staging/iio/industrialio-core.c +++ /dev/null @@ -1,912 +0,0 @@ -/* The industrial I/O core - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * Based on elements of hwmon and input subsystems. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "iio_core.h" -#include "iio_core_trigger.h" -#include -#include - -/* IDA to assign each registered device a unique id*/ -static DEFINE_IDA(iio_ida); - -static dev_t iio_devt; - -#define IIO_DEV_MAX 256 -struct bus_type iio_bus_type = { - .name = "iio", -}; -EXPORT_SYMBOL(iio_bus_type); - -static struct dentry *iio_debugfs_dentry; - -static const char * const iio_direction[] = { - [0] = "in", - [1] = "out", -}; - -static const char * const iio_chan_type_name_spec[] = { - [IIO_VOLTAGE] = "voltage", - [IIO_CURRENT] = "current", - [IIO_POWER] = "power", - [IIO_ACCEL] = "accel", - [IIO_ANGL_VEL] = "anglvel", - [IIO_MAGN] = "magn", - [IIO_LIGHT] = "illuminance", - [IIO_INTENSITY] = "intensity", - [IIO_PROXIMITY] = "proximity", - [IIO_TEMP] = "temp", - [IIO_INCLI] = "incli", - [IIO_ROT] = "rot", - [IIO_ANGL] = "angl", - [IIO_TIMESTAMP] = "timestamp", - [IIO_CAPACITANCE] = "capacitance", -}; - -static const char * const iio_modifier_names[] = { - [IIO_MOD_X] = "x", - [IIO_MOD_Y] = "y", - [IIO_MOD_Z] = "z", - [IIO_MOD_LIGHT_BOTH] = "both", - [IIO_MOD_LIGHT_IR] = "ir", -}; - -/* relies on pairs of these shared then separate */ -static const char * const iio_chan_info_postfix[] = { - [IIO_CHAN_INFO_RAW] = "raw", - [IIO_CHAN_INFO_PROCESSED] = "input", - [IIO_CHAN_INFO_SCALE] = "scale", - [IIO_CHAN_INFO_OFFSET] = "offset", - [IIO_CHAN_INFO_CALIBSCALE] = "calibscale", - [IIO_CHAN_INFO_CALIBBIAS] = "calibbias", - [IIO_CHAN_INFO_PEAK] = "peak_raw", - [IIO_CHAN_INFO_PEAK_SCALE] = "peak_scale", - [IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW] = "quadrature_correction_raw", - [IIO_CHAN_INFO_AVERAGE_RAW] = "mean_raw", - [IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY] - = "filter_low_pass_3db_frequency", - [IIO_CHAN_INFO_SAMP_FREQ] = "sampling_frequency", -}; - -const struct iio_chan_spec -*iio_find_channel_from_si(struct iio_dev *indio_dev, int si) -{ - int i; - - for (i = 0; i < indio_dev->num_channels; i++) - if (indio_dev->channels[i].scan_index == si) - return &indio_dev->channels[i]; - return NULL; -} - -/* This turns up an awful lot */ -ssize_t iio_read_const_attr(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "%s\n", to_iio_const_attr(attr)->string); -} -EXPORT_SYMBOL(iio_read_const_attr); - -static int __init iio_init(void) -{ - int ret; - - /* Register sysfs bus */ - ret = bus_register(&iio_bus_type); - if (ret < 0) { - printk(KERN_ERR - "%s could not register bus type\n", - __FILE__); - goto error_nothing; - } - - ret = alloc_chrdev_region(&iio_devt, 0, IIO_DEV_MAX, "iio"); - if (ret < 0) { - printk(KERN_ERR "%s: failed to allocate char dev region\n", - __FILE__); - goto error_unregister_bus_type; - } - - iio_debugfs_dentry = debugfs_create_dir("iio", NULL); - - return 0; - -error_unregister_bus_type: - bus_unregister(&iio_bus_type); -error_nothing: - return ret; -} - -static void __exit iio_exit(void) -{ - if (iio_devt) - unregister_chrdev_region(iio_devt, IIO_DEV_MAX); - bus_unregister(&iio_bus_type); - debugfs_remove(iio_debugfs_dentry); -} - -#if defined(CONFIG_DEBUG_FS) -static int iio_debugfs_open(struct inode *inode, struct file *file) -{ - if (inode->i_private) - file->private_data = inode->i_private; - - return 0; -} - -static ssize_t iio_debugfs_read_reg(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - struct iio_dev *indio_dev = file->private_data; - char buf[20]; - unsigned val = 0; - ssize_t len; - int ret; - - ret = indio_dev->info->debugfs_reg_access(indio_dev, - indio_dev->cached_reg_addr, - 0, &val); - if (ret) - dev_err(indio_dev->dev.parent, "%s: read failed\n", __func__); - - len = snprintf(buf, sizeof(buf), "0x%X\n", val); - - return simple_read_from_buffer(userbuf, count, ppos, buf, len); -} - -static ssize_t iio_debugfs_write_reg(struct file *file, - const char __user *userbuf, size_t count, loff_t *ppos) -{ - struct iio_dev *indio_dev = file->private_data; - unsigned reg, val; - char buf[80]; - int ret; - - count = min_t(size_t, count, (sizeof(buf)-1)); - if (copy_from_user(buf, userbuf, count)) - return -EFAULT; - - buf[count] = 0; - - ret = sscanf(buf, "%i %i", ®, &val); - - switch (ret) { - case 1: - indio_dev->cached_reg_addr = reg; - break; - case 2: - indio_dev->cached_reg_addr = reg; - ret = indio_dev->info->debugfs_reg_access(indio_dev, reg, - val, NULL); - if (ret) { - dev_err(indio_dev->dev.parent, "%s: write failed\n", - __func__); - return ret; - } - break; - default: - return -EINVAL; - } - - return count; -} - -static const struct file_operations iio_debugfs_reg_fops = { - .open = iio_debugfs_open, - .read = iio_debugfs_read_reg, - .write = iio_debugfs_write_reg, -}; - -static void iio_device_unregister_debugfs(struct iio_dev *indio_dev) -{ - debugfs_remove_recursive(indio_dev->debugfs_dentry); -} - -static int iio_device_register_debugfs(struct iio_dev *indio_dev) -{ - struct dentry *d; - - if (indio_dev->info->debugfs_reg_access == NULL) - return 0; - - if (IS_ERR(iio_debugfs_dentry)) - return 0; - - indio_dev->debugfs_dentry = - debugfs_create_dir(dev_name(&indio_dev->dev), - iio_debugfs_dentry); - if (IS_ERR(indio_dev->debugfs_dentry)) - return PTR_ERR(indio_dev->debugfs_dentry); - - if (indio_dev->debugfs_dentry == NULL) { - dev_warn(indio_dev->dev.parent, - "Failed to create debugfs directory\n"); - return -EFAULT; - } - - d = debugfs_create_file("direct_reg_access", 0644, - indio_dev->debugfs_dentry, - indio_dev, &iio_debugfs_reg_fops); - if (!d) { - iio_device_unregister_debugfs(indio_dev); - return -ENOMEM; - } - - return 0; -} -#else -static int iio_device_register_debugfs(struct iio_dev *indio_dev) -{ - return 0; -} - -static void iio_device_unregister_debugfs(struct iio_dev *indio_dev) -{ -} -#endif /* CONFIG_DEBUG_FS */ - -static ssize_t iio_read_channel_ext_info(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - const struct iio_chan_spec_ext_info *ext_info; - - ext_info = &this_attr->c->ext_info[this_attr->address]; - - return ext_info->read(indio_dev, this_attr->c, buf); -} - -static ssize_t iio_write_channel_ext_info(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - const struct iio_chan_spec_ext_info *ext_info; - - ext_info = &this_attr->c->ext_info[this_attr->address]; - - return ext_info->write(indio_dev, this_attr->c, buf, len); -} - -static ssize_t iio_read_channel_info(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int val, val2; - int ret = indio_dev->info->read_raw(indio_dev, this_attr->c, - &val, &val2, this_attr->address); - - if (ret < 0) - return ret; - - if (ret == IIO_VAL_INT) - return sprintf(buf, "%d\n", val); - else if (ret == IIO_VAL_INT_PLUS_MICRO) { - if (val2 < 0) - return sprintf(buf, "-%d.%06u\n", val, -val2); - else - return sprintf(buf, "%d.%06u\n", val, val2); - } else if (ret == IIO_VAL_INT_PLUS_NANO) { - if (val2 < 0) - return sprintf(buf, "-%d.%09u\n", val, -val2); - else - return sprintf(buf, "%d.%09u\n", val, val2); - } else - return 0; -} - -static ssize_t iio_write_channel_info(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int ret, integer = 0, fract = 0, fract_mult = 100000; - bool integer_part = true, negative = false; - - /* Assumes decimal - precision based on number of digits */ - if (!indio_dev->info->write_raw) - return -EINVAL; - - if (indio_dev->info->write_raw_get_fmt) - switch (indio_dev->info->write_raw_get_fmt(indio_dev, - this_attr->c, this_attr->address)) { - case IIO_VAL_INT_PLUS_MICRO: - fract_mult = 100000; - break; - case IIO_VAL_INT_PLUS_NANO: - fract_mult = 100000000; - break; - default: - return -EINVAL; - } - - if (buf[0] == '-') { - negative = true; - buf++; - } - - while (*buf) { - if ('0' <= *buf && *buf <= '9') { - if (integer_part) - integer = integer*10 + *buf - '0'; - else { - fract += fract_mult*(*buf - '0'); - if (fract_mult == 1) - break; - fract_mult /= 10; - } - } else if (*buf == '\n') { - if (*(buf + 1) == '\0') - break; - else - return -EINVAL; - } else if (*buf == '.') { - integer_part = false; - } else { - return -EINVAL; - } - buf++; - } - if (negative) { - if (integer) - integer = -integer; - else - fract = -fract; - } - - ret = indio_dev->info->write_raw(indio_dev, this_attr->c, - integer, fract, this_attr->address); - if (ret) - return ret; - - return len; -} - -static -int __iio_device_attr_init(struct device_attribute *dev_attr, - const char *postfix, - struct iio_chan_spec const *chan, - ssize_t (*readfunc)(struct device *dev, - struct device_attribute *attr, - char *buf), - ssize_t (*writefunc)(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len), - bool generic) -{ - int ret; - char *name_format, *full_postfix; - sysfs_attr_init(&dev_attr->attr); - - /* Build up postfix of __postfix */ - if (chan->modified && !generic) { - if (chan->extend_name) - full_postfix = kasprintf(GFP_KERNEL, "%s_%s_%s", - iio_modifier_names[chan - ->channel2], - chan->extend_name, - postfix); - else - full_postfix = kasprintf(GFP_KERNEL, "%s_%s", - iio_modifier_names[chan - ->channel2], - postfix); - } else { - if (chan->extend_name == NULL) - full_postfix = kstrdup(postfix, GFP_KERNEL); - else - full_postfix = kasprintf(GFP_KERNEL, - "%s_%s", - chan->extend_name, - postfix); - } - if (full_postfix == NULL) { - ret = -ENOMEM; - goto error_ret; - } - - if (chan->differential) { /* Differential can not have modifier */ - if (generic) - name_format - = kasprintf(GFP_KERNEL, "%s_%s-%s_%s", - iio_direction[chan->output], - iio_chan_type_name_spec[chan->type], - iio_chan_type_name_spec[chan->type], - full_postfix); - else if (chan->indexed) - name_format - = kasprintf(GFP_KERNEL, "%s_%s%d-%s%d_%s", - iio_direction[chan->output], - iio_chan_type_name_spec[chan->type], - chan->channel, - iio_chan_type_name_spec[chan->type], - chan->channel2, - full_postfix); - else { - WARN_ON("Differential channels must be indexed\n"); - ret = -EINVAL; - goto error_free_full_postfix; - } - } else { /* Single ended */ - if (generic) - name_format - = kasprintf(GFP_KERNEL, "%s_%s_%s", - iio_direction[chan->output], - iio_chan_type_name_spec[chan->type], - full_postfix); - else if (chan->indexed) - name_format - = kasprintf(GFP_KERNEL, "%s_%s%d_%s", - iio_direction[chan->output], - iio_chan_type_name_spec[chan->type], - chan->channel, - full_postfix); - else - name_format - = kasprintf(GFP_KERNEL, "%s_%s_%s", - iio_direction[chan->output], - iio_chan_type_name_spec[chan->type], - full_postfix); - } - if (name_format == NULL) { - ret = -ENOMEM; - goto error_free_full_postfix; - } - dev_attr->attr.name = kasprintf(GFP_KERNEL, - name_format, - chan->channel, - chan->channel2); - if (dev_attr->attr.name == NULL) { - ret = -ENOMEM; - goto error_free_name_format; - } - - if (readfunc) { - dev_attr->attr.mode |= S_IRUGO; - dev_attr->show = readfunc; - } - - if (writefunc) { - dev_attr->attr.mode |= S_IWUSR; - dev_attr->store = writefunc; - } - kfree(name_format); - kfree(full_postfix); - - return 0; - -error_free_name_format: - kfree(name_format); -error_free_full_postfix: - kfree(full_postfix); -error_ret: - return ret; -} - -static void __iio_device_attr_deinit(struct device_attribute *dev_attr) -{ - kfree(dev_attr->attr.name); -} - -int __iio_add_chan_devattr(const char *postfix, - struct iio_chan_spec const *chan, - ssize_t (*readfunc)(struct device *dev, - struct device_attribute *attr, - char *buf), - ssize_t (*writefunc)(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len), - u64 mask, - bool generic, - struct device *dev, - struct list_head *attr_list) -{ - int ret; - struct iio_dev_attr *iio_attr, *t; - - iio_attr = kzalloc(sizeof *iio_attr, GFP_KERNEL); - if (iio_attr == NULL) { - ret = -ENOMEM; - goto error_ret; - } - ret = __iio_device_attr_init(&iio_attr->dev_attr, - postfix, chan, - readfunc, writefunc, generic); - if (ret) - goto error_iio_dev_attr_free; - iio_attr->c = chan; - iio_attr->address = mask; - list_for_each_entry(t, attr_list, l) - if (strcmp(t->dev_attr.attr.name, - iio_attr->dev_attr.attr.name) == 0) { - if (!generic) - dev_err(dev, "tried to double register : %s\n", - t->dev_attr.attr.name); - ret = -EBUSY; - goto error_device_attr_deinit; - } - list_add(&iio_attr->l, attr_list); - - return 0; - -error_device_attr_deinit: - __iio_device_attr_deinit(&iio_attr->dev_attr); -error_iio_dev_attr_free: - kfree(iio_attr); -error_ret: - return ret; -} - -static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan) -{ - int ret, attrcount = 0; - int i; - const struct iio_chan_spec_ext_info *ext_info; - - if (chan->channel < 0) - return 0; - for_each_set_bit(i, &chan->info_mask, sizeof(long)*8) { - ret = __iio_add_chan_devattr(iio_chan_info_postfix[i/2], - chan, - &iio_read_channel_info, - &iio_write_channel_info, - i/2, - !(i%2), - &indio_dev->dev, - &indio_dev->channel_attr_list); - if (ret == -EBUSY && (i%2 == 0)) { - ret = 0; - continue; - } - if (ret < 0) - goto error_ret; - attrcount++; - } - - if (chan->ext_info) { - unsigned int i = 0; - for (ext_info = chan->ext_info; ext_info->name; ext_info++) { - ret = __iio_add_chan_devattr(ext_info->name, - chan, - ext_info->read ? - &iio_read_channel_ext_info : NULL, - ext_info->write ? - &iio_write_channel_ext_info : NULL, - i, - ext_info->shared, - &indio_dev->dev, - &indio_dev->channel_attr_list); - i++; - if (ret == -EBUSY && ext_info->shared) - continue; - - if (ret) - goto error_ret; - - attrcount++; - } - } - - ret = attrcount; -error_ret: - return ret; -} - -static void iio_device_remove_and_free_read_attr(struct iio_dev *indio_dev, - struct iio_dev_attr *p) -{ - kfree(p->dev_attr.attr.name); - kfree(p); -} - -static ssize_t iio_show_dev_name(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - return sprintf(buf, "%s\n", indio_dev->name); -} - -static DEVICE_ATTR(name, S_IRUGO, iio_show_dev_name, NULL); - -static int iio_device_register_sysfs(struct iio_dev *indio_dev) -{ - int i, ret = 0, attrcount, attrn, attrcount_orig = 0; - struct iio_dev_attr *p, *n; - struct attribute **attr; - - /* First count elements in any existing group */ - if (indio_dev->info->attrs) { - attr = indio_dev->info->attrs->attrs; - while (*attr++ != NULL) - attrcount_orig++; - } - attrcount = attrcount_orig; - /* - * New channel registration method - relies on the fact a group does - * not need to be initialized if it is name is NULL. - */ - INIT_LIST_HEAD(&indio_dev->channel_attr_list); - if (indio_dev->channels) - for (i = 0; i < indio_dev->num_channels; i++) { - ret = iio_device_add_channel_sysfs(indio_dev, - &indio_dev - ->channels[i]); - if (ret < 0) - goto error_clear_attrs; - attrcount += ret; - } - - if (indio_dev->name) - attrcount++; - - indio_dev->chan_attr_group.attrs = kcalloc(attrcount + 1, - sizeof(indio_dev->chan_attr_group.attrs[0]), - GFP_KERNEL); - if (indio_dev->chan_attr_group.attrs == NULL) { - ret = -ENOMEM; - goto error_clear_attrs; - } - /* Copy across original attributes */ - if (indio_dev->info->attrs) - memcpy(indio_dev->chan_attr_group.attrs, - indio_dev->info->attrs->attrs, - sizeof(indio_dev->chan_attr_group.attrs[0]) - *attrcount_orig); - attrn = attrcount_orig; - /* Add all elements from the list. */ - list_for_each_entry(p, &indio_dev->channel_attr_list, l) - indio_dev->chan_attr_group.attrs[attrn++] = &p->dev_attr.attr; - if (indio_dev->name) - indio_dev->chan_attr_group.attrs[attrn++] = &dev_attr_name.attr; - - indio_dev->groups[indio_dev->groupcounter++] = - &indio_dev->chan_attr_group; - - return 0; - -error_clear_attrs: - list_for_each_entry_safe(p, n, - &indio_dev->channel_attr_list, l) { - list_del(&p->l); - iio_device_remove_and_free_read_attr(indio_dev, p); - } - - return ret; -} - -static void iio_device_unregister_sysfs(struct iio_dev *indio_dev) -{ - - struct iio_dev_attr *p, *n; - - list_for_each_entry_safe(p, n, &indio_dev->channel_attr_list, l) { - list_del(&p->l); - iio_device_remove_and_free_read_attr(indio_dev, p); - } - kfree(indio_dev->chan_attr_group.attrs); -} - -static void iio_dev_release(struct device *device) -{ - struct iio_dev *indio_dev = container_of(device, struct iio_dev, dev); - cdev_del(&indio_dev->chrdev); - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) - iio_device_unregister_trigger_consumer(indio_dev); - iio_device_unregister_eventset(indio_dev); - iio_device_unregister_sysfs(indio_dev); - iio_device_unregister_debugfs(indio_dev); -} - -static struct device_type iio_dev_type = { - .name = "iio_device", - .release = iio_dev_release, -}; - -struct iio_dev *iio_allocate_device(int sizeof_priv) -{ - struct iio_dev *dev; - size_t alloc_size; - - alloc_size = sizeof(struct iio_dev); - if (sizeof_priv) { - alloc_size = ALIGN(alloc_size, IIO_ALIGN); - alloc_size += sizeof_priv; - } - /* ensure 32-byte alignment of whole construct ? */ - alloc_size += IIO_ALIGN - 1; - - dev = kzalloc(alloc_size, GFP_KERNEL); - - if (dev) { - dev->dev.groups = dev->groups; - dev->dev.type = &iio_dev_type; - dev->dev.bus = &iio_bus_type; - device_initialize(&dev->dev); - dev_set_drvdata(&dev->dev, (void *)dev); - mutex_init(&dev->mlock); - mutex_init(&dev->info_exist_lock); - - dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL); - if (dev->id < 0) { - /* cannot use a dev_err as the name isn't available */ - printk(KERN_ERR "Failed to get id\n"); - kfree(dev); - return NULL; - } - dev_set_name(&dev->dev, "iio:device%d", dev->id); - } - - return dev; -} -EXPORT_SYMBOL(iio_allocate_device); - -void iio_free_device(struct iio_dev *dev) -{ - if (dev) { - ida_simple_remove(&iio_ida, dev->id); - kfree(dev); - } -} -EXPORT_SYMBOL(iio_free_device); - -/** - * iio_chrdev_open() - chrdev file open for buffer access and ioctls - **/ -static int iio_chrdev_open(struct inode *inode, struct file *filp) -{ - struct iio_dev *indio_dev = container_of(inode->i_cdev, - struct iio_dev, chrdev); - - if (test_and_set_bit(IIO_BUSY_BIT_POS, &indio_dev->flags)) - return -EBUSY; - - filp->private_data = indio_dev; - - return 0; -} - -/** - * iio_chrdev_release() - chrdev file close buffer access and ioctls - **/ -static int iio_chrdev_release(struct inode *inode, struct file *filp) -{ - struct iio_dev *indio_dev = container_of(inode->i_cdev, - struct iio_dev, chrdev); - clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags); - return 0; -} - -/* Somewhat of a cross file organization violation - ioctls here are actually - * event related */ -static long iio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - struct iio_dev *indio_dev = filp->private_data; - int __user *ip = (int __user *)arg; - int fd; - - if (cmd == IIO_GET_EVENT_FD_IOCTL) { - fd = iio_event_getfd(indio_dev); - if (copy_to_user(ip, &fd, sizeof(fd))) - return -EFAULT; - return 0; - } - return -EINVAL; -} - -static const struct file_operations iio_buffer_fileops = { - .read = iio_buffer_read_first_n_outer_addr, - .release = iio_chrdev_release, - .open = iio_chrdev_open, - .poll = iio_buffer_poll_addr, - .owner = THIS_MODULE, - .llseek = noop_llseek, - .unlocked_ioctl = iio_ioctl, - .compat_ioctl = iio_ioctl, -}; - -static const struct iio_buffer_setup_ops noop_ring_setup_ops; - -int iio_device_register(struct iio_dev *indio_dev) -{ - int ret; - - /* configure elements for the chrdev */ - indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), indio_dev->id); - - ret = iio_device_register_debugfs(indio_dev); - if (ret) { - dev_err(indio_dev->dev.parent, - "Failed to register debugfs interfaces\n"); - goto error_ret; - } - ret = iio_device_register_sysfs(indio_dev); - if (ret) { - dev_err(indio_dev->dev.parent, - "Failed to register sysfs interfaces\n"); - goto error_unreg_debugfs; - } - ret = iio_device_register_eventset(indio_dev); - if (ret) { - dev_err(indio_dev->dev.parent, - "Failed to register event set\n"); - goto error_free_sysfs; - } - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) - iio_device_register_trigger_consumer(indio_dev); - - if ((indio_dev->modes & INDIO_ALL_BUFFER_MODES) && - indio_dev->setup_ops == NULL) - indio_dev->setup_ops = &noop_ring_setup_ops; - - ret = device_add(&indio_dev->dev); - if (ret < 0) - goto error_unreg_eventset; - cdev_init(&indio_dev->chrdev, &iio_buffer_fileops); - indio_dev->chrdev.owner = indio_dev->info->driver_module; - ret = cdev_add(&indio_dev->chrdev, indio_dev->dev.devt, 1); - if (ret < 0) - goto error_del_device; - return 0; - -error_del_device: - device_del(&indio_dev->dev); -error_unreg_eventset: - iio_device_unregister_eventset(indio_dev); -error_free_sysfs: - iio_device_unregister_sysfs(indio_dev); -error_unreg_debugfs: - iio_device_unregister_debugfs(indio_dev); -error_ret: - return ret; -} -EXPORT_SYMBOL(iio_device_register); - -void iio_device_unregister(struct iio_dev *indio_dev) -{ - mutex_lock(&indio_dev->info_exist_lock); - indio_dev->info = NULL; - mutex_unlock(&indio_dev->info_exist_lock); - device_unregister(&indio_dev->dev); -} -EXPORT_SYMBOL(iio_device_unregister); -subsys_initcall(iio_init); -module_exit(iio_exit); - -MODULE_AUTHOR("Jonathan Cameron "); -MODULE_DESCRIPTION("Industrial I/O core"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/iio/industrialio-event.c b/drivers/staging/iio/industrialio-event.c deleted file mode 100644 index 5fcf50b..0000000 --- a/drivers/staging/iio/industrialio-event.c +++ /dev/null @@ -1,453 +0,0 @@ -/* Industrial I/O event handling - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * Based on elements of hwmon and input subsystems. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "iio_core.h" -#include -#include - -/** - * struct iio_event_interface - chrdev interface for an event line - * @wait: wait queue to allow blocking reads of events - * @det_events: list of detected events - * @dev_attr_list: list of event interface sysfs attribute - * @flags: file operations related flags including busy flag. - * @group: event interface sysfs attribute group - */ -struct iio_event_interface { - wait_queue_head_t wait; - DECLARE_KFIFO(det_events, struct iio_event_data, 16); - - struct list_head dev_attr_list; - unsigned long flags; - struct attribute_group group; -}; - -int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp) -{ - struct iio_event_interface *ev_int = indio_dev->event_interface; - struct iio_event_data ev; - int copied; - - /* Does anyone care? */ - spin_lock(&ev_int->wait.lock); - if (test_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { - - ev.id = ev_code; - ev.timestamp = timestamp; - - copied = kfifo_put(&ev_int->det_events, &ev); - if (copied != 0) - wake_up_locked_poll(&ev_int->wait, POLLIN); - } - spin_unlock(&ev_int->wait.lock); - - return 0; -} -EXPORT_SYMBOL(iio_push_event); - -/** - * iio_event_poll() - poll the event queue to find out if it has data - */ -static unsigned int iio_event_poll(struct file *filep, - struct poll_table_struct *wait) -{ - struct iio_event_interface *ev_int = filep->private_data; - unsigned int events = 0; - - poll_wait(filep, &ev_int->wait, wait); - - spin_lock(&ev_int->wait.lock); - if (!kfifo_is_empty(&ev_int->det_events)) - events = POLLIN | POLLRDNORM; - spin_unlock(&ev_int->wait.lock); - - return events; -} - -static ssize_t iio_event_chrdev_read(struct file *filep, - char __user *buf, - size_t count, - loff_t *f_ps) -{ - struct iio_event_interface *ev_int = filep->private_data; - unsigned int copied; - int ret; - - if (count < sizeof(struct iio_event_data)) - return -EINVAL; - - spin_lock(&ev_int->wait.lock); - if (kfifo_is_empty(&ev_int->det_events)) { - if (filep->f_flags & O_NONBLOCK) { - ret = -EAGAIN; - goto error_unlock; - } - /* Blocking on device; waiting for something to be there */ - ret = wait_event_interruptible_locked(ev_int->wait, - !kfifo_is_empty(&ev_int->det_events)); - if (ret) - goto error_unlock; - /* Single access device so no one else can get the data */ - } - - ret = kfifo_to_user(&ev_int->det_events, buf, count, &copied); - -error_unlock: - spin_unlock(&ev_int->wait.lock); - - return ret ? ret : copied; -} - -static int iio_event_chrdev_release(struct inode *inode, struct file *filep) -{ - struct iio_event_interface *ev_int = filep->private_data; - - spin_lock(&ev_int->wait.lock); - __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); - /* - * In order to maintain a clean state for reopening, - * clear out any awaiting events. The mask will prevent - * any new __iio_push_event calls running. - */ - kfifo_reset_out(&ev_int->det_events); - spin_unlock(&ev_int->wait.lock); - - return 0; -} - -static const struct file_operations iio_event_chrdev_fileops = { - .read = iio_event_chrdev_read, - .poll = iio_event_poll, - .release = iio_event_chrdev_release, - .owner = THIS_MODULE, - .llseek = noop_llseek, -}; - -int iio_event_getfd(struct iio_dev *indio_dev) -{ - struct iio_event_interface *ev_int = indio_dev->event_interface; - int fd; - - if (ev_int == NULL) - return -ENODEV; - - spin_lock(&ev_int->wait.lock); - if (__test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { - spin_unlock(&ev_int->wait.lock); - return -EBUSY; - } - spin_unlock(&ev_int->wait.lock); - fd = anon_inode_getfd("iio:event", - &iio_event_chrdev_fileops, ev_int, O_RDONLY); - if (fd < 0) { - spin_lock(&ev_int->wait.lock); - __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); - spin_unlock(&ev_int->wait.lock); - } - return fd; -} - -static const char * const iio_ev_type_text[] = { - [IIO_EV_TYPE_THRESH] = "thresh", - [IIO_EV_TYPE_MAG] = "mag", - [IIO_EV_TYPE_ROC] = "roc", - [IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive", - [IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive", -}; - -static const char * const iio_ev_dir_text[] = { - [IIO_EV_DIR_EITHER] = "either", - [IIO_EV_DIR_RISING] = "rising", - [IIO_EV_DIR_FALLING] = "falling" -}; - -static ssize_t iio_ev_state_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int ret; - bool val; - - ret = strtobool(buf, &val); - if (ret < 0) - return ret; - - ret = indio_dev->info->write_event_config(indio_dev, - this_attr->address, - val); - return (ret < 0) ? ret : len; -} - -static ssize_t iio_ev_state_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int val = indio_dev->info->read_event_config(indio_dev, - this_attr->address); - - if (val < 0) - return val; - else - return sprintf(buf, "%d\n", val); -} - -static ssize_t iio_ev_value_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int val, ret; - - ret = indio_dev->info->read_event_value(indio_dev, - this_attr->address, &val); - if (ret < 0) - return ret; - - return sprintf(buf, "%d\n", val); -} - -static ssize_t iio_ev_value_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - unsigned long val; - int ret; - - if (!indio_dev->info->write_event_value) - return -EINVAL; - - ret = strict_strtoul(buf, 10, &val); - if (ret) - return ret; - - ret = indio_dev->info->write_event_value(indio_dev, this_attr->address, - val); - if (ret < 0) - return ret; - - return len; -} - -static int iio_device_add_event_sysfs(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan) -{ - int ret = 0, i, attrcount = 0; - u64 mask = 0; - char *postfix; - if (!chan->event_mask) - return 0; - - for_each_set_bit(i, &chan->event_mask, sizeof(chan->event_mask)*8) { - postfix = kasprintf(GFP_KERNEL, "%s_%s_en", - iio_ev_type_text[i/IIO_EV_DIR_MAX], - iio_ev_dir_text[i%IIO_EV_DIR_MAX]); - if (postfix == NULL) { - ret = -ENOMEM; - goto error_ret; - } - if (chan->modified) - mask = IIO_MOD_EVENT_CODE(chan->type, 0, chan->channel, - i/IIO_EV_DIR_MAX, - i%IIO_EV_DIR_MAX); - else if (chan->differential) - mask = IIO_EVENT_CODE(chan->type, - 0, 0, - i%IIO_EV_DIR_MAX, - i/IIO_EV_DIR_MAX, - 0, - chan->channel, - chan->channel2); - else - mask = IIO_UNMOD_EVENT_CODE(chan->type, - chan->channel, - i/IIO_EV_DIR_MAX, - i%IIO_EV_DIR_MAX); - - ret = __iio_add_chan_devattr(postfix, - chan, - &iio_ev_state_show, - iio_ev_state_store, - mask, - 0, - &indio_dev->dev, - &indio_dev->event_interface-> - dev_attr_list); - kfree(postfix); - if (ret) - goto error_ret; - attrcount++; - postfix = kasprintf(GFP_KERNEL, "%s_%s_value", - iio_ev_type_text[i/IIO_EV_DIR_MAX], - iio_ev_dir_text[i%IIO_EV_DIR_MAX]); - if (postfix == NULL) { - ret = -ENOMEM; - goto error_ret; - } - ret = __iio_add_chan_devattr(postfix, chan, - iio_ev_value_show, - iio_ev_value_store, - mask, - 0, - &indio_dev->dev, - &indio_dev->event_interface-> - dev_attr_list); - kfree(postfix); - if (ret) - goto error_ret; - attrcount++; - } - ret = attrcount; -error_ret: - return ret; -} - -static inline void __iio_remove_event_config_attrs(struct iio_dev *indio_dev) -{ - struct iio_dev_attr *p, *n; - list_for_each_entry_safe(p, n, - &indio_dev->event_interface-> - dev_attr_list, l) { - kfree(p->dev_attr.attr.name); - kfree(p); - } -} - -static inline int __iio_add_event_config_attrs(struct iio_dev *indio_dev) -{ - int j, ret, attrcount = 0; - - INIT_LIST_HEAD(&indio_dev->event_interface->dev_attr_list); - /* Dynically created from the channels array */ - for (j = 0; j < indio_dev->num_channels; j++) { - ret = iio_device_add_event_sysfs(indio_dev, - &indio_dev->channels[j]); - if (ret < 0) - goto error_clear_attrs; - attrcount += ret; - } - return attrcount; - -error_clear_attrs: - __iio_remove_event_config_attrs(indio_dev); - - return ret; -} - -static bool iio_check_for_dynamic_events(struct iio_dev *indio_dev) -{ - int j; - - for (j = 0; j < indio_dev->num_channels; j++) - if (indio_dev->channels[j].event_mask != 0) - return true; - return false; -} - -static void iio_setup_ev_int(struct iio_event_interface *ev_int) -{ - INIT_KFIFO(ev_int->det_events); - init_waitqueue_head(&ev_int->wait); -} - -static const char *iio_event_group_name = "events"; -int iio_device_register_eventset(struct iio_dev *indio_dev) -{ - struct iio_dev_attr *p; - int ret = 0, attrcount_orig = 0, attrcount, attrn; - struct attribute **attr; - - if (!(indio_dev->info->event_attrs || - iio_check_for_dynamic_events(indio_dev))) - return 0; - - indio_dev->event_interface = - kzalloc(sizeof(struct iio_event_interface), GFP_KERNEL); - if (indio_dev->event_interface == NULL) { - ret = -ENOMEM; - goto error_ret; - } - - iio_setup_ev_int(indio_dev->event_interface); - if (indio_dev->info->event_attrs != NULL) { - attr = indio_dev->info->event_attrs->attrs; - while (*attr++ != NULL) - attrcount_orig++; - } - attrcount = attrcount_orig; - if (indio_dev->channels) { - ret = __iio_add_event_config_attrs(indio_dev); - if (ret < 0) - goto error_free_setup_event_lines; - attrcount += ret; - } - - indio_dev->event_interface->group.name = iio_event_group_name; - indio_dev->event_interface->group.attrs = kcalloc(attrcount + 1, - sizeof(indio_dev->event_interface->group.attrs[0]), - GFP_KERNEL); - if (indio_dev->event_interface->group.attrs == NULL) { - ret = -ENOMEM; - goto error_free_setup_event_lines; - } - if (indio_dev->info->event_attrs) - memcpy(indio_dev->event_interface->group.attrs, - indio_dev->info->event_attrs->attrs, - sizeof(indio_dev->event_interface->group.attrs[0]) - *attrcount_orig); - attrn = attrcount_orig; - /* Add all elements from the list. */ - list_for_each_entry(p, - &indio_dev->event_interface->dev_attr_list, - l) - indio_dev->event_interface->group.attrs[attrn++] = - &p->dev_attr.attr; - indio_dev->groups[indio_dev->groupcounter++] = - &indio_dev->event_interface->group; - - return 0; - -error_free_setup_event_lines: - __iio_remove_event_config_attrs(indio_dev); - kfree(indio_dev->event_interface); -error_ret: - - return ret; -} - -void iio_device_unregister_eventset(struct iio_dev *indio_dev) -{ - if (indio_dev->event_interface == NULL) - return; - __iio_remove_event_config_attrs(indio_dev); - kfree(indio_dev->event_interface->group.attrs); - kfree(indio_dev->event_interface); -} diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c deleted file mode 100644 index 03fee2e..0000000 --- a/drivers/staging/iio/industrialio-trigger.c +++ /dev/null @@ -1,509 +0,0 @@ -/* The industrial I/O core, trigger handling functions - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "iio_core.h" -#include "iio_core_trigger.h" -#include - -/* RFC - Question of approach - * Make the common case (single sensor single trigger) - * simple by starting trigger capture from when first sensors - * is added. - * - * Complex simultaneous start requires use of 'hold' functionality - * of the trigger. (not implemented) - * - * Any other suggestions? - */ - -static DEFINE_IDA(iio_trigger_ida); - -/* Single list of all available triggers */ -static LIST_HEAD(iio_trigger_list); -static DEFINE_MUTEX(iio_trigger_list_lock); - -/** - * iio_trigger_read_name() - retrieve useful identifying name - **/ -static ssize_t iio_trigger_read_name(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_trigger *trig = dev_get_drvdata(dev); - return sprintf(buf, "%s\n", trig->name); -} - -static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL); - -/** - * iio_trigger_register_sysfs() - create a device for this trigger - * @trig_info: the trigger - * - * Also adds any control attribute registered by the trigger driver - **/ -static int iio_trigger_register_sysfs(struct iio_trigger *trig_info) -{ - return sysfs_add_file_to_group(&trig_info->dev.kobj, - &dev_attr_name.attr, - NULL); -} - -static void iio_trigger_unregister_sysfs(struct iio_trigger *trig_info) -{ - sysfs_remove_file_from_group(&trig_info->dev.kobj, - &dev_attr_name.attr, - NULL); -} - -int iio_trigger_register(struct iio_trigger *trig_info) -{ - int ret; - - trig_info->id = ida_simple_get(&iio_trigger_ida, 0, 0, GFP_KERNEL); - if (trig_info->id < 0) { - ret = trig_info->id; - goto error_ret; - } - /* Set the name used for the sysfs directory etc */ - dev_set_name(&trig_info->dev, "trigger%ld", - (unsigned long) trig_info->id); - - ret = device_add(&trig_info->dev); - if (ret) - goto error_unregister_id; - - ret = iio_trigger_register_sysfs(trig_info); - if (ret) - goto error_device_del; - - /* Add to list of available triggers held by the IIO core */ - mutex_lock(&iio_trigger_list_lock); - list_add_tail(&trig_info->list, &iio_trigger_list); - mutex_unlock(&iio_trigger_list_lock); - - return 0; - -error_device_del: - device_del(&trig_info->dev); -error_unregister_id: - ida_simple_remove(&iio_trigger_ida, trig_info->id); -error_ret: - return ret; -} -EXPORT_SYMBOL(iio_trigger_register); - -void iio_trigger_unregister(struct iio_trigger *trig_info) -{ - mutex_lock(&iio_trigger_list_lock); - list_del(&trig_info->list); - mutex_unlock(&iio_trigger_list_lock); - - iio_trigger_unregister_sysfs(trig_info); - ida_simple_remove(&iio_trigger_ida, trig_info->id); - /* Possible issue in here */ - device_unregister(&trig_info->dev); -} -EXPORT_SYMBOL(iio_trigger_unregister); - -static struct iio_trigger *iio_trigger_find_by_name(const char *name, - size_t len) -{ - struct iio_trigger *trig = NULL, *iter; - - mutex_lock(&iio_trigger_list_lock); - list_for_each_entry(iter, &iio_trigger_list, list) - if (sysfs_streq(iter->name, name)) { - trig = iter; - break; - } - mutex_unlock(&iio_trigger_list_lock); - - return trig; -} - -void iio_trigger_poll(struct iio_trigger *trig, s64 time) -{ - int i; - if (!trig->use_count) - for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) - if (trig->subirqs[i].enabled) { - trig->use_count++; - generic_handle_irq(trig->subirq_base + i); - } -} -EXPORT_SYMBOL(iio_trigger_poll); - -irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private) -{ - iio_trigger_poll(private, iio_get_time_ns()); - return IRQ_HANDLED; -} -EXPORT_SYMBOL(iio_trigger_generic_data_rdy_poll); - -void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time) -{ - int i; - if (!trig->use_count) - for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) - if (trig->subirqs[i].enabled) { - trig->use_count++; - handle_nested_irq(trig->subirq_base + i); - } -} -EXPORT_SYMBOL(iio_trigger_poll_chained); - -void iio_trigger_notify_done(struct iio_trigger *trig) -{ - trig->use_count--; - if (trig->use_count == 0 && trig->ops && trig->ops->try_reenable) - if (trig->ops->try_reenable(trig)) - /* Missed and interrupt so launch new poll now */ - iio_trigger_poll(trig, 0); -} -EXPORT_SYMBOL(iio_trigger_notify_done); - -/* Trigger Consumer related functions */ -static int iio_trigger_get_irq(struct iio_trigger *trig) -{ - int ret; - mutex_lock(&trig->pool_lock); - ret = bitmap_find_free_region(trig->pool, - CONFIG_IIO_CONSUMERS_PER_TRIGGER, - ilog2(1)); - mutex_unlock(&trig->pool_lock); - if (ret >= 0) - ret += trig->subirq_base; - - return ret; -} - -static void iio_trigger_put_irq(struct iio_trigger *trig, int irq) -{ - mutex_lock(&trig->pool_lock); - clear_bit(irq - trig->subirq_base, trig->pool); - mutex_unlock(&trig->pool_lock); -} - -/* Complexity in here. With certain triggers (datardy) an acknowledgement - * may be needed if the pollfuncs do not include the data read for the - * triggering device. - * This is not currently handled. Alternative of not enabling trigger unless - * the relevant function is in there may be the best option. - */ -/* Worth protecting against double additions?*/ -static int iio_trigger_attach_poll_func(struct iio_trigger *trig, - struct iio_poll_func *pf) -{ - int ret = 0; - bool notinuse - = bitmap_empty(trig->pool, CONFIG_IIO_CONSUMERS_PER_TRIGGER); - - /* Prevent the module being removed whilst attached to a trigger */ - __module_get(pf->indio_dev->info->driver_module); - pf->irq = iio_trigger_get_irq(trig); - ret = request_threaded_irq(pf->irq, pf->h, pf->thread, - pf->type, pf->name, - pf); - if (ret < 0) { - module_put(pf->indio_dev->info->driver_module); - return ret; - } - - if (trig->ops && trig->ops->set_trigger_state && notinuse) { - ret = trig->ops->set_trigger_state(trig, true); - if (ret < 0) - module_put(pf->indio_dev->info->driver_module); - } - - return ret; -} - -static int iio_trigger_dettach_poll_func(struct iio_trigger *trig, - struct iio_poll_func *pf) -{ - int ret = 0; - bool no_other_users - = (bitmap_weight(trig->pool, - CONFIG_IIO_CONSUMERS_PER_TRIGGER) - == 1); - if (trig->ops && trig->ops->set_trigger_state && no_other_users) { - ret = trig->ops->set_trigger_state(trig, false); - if (ret) - goto error_ret; - } - iio_trigger_put_irq(trig, pf->irq); - free_irq(pf->irq, pf); - module_put(pf->indio_dev->info->driver_module); - -error_ret: - return ret; -} - -irqreturn_t iio_pollfunc_store_time(int irq, void *p) -{ - struct iio_poll_func *pf = p; - pf->timestamp = iio_get_time_ns(); - return IRQ_WAKE_THREAD; -} -EXPORT_SYMBOL(iio_pollfunc_store_time); - -struct iio_poll_func -*iio_alloc_pollfunc(irqreturn_t (*h)(int irq, void *p), - irqreturn_t (*thread)(int irq, void *p), - int type, - struct iio_dev *indio_dev, - const char *fmt, - ...) -{ - va_list vargs; - struct iio_poll_func *pf; - - pf = kmalloc(sizeof *pf, GFP_KERNEL); - if (pf == NULL) - return NULL; - va_start(vargs, fmt); - pf->name = kvasprintf(GFP_KERNEL, fmt, vargs); - va_end(vargs); - if (pf->name == NULL) { - kfree(pf); - return NULL; - } - pf->h = h; - pf->thread = thread; - pf->type = type; - pf->indio_dev = indio_dev; - - return pf; -} -EXPORT_SYMBOL_GPL(iio_alloc_pollfunc); - -void iio_dealloc_pollfunc(struct iio_poll_func *pf) -{ - kfree(pf->name); - kfree(pf); -} -EXPORT_SYMBOL_GPL(iio_dealloc_pollfunc); - -/** - * iio_trigger_read_current() - trigger consumer sysfs query which trigger - * - * For trigger consumers the current_trigger interface allows the trigger - * used by the device to be queried. - **/ -static ssize_t iio_trigger_read_current(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - - if (indio_dev->trig) - return sprintf(buf, "%s\n", indio_dev->trig->name); - return 0; -} - -/** - * iio_trigger_write_current() trigger consumer sysfs set current trigger - * - * For trigger consumers the current_trigger interface allows the trigger - * used for this device to be specified at run time based on the triggers - * name. - **/ -static ssize_t iio_trigger_write_current(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_trigger *oldtrig = indio_dev->trig; - struct iio_trigger *trig; - int ret; - - mutex_lock(&indio_dev->mlock); - if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) { - mutex_unlock(&indio_dev->mlock); - return -EBUSY; - } - mutex_unlock(&indio_dev->mlock); - - trig = iio_trigger_find_by_name(buf, len); - if (oldtrig == trig) - return len; - - if (trig && indio_dev->info->validate_trigger) { - ret = indio_dev->info->validate_trigger(indio_dev, trig); - if (ret) - return ret; - } - - if (trig && trig->ops && trig->ops->validate_device) { - ret = trig->ops->validate_device(trig, indio_dev); - if (ret) - return ret; - } - - indio_dev->trig = trig; - - if (oldtrig && indio_dev->trig != oldtrig) - iio_put_trigger(oldtrig); - if (indio_dev->trig) - iio_get_trigger(indio_dev->trig); - - return len; -} - -static DEVICE_ATTR(current_trigger, S_IRUGO | S_IWUSR, - iio_trigger_read_current, - iio_trigger_write_current); - -static struct attribute *iio_trigger_consumer_attrs[] = { - &dev_attr_current_trigger.attr, - NULL, -}; - -static const struct attribute_group iio_trigger_consumer_attr_group = { - .name = "trigger", - .attrs = iio_trigger_consumer_attrs, -}; - -static void iio_trig_release(struct device *device) -{ - struct iio_trigger *trig = to_iio_trigger(device); - int i; - - if (trig->subirq_base) { - for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) { - irq_modify_status(trig->subirq_base + i, - IRQ_NOAUTOEN, - IRQ_NOREQUEST | IRQ_NOPROBE); - irq_set_chip(trig->subirq_base + i, - NULL); - irq_set_handler(trig->subirq_base + i, - NULL); - } - - irq_free_descs(trig->subirq_base, - CONFIG_IIO_CONSUMERS_PER_TRIGGER); - } - kfree(trig->name); - kfree(trig); -} - -static struct device_type iio_trig_type = { - .release = iio_trig_release, -}; - -static void iio_trig_subirqmask(struct irq_data *d) -{ - struct irq_chip *chip = irq_data_get_irq_chip(d); - struct iio_trigger *trig - = container_of(chip, - struct iio_trigger, subirq_chip); - trig->subirqs[d->irq - trig->subirq_base].enabled = false; -} - -static void iio_trig_subirqunmask(struct irq_data *d) -{ - struct irq_chip *chip = irq_data_get_irq_chip(d); - struct iio_trigger *trig - = container_of(chip, - struct iio_trigger, subirq_chip); - trig->subirqs[d->irq - trig->subirq_base].enabled = true; -} - -struct iio_trigger *iio_allocate_trigger(const char *fmt, ...) -{ - va_list vargs; - struct iio_trigger *trig; - trig = kzalloc(sizeof *trig, GFP_KERNEL); - if (trig) { - int i; - trig->dev.type = &iio_trig_type; - trig->dev.bus = &iio_bus_type; - device_initialize(&trig->dev); - dev_set_drvdata(&trig->dev, (void *)trig); - - mutex_init(&trig->pool_lock); - trig->subirq_base - = irq_alloc_descs(-1, 0, - CONFIG_IIO_CONSUMERS_PER_TRIGGER, - 0); - if (trig->subirq_base < 0) { - kfree(trig); - return NULL; - } - va_start(vargs, fmt); - trig->name = kvasprintf(GFP_KERNEL, fmt, vargs); - va_end(vargs); - if (trig->name == NULL) { - irq_free_descs(trig->subirq_base, - CONFIG_IIO_CONSUMERS_PER_TRIGGER); - kfree(trig); - return NULL; - } - trig->subirq_chip.name = trig->name; - trig->subirq_chip.irq_mask = &iio_trig_subirqmask; - trig->subirq_chip.irq_unmask = &iio_trig_subirqunmask; - for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) { - irq_set_chip(trig->subirq_base + i, - &trig->subirq_chip); - irq_set_handler(trig->subirq_base + i, - &handle_simple_irq); - irq_modify_status(trig->subirq_base + i, - IRQ_NOREQUEST | IRQ_NOAUTOEN, - IRQ_NOPROBE); - } - get_device(&trig->dev); - } - return trig; -} -EXPORT_SYMBOL(iio_allocate_trigger); - -void iio_free_trigger(struct iio_trigger *trig) -{ - if (trig) - put_device(&trig->dev); -} -EXPORT_SYMBOL(iio_free_trigger); - -void iio_device_register_trigger_consumer(struct iio_dev *indio_dev) -{ - indio_dev->groups[indio_dev->groupcounter++] = - &iio_trigger_consumer_attr_group; -} - -void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev) -{ - /* Clean up and associated but not attached triggers references */ - if (indio_dev->trig) - iio_put_trigger(indio_dev->trig); -} - -int iio_triggered_buffer_postenable(struct iio_dev *indio_dev) -{ - return iio_trigger_attach_poll_func(indio_dev->trig, - indio_dev->pollfunc); -} -EXPORT_SYMBOL(iio_triggered_buffer_postenable); - -int iio_triggered_buffer_predisable(struct iio_dev *indio_dev) -{ - return iio_trigger_dettach_poll_func(indio_dev->trig, - indio_dev->pollfunc); -} -EXPORT_SYMBOL(iio_triggered_buffer_predisable); diff --git a/drivers/staging/iio/inkern.c b/drivers/staging/iio/inkern.c deleted file mode 100644 index 22ddf62..0000000 --- a/drivers/staging/iio/inkern.c +++ /dev/null @@ -1,292 +0,0 @@ -/* The industrial I/O core in kernel channel mapping - * - * Copyright (c) 2011 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ -#include -#include -#include -#include - -#include -#include "iio_core.h" -#include -#include -#include - -struct iio_map_internal { - struct iio_dev *indio_dev; - struct iio_map *map; - struct list_head l; -}; - -static LIST_HEAD(iio_map_list); -static DEFINE_MUTEX(iio_map_list_lock); - -int iio_map_array_register(struct iio_dev *indio_dev, struct iio_map *maps) -{ - int i = 0, ret = 0; - struct iio_map_internal *mapi; - - if (maps == NULL) - return 0; - - mutex_lock(&iio_map_list_lock); - while (maps[i].consumer_dev_name != NULL) { - mapi = kzalloc(sizeof(*mapi), GFP_KERNEL); - if (mapi == NULL) { - ret = -ENOMEM; - goto error_ret; - } - mapi->map = &maps[i]; - mapi->indio_dev = indio_dev; - list_add(&mapi->l, &iio_map_list); - i++; - } -error_ret: - mutex_unlock(&iio_map_list_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(iio_map_array_register); - - -/* Assumes the exact same array (e.g. memory locations) - * used at unregistration as used at registration rather than - * more complex checking of contents. - */ -int iio_map_array_unregister(struct iio_dev *indio_dev, - struct iio_map *maps) -{ - int i = 0, ret = 0; - bool found_it; - struct iio_map_internal *mapi; - - if (maps == NULL) - return 0; - - mutex_lock(&iio_map_list_lock); - while (maps[i].consumer_dev_name != NULL) { - found_it = false; - list_for_each_entry(mapi, &iio_map_list, l) - if (&maps[i] == mapi->map) { - list_del(&mapi->l); - kfree(mapi); - found_it = true; - break; - } - if (found_it == false) { - ret = -ENODEV; - goto error_ret; - } - } -error_ret: - mutex_unlock(&iio_map_list_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(iio_map_array_unregister); - -static const struct iio_chan_spec -*iio_chan_spec_from_name(const struct iio_dev *indio_dev, - const char *name) -{ - int i; - const struct iio_chan_spec *chan = NULL; - - for (i = 0; i < indio_dev->num_channels; i++) - if (indio_dev->channels[i].datasheet_name && - strcmp(name, indio_dev->channels[i].datasheet_name) == 0) { - chan = &indio_dev->channels[i]; - break; - } - return chan; -} - - -struct iio_channel *iio_st_channel_get(const char *name, - const char *channel_name) -{ - struct iio_map_internal *c_i = NULL, *c = NULL; - struct iio_channel *channel; - - if (name == NULL && channel_name == NULL) - return ERR_PTR(-ENODEV); - - /* first find matching entry the channel map */ - mutex_lock(&iio_map_list_lock); - list_for_each_entry(c_i, &iio_map_list, l) { - if ((name && strcmp(name, c_i->map->consumer_dev_name) != 0) || - (channel_name && - strcmp(channel_name, c_i->map->consumer_channel) != 0)) - continue; - c = c_i; - get_device(&c->indio_dev->dev); - break; - } - mutex_unlock(&iio_map_list_lock); - if (c == NULL) - return ERR_PTR(-ENODEV); - - channel = kmalloc(sizeof(*channel), GFP_KERNEL); - if (channel == NULL) - return ERR_PTR(-ENOMEM); - - channel->indio_dev = c->indio_dev; - - if (c->map->adc_channel_label) - channel->channel = - iio_chan_spec_from_name(channel->indio_dev, - c->map->adc_channel_label); - - return channel; -} -EXPORT_SYMBOL_GPL(iio_st_channel_get); - -void iio_st_channel_release(struct iio_channel *channel) -{ - put_device(&channel->indio_dev->dev); - kfree(channel); -} -EXPORT_SYMBOL_GPL(iio_st_channel_release); - -struct iio_channel *iio_st_channel_get_all(const char *name) -{ - struct iio_channel *chans; - struct iio_map_internal *c = NULL; - int nummaps = 0; - int mapind = 0; - int i, ret; - - if (name == NULL) - return ERR_PTR(-EINVAL); - - mutex_lock(&iio_map_list_lock); - /* first count the matching maps */ - list_for_each_entry(c, &iio_map_list, l) - if (name && strcmp(name, c->map->consumer_dev_name) != 0) - continue; - else - nummaps++; - - if (nummaps == 0) { - ret = -ENODEV; - goto error_ret; - } - - /* NULL terminated array to save passing size */ - chans = kzalloc(sizeof(*chans)*(nummaps + 1), GFP_KERNEL); - if (chans == NULL) { - ret = -ENOMEM; - goto error_ret; - } - - /* for each map fill in the chans element */ - list_for_each_entry(c, &iio_map_list, l) { - if (name && strcmp(name, c->map->consumer_dev_name) != 0) - continue; - chans[mapind].indio_dev = c->indio_dev; - chans[mapind].channel = - iio_chan_spec_from_name(chans[mapind].indio_dev, - c->map->adc_channel_label); - if (chans[mapind].channel == NULL) { - ret = -EINVAL; - put_device(&chans[mapind].indio_dev->dev); - goto error_free_chans; - } - get_device(&chans[mapind].indio_dev->dev); - mapind++; - } - mutex_unlock(&iio_map_list_lock); - if (mapind == 0) { - ret = -ENODEV; - goto error_free_chans; - } - return chans; - -error_free_chans: - for (i = 0; i < nummaps; i++) - if (chans[i].indio_dev) - put_device(&chans[i].indio_dev->dev); - kfree(chans); -error_ret: - mutex_unlock(&iio_map_list_lock); - - return ERR_PTR(ret); -} -EXPORT_SYMBOL_GPL(iio_st_channel_get_all); - -void iio_st_channel_release_all(struct iio_channel *channels) -{ - struct iio_channel *chan = &channels[0]; - - while (chan->indio_dev) { - put_device(&chan->indio_dev->dev); - chan++; - } - kfree(channels); -} -EXPORT_SYMBOL_GPL(iio_st_channel_release_all); - -int iio_st_read_channel_raw(struct iio_channel *chan, int *val) -{ - int val2, ret; - - mutex_lock(&chan->indio_dev->info_exist_lock); - if (chan->indio_dev->info == NULL) { - ret = -ENODEV; - goto err_unlock; - } - - ret = chan->indio_dev->info->read_raw(chan->indio_dev, chan->channel, - val, &val2, 0); -err_unlock: - mutex_unlock(&chan->indio_dev->info_exist_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(iio_st_read_channel_raw); - -int iio_st_read_channel_scale(struct iio_channel *chan, int *val, int *val2) -{ - int ret; - - mutex_lock(&chan->indio_dev->info_exist_lock); - if (chan->indio_dev->info == NULL) { - ret = -ENODEV; - goto err_unlock; - } - - ret = chan->indio_dev->info->read_raw(chan->indio_dev, - chan->channel, - val, val2, - IIO_CHAN_INFO_SCALE); -err_unlock: - mutex_unlock(&chan->indio_dev->info_exist_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(iio_st_read_channel_scale); - -int iio_st_get_channel_type(struct iio_channel *chan, - enum iio_chan_type *type) -{ - int ret = 0; - /* Need to verify underlying driver has not gone away */ - - mutex_lock(&chan->indio_dev->info_exist_lock); - if (chan->indio_dev->info == NULL) { - ret = -ENODEV; - goto err_unlock; - } - - *type = chan->channel->type; -err_unlock: - mutex_unlock(&chan->indio_dev->info_exist_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(iio_st_get_channel_type); diff --git a/drivers/staging/iio/kfifo_buf.c b/drivers/staging/iio/kfifo_buf.c deleted file mode 100644 index 6bf9d05..0000000 --- a/drivers/staging/iio/kfifo_buf.c +++ /dev/null @@ -1,150 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -struct iio_kfifo { - struct iio_buffer buffer; - struct kfifo kf; - int update_needed; -}; - -#define iio_to_kfifo(r) container_of(r, struct iio_kfifo, buffer) - -static inline int __iio_allocate_kfifo(struct iio_kfifo *buf, - int bytes_per_datum, int length) -{ - if ((length == 0) || (bytes_per_datum == 0)) - return -EINVAL; - - __iio_update_buffer(&buf->buffer, bytes_per_datum, length); - return kfifo_alloc(&buf->kf, bytes_per_datum*length, GFP_KERNEL); -} - -static int iio_request_update_kfifo(struct iio_buffer *r) -{ - int ret = 0; - struct iio_kfifo *buf = iio_to_kfifo(r); - - if (!buf->update_needed) - goto error_ret; - kfifo_free(&buf->kf); - ret = __iio_allocate_kfifo(buf, buf->buffer.bytes_per_datum, - buf->buffer.length); -error_ret: - return ret; -} - -static int iio_get_length_kfifo(struct iio_buffer *r) -{ - return r->length; -} - -static IIO_BUFFER_ENABLE_ATTR; -static IIO_BUFFER_LENGTH_ATTR; - -static struct attribute *iio_kfifo_attributes[] = { - &dev_attr_length.attr, - &dev_attr_enable.attr, - NULL, -}; - -static struct attribute_group iio_kfifo_attribute_group = { - .attrs = iio_kfifo_attributes, - .name = "buffer", -}; - -static int iio_get_bytes_per_datum_kfifo(struct iio_buffer *r) -{ - return r->bytes_per_datum; -} - -static int iio_mark_update_needed_kfifo(struct iio_buffer *r) -{ - struct iio_kfifo *kf = iio_to_kfifo(r); - kf->update_needed = true; - return 0; -} - -static int iio_set_bytes_per_datum_kfifo(struct iio_buffer *r, size_t bpd) -{ - if (r->bytes_per_datum != bpd) { - r->bytes_per_datum = bpd; - iio_mark_update_needed_kfifo(r); - } - return 0; -} - -static int iio_set_length_kfifo(struct iio_buffer *r, int length) -{ - if (r->length != length) { - r->length = length; - iio_mark_update_needed_kfifo(r); - } - return 0; -} - -static int iio_store_to_kfifo(struct iio_buffer *r, - u8 *data, - s64 timestamp) -{ - int ret; - struct iio_kfifo *kf = iio_to_kfifo(r); - ret = kfifo_in(&kf->kf, data, r->bytes_per_datum); - if (ret != r->bytes_per_datum) - return -EBUSY; - return 0; -} - -static int iio_read_first_n_kfifo(struct iio_buffer *r, - size_t n, char __user *buf) -{ - int ret, copied; - struct iio_kfifo *kf = iio_to_kfifo(r); - - if (n < r->bytes_per_datum) - return -EINVAL; - - n = rounddown(n, r->bytes_per_datum); - ret = kfifo_to_user(&kf->kf, buf, n, &copied); - - return copied; -} - -static const struct iio_buffer_access_funcs kfifo_access_funcs = { - .store_to = &iio_store_to_kfifo, - .read_first_n = &iio_read_first_n_kfifo, - .request_update = &iio_request_update_kfifo, - .get_bytes_per_datum = &iio_get_bytes_per_datum_kfifo, - .set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo, - .get_length = &iio_get_length_kfifo, - .set_length = &iio_set_length_kfifo, -}; - -struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev) -{ - struct iio_kfifo *kf; - - kf = kzalloc(sizeof *kf, GFP_KERNEL); - if (!kf) - return NULL; - kf->update_needed = true; - iio_buffer_init(&kf->buffer); - kf->buffer.attrs = &iio_kfifo_attribute_group; - kf->buffer.access = &kfifo_access_funcs; - - return &kf->buffer; -} -EXPORT_SYMBOL(iio_kfifo_allocate); - -void iio_kfifo_free(struct iio_buffer *r) -{ - kfree(iio_to_kfifo(r)); -} -EXPORT_SYMBOL(iio_kfifo_free); - -MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 8af2c75a328355c23d68d3f8651ad52af3c7979d Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 25 Apr 2012 15:55:00 +0100 Subject: IIO: Move the core abi documentation from staging This file contains only the most generic elements. Other class specific and device specific ABI documents will follow over time. Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio new file mode 100644 index 0000000..2ce4dad --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -0,0 +1,730 @@ +What: /sys/bus/iio/devices/iio:deviceX +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Hardware chip or device accessed by one communication port. + Corresponds to a grouping of sensor channels. X is the IIO + index of the device. + +What: /sys/bus/iio/devices/triggerX +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + An event driven driver of data capture to an in kernel buffer. + May be provided by a device driver that also has an IIO device + based on hardware generated events (e.g. data ready) or + provided by a separate driver for other hardware (e.g. + periodic timer, GPIO or high resolution timer). + Contains trigger type specific elements. These do not + generalize well and hence are not documented in this file. + X is the IIO index of the trigger. + +What: /sys/bus/iio/devices/iio:deviceX/buffer +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Directory of attributes relating to the buffer for the device. + +What: /sys/bus/iio/devices/iio:deviceX/name +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Description of the physical chip / device for device X. + Typically a part number. + +What: /sys/bus/iio/devices/iio:deviceX/sampling_frequency +What: /sys/bus/iio/devices/iio:deviceX/buffer/sampling_frequency +What: /sys/bus/iio/devices/triggerX/sampling_frequency +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Some devices have internal clocks. This parameter sets the + resulting sampling frequency. In many devices this + parameter has an effect on input filters etc rather than + simply controlling when the input is sampled. As this + effects datardy triggers, hardware buffers and the sysfs + direct access interfaces, it may be found in any of the + relevant directories. If it effects all of the above + then it is to be found in the base device directory. + +What: /sys/bus/iio/devices/iio:deviceX/sampling_frequency_available +What: /sys/.../iio:deviceX/buffer/sampling_frequency_available +What: /sys/bus/iio/devices/triggerX/sampling_frequency_available +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + When the internal sampling clock can only take a small + discrete set of values, this file lists those available. + +What: /sys/bus/iio/devices/iio:deviceX/oversampling_ratio +KernelVersion: 2.6.38 +Contact: linux-iio@vger.kernel.org +Description: + Hardware dependent ADC oversampling. Controls the sampling ratio + of the digital filter if available. + +What: /sys/bus/iio/devices/iio:deviceX/oversampling_ratio_available +KernelVersion: 2.6.38 +Contact: linux-iio@vger.kernel.org +Description: + Hardware dependent values supported by the oversampling filter. + +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_raw +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_raw +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Raw (unscaled no bias removal etc) voltage measurement from + channel Y. In special cases where the channel does not + correspond to externally available input one of the named + versions may be used. The number must always be specified and + unique to allow association with event codes. Units after + application of scale and offset are microvolts. + +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY-voltageZ_raw +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Raw (unscaled) differential voltage measurement equivalent to + channel Y - channel Z where these channel numbers apply to the + physically equivalent inputs when non differential readings are + separately available. In differential only parts, then all that + is required is a consistent labeling. Units after application + of scale and offset are microvolts. + +What: /sys/bus/iio/devices/iio:deviceX/in_capacitanceY_raw +KernelVersion: 3.2 +Contact: linux-iio@vger.kernel.org +Description: + Raw capacitance measurement from channel Y. Units after + application of scale and offset are nanofarads. + +What: /sys/.../iio:deviceX/in_capacitanceY-in_capacitanceZ_raw +KernelVersion: 3.2 +Contact: linux-iio@vger.kernel.org +Description: + Raw differential capacitance measurement equivalent to + channel Y - channel Z where these channel numbers apply to the + physically equivalent inputs when non differential readings are + separately available. In differential only parts, then all that + is required is a consistent labeling. Units after application + of scale and offset are nanofarads. + +What: /sys/bus/iio/devices/iio:deviceX/in_temp_raw +What: /sys/bus/iio/devices/iio:deviceX/in_tempX_raw +What: /sys/bus/iio/devices/iio:deviceX/in_temp_x_raw +What: /sys/bus/iio/devices/iio:deviceX/in_temp_y_raw +What: /sys/bus/iio/devices/iio:deviceX/in_temp_z_raw +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Raw (unscaled no bias removal etc) temperature measurement. + If an axis is specified it generally means that the temperature + sensor is associated with one part of a compound device (e.g. + a gyroscope axis). Units after application of scale and offset + are milli degrees Celsuis. + +What: /sys/bus/iio/devices/iio:deviceX/in_tempX_input +KernelVersion: 2.6.38 +Contact: linux-iio@vger.kernel.org +Description: + Scaled temperature measurement in milli degrees Celsius. + +What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_raw +What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_raw +What: /sys/bus/iio/devices/iio:deviceX/in_accel_z_raw +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Acceleration in direction x, y or z (may be arbitrarily assigned + but should match other such assignments on device). + Has all of the equivalent parameters as per voltageY. Units + after application of scale and offset are m/s^2. + +What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_x_raw +What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_raw +What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_raw +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Angular velocity about axis x, y or z (may be arbitrarily + assigned) Data converted by application of offset then scale to + radians per second. Has all the equivalent parameters as + per voltageY. Units after application of scale and offset are + radians per second. + +What: /sys/bus/iio/devices/iio:deviceX/in_incli_x_raw +What: /sys/bus/iio/devices/iio:deviceX/in_incli_y_raw +What: /sys/bus/iio/devices/iio:deviceX/in_incli_z_raw +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Inclination raw reading about axis x, y or z (may be + arbitrarily assigned). Data converted by application of offset + and scale to Degrees. + +What: /sys/bus/iio/devices/iio:deviceX/in_magn_x_raw +What: /sys/bus/iio/devices/iio:deviceX/in_magn_y_raw +What: /sys/bus/iio/devices/iio:deviceX/in_magn_z_raw +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Magnetic field along axis x, y or z (may be arbitrarily + assigned). Data converted by application of offset + then scale to Gauss. + +What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_peak_raw +What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_peak_raw +What: /sys/bus/iio/devices/iio:deviceX/in_accel_z_peak_raw +KernelVersion: 2.6.36 +Contact: linux-iio@vger.kernel.org +Description: + Highest value since some reset condition. These + attributes allow access to this and are otherwise + the direct equivalent of the Y[_name]_raw attributes. + +What: /sys/bus/iio/devices/iio:deviceX/in_accel_xyz_squared_peak_raw +KernelVersion: 2.6.36 +Contact: linux-iio@vger.kernel.org +Description: + A computed peak value based on the sum squared magnitude of + the underlying value in the specified directions. + +What: /sys/bus/iio/devices/iio:deviceX/in_accel_offset +What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_offset +What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_offset +What: /sys/bus/iio/devices/iio:deviceX/in_accel_z_offset +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_offset +What: /sys/bus/iio/devices/iio:deviceX/in_voltage_offset +What: /sys/bus/iio/devices/iio:deviceX/in_tempY_offset +What: /sys/bus/iio/devices/iio:deviceX/in_temp_offset +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + If known for a device, offset to be added to [Y]_raw prior + to scaling by [Y]_scale in order to obtain value in the + units as specified in [y]_raw documentation. + Not present if the offset is always 0 or unknown. If Y or + axis is not present, then the offset applies to all + in channels of . + May be writable if a variable offset can be applied on the + device. Note that this is different to calibbias which + is for devices (or drivers) that apply offsets to compensate + for variation between different instances of the part, typically + adjusted by using some hardware supported calibration procedure. + Calibbias is applied internally, offset is applied in userspace + to the _raw output. + +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_scale +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_scale +What: /sys/bus/iio/devices/iio:deviceX/in_voltage_scale +What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_scale +What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale +What: /sys/bus/iio/devices/iio:deviceX/in_accel_peak_scale +What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_scale +What: /sys/bus/iio/devices/iio:deviceX/in_magn_scale +What: /sys/bus/iio/devices/iio:deviceX/in_magn_x_scale +What: /sys/bus/iio/devices/iio:deviceX/in_magn_y_scale +What: /sys/bus/iio/devices/iio:deviceX/in_magn_z_scale +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + If known for a device, scale to be applied to Y[_name]_raw + post addition of [Y][_name]_offset in order to obtain the + measured value in units as specified in + [Y][_name]_raw documentation. If shared across all in + channels then Y and are not present and the value is + called [Y][_name]_scale. The peak modifier means this + value is applied to Y[_name]_peak_raw values. + +What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_calibbias +What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_calibbias +What: /sys/bus/iio/devices/iio:deviceX/in_accel_z_calibbias +What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_x_calibbias +What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_calibbias +What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_calibbias +What: /sys/bus/iio/devices/iio:deviceX/in_illuminance0_calibbias +What: /sys/bus/iio/devices/iio:deviceX/in_proximity0_calibbias +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Hardware applied calibration offset. (assumed to fix production + inaccuracies). + +What /sys/bus/iio/devices/iio:deviceX/in_voltageY_calibscale +What /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_calibscale +What /sys/bus/iio/devices/iio:deviceX/in_voltage_calibscale +What /sys/bus/iio/devices/iio:deviceX/in_accel_x_calibscale +What /sys/bus/iio/devices/iio:deviceX/in_accel_y_calibscale +What /sys/bus/iio/devices/iio:deviceX/in_accel_z_calibscale +What /sys/bus/iio/devices/iio:deviceX/in_anglvel_x_calibscale +What /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_calibscale +What /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_calibscale +what /sys/bus/iio/devices/iio:deviceX/in_illuminance0_calibscale +what /sys/bus/iio/devices/iio:deviceX/in_proximity0_calibscale +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Hardware applied calibration scale factor. (assumed to fix + production inaccuracies). If shared across all channels, + _calibscale is used. + +What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale_available +What: /sys/.../iio:deviceX/in_voltageX_scale_available +What: /sys/.../iio:deviceX/in_voltage-voltage_scale_available +What: /sys/.../iio:deviceX/out_voltageX_scale_available +What: /sys/.../iio:deviceX/in_capacitance_scale_available +KernelVersion: 2.635 +Contact: linux-iio@vger.kernel.org +Description: + If a discrete set of scale values are available, they + are listed in this attribute. + +What: /sys/.../in_accel_filter_low_pass_3db_frequency +What: /sys/.../in_magn_filter_low_pass_3db_frequency +What: /sys/.../in_anglvel_filter_low_pass_3db_frequency +KernelVersion: 3.2 +Contact: linux-iio@vger.kernel.org +Description: + If a known or controllable low pass filter is applied + to the underlying data channel, then this parameter + gives the 3dB frequency of the filter in Hz. + +What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_raw +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Raw (unscaled, no bias etc.) output voltage for + channel Y. The number must always be specified and + unique if the output corresponds to a single channel. + +What: /sys/bus/iio/devices/iio:deviceX/out_voltageY&Z_raw +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Raw (unscaled, no bias etc.) output voltage for an aggregate of + channel Y, channel Z, etc. This interface is available in cases + where a single output sets the value for multiple channels + simultaneously. + +What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown_mode +What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown_mode +KernelVersion: 2.6.38 +Contact: linux-iio@vger.kernel.org +Description: + Specifies the output powerdown mode. + DAC output stage is disconnected from the amplifier and + 1kohm_to_gnd: connected to ground via an 1kOhm resistor + 100kohm_to_gnd: connected to ground via an 100kOhm resistor + three_state: left floating + For a list of available output power down options read + outX_powerdown_mode_available. If Y is not present the + mode is shared across all outputs. + +What: /sys/.../iio:deviceX/out_votlageY_powerdown_mode_available +What: /sys/.../iio:deviceX/out_voltage_powerdown_mode_available +KernelVersion: 2.6.38 +Contact: linux-iio@vger.kernel.org +Description: + Lists all available output power down modes. + If Y is not present the mode is shared across all outputs. + +What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown +What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown +KernelVersion: 2.6.38 +Contact: linux-iio@vger.kernel.org +Description: + Writing 1 causes output Y to enter the power down mode specified + by the corresponding outY_powerdown_mode. Clearing returns to + normal operation. Y may be suppressed if all outputs are + controlled together. + +What: /sys/bus/iio/devices/iio:deviceX/events +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Configuration of which hardware generated events are passed up + to user-space. + +What: /sys/.../iio:deviceX/events/in_accel_x_thresh_rising_en +What: /sys/.../iio:deviceX/events/in_accel_x_thresh_falling_en +What: /sys/.../iio:deviceX/events/in_accel_y_thresh_rising_en +What: /sys/.../iio:deviceX/events/in_accel_y_thresh_falling_en +What: /sys/.../iio:deviceX/events/in_accel_z_thresh_rising_en +What: /sys/.../iio:deviceX/events/in_accel_z_thresh_falling_en +What: /sys/.../iio:deviceX/events/in_anglvel_x_thresh_rising_en +What: /sys/.../iio:deviceX/events/in_anglvel_x_thresh_falling_en +What: /sys/.../iio:deviceX/events/in_anglvel_y_thresh_rising_en +What: /sys/.../iio:deviceX/events/in_anglvel_y_thresh_falling_en +What: /sys/.../iio:deviceX/events/in_anglvel_z_thresh_rising_en +What: /sys/.../iio:deviceX/events/in_anglvel_z_thresh_falling_en +What: /sys/.../iio:deviceX/events/in_magn_x_thresh_rising_en +What: /sys/.../iio:deviceX/events/in_magn_x_thresh_falling_en +What: /sys/.../iio:deviceX/events/in_magn_y_thresh_rising_en +What: /sys/.../iio:deviceX/events/in_magn_y_thresh_falling_en +What: /sys/.../iio:deviceX/events/in_magn_z_thresh_rising_en +What: /sys/.../iio:deviceX/events/in_magn_z_thresh_falling_en +What: /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_rising_en +What: /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_falling_en +What: /sys/.../iio:deviceX/events/in_voltageY_thresh_rising_en +What: /sys/.../iio:deviceX/events/in_voltageY_thresh_falling_en +What: /sys/.../iio:deviceX/events/in_tempY_thresh_rising_en +What: /sys/.../iio:deviceX/events/in_tempY_thresh_falling_en +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Event generated when channel passes a threshold in the specified + (_rising|_falling) direction. If the direction is not specified, + then either the device will report an event which ever direction + a single threshold value is passed in (e.g. + [Y][_name]__thresh_value) or + [Y][_name]__thresh_rising_value and + [Y][_name]__thresh_falling_value may take + different values, but the device can only enable both thresholds + or neither. + Note the driver will assume the last p events requested are + to be enabled where p is however many it supports (which may + vary depending on the exact set requested. So if you want to be + sure you have set what you think you have, check the contents of + these attributes after everything is configured. Drivers may + have to buffer any parameters so that they are consistent when + a given event type is enabled a future point (and not those for + whatever event was previously enabled). + +What: /sys/.../iio:deviceX/events/in_accel_x_roc_rising_en +What: /sys/.../iio:deviceX/events/in_accel_x_roc_falling_en +What: /sys/.../iio:deviceX/events/in_accel_y_roc_rising_en +What: /sys/.../iio:deviceX/events/in_accel_y_roc_falling_en +What: /sys/.../iio:deviceX/events/in_accel_z_roc_rising_en +What: /sys/.../iio:deviceX/events/in_accel_z_roc_falling_en +What: /sys/.../iio:deviceX/events/in_anglvel_x_roc_rising_en +What: /sys/.../iio:deviceX/events/in_anglvel_x_roc_falling_en +What: /sys/.../iio:deviceX/events/in_anglvel_y_roc_rising_en +What: /sys/.../iio:deviceX/events/in_anglvel_y_roc_falling_en +What: /sys/.../iio:deviceX/events/in_anglvel_z_roc_rising_en +What: /sys/.../iio:deviceX/events/in_anglvel_z_roc_falling_en +What: /sys/.../iio:deviceX/events/in_magn_x_roc_rising_en +What: /sys/.../iio:deviceX/events/in_magn_x_roc_falling_en +What: /sys/.../iio:deviceX/events/in_magn_y_roc_rising_en +What: /sys/.../iio:deviceX/events/in_magn_y_roc_falling_en +What: /sys/.../iio:deviceX/events/in_magn_z_roc_rising_en +What: /sys/.../iio:deviceX/events/in_magn_z_roc_falling_en +What: /sys/.../iio:deviceX/events/in_voltageY_supply_roc_rising_en +What: /sys/.../iio:deviceX/events/in_voltageY_supply_roc_falling_en +What: /sys/.../iio:deviceX/events/in_voltageY_roc_rising_en +What: /sys/.../iio:deviceX/events/in_voltageY_roc_falling_en +What: /sys/.../iio:deviceX/events/in_tempY_roc_rising_en +What: /sys/.../iio:deviceX/events/in_tempY_roc_falling_en +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Event generated when channel passes a threshold on the rate of + change (1st differential) in the specified (_rising|_falling) + direction. If the direction is not specified, then either the + device will report an event which ever direction a single + threshold value is passed in (e.g. + [Y][_name]__roc_value) or + [Y][_name]__roc_rising_value and + [Y][_name]__roc_falling_value may take + different values, but the device can only enable both rate of + change thresholds or neither. + Note the driver will assume the last p events requested are + to be enabled where p is however many it supports (which may + vary depending on the exact set requested. So if you want to be + sure you have set what you think you have, check the contents of + these attributes after everything is configured. Drivers may + have to buffer any parameters so that they are consistent when + a given event type is enabled a future point (and not those for + whatever event was previously enabled). + +What: /sys/.../events/in_accel_x_raw_thresh_rising_value +What: /sys/.../events/in_accel_x_raw_thresh_falling_value +What: /sys/.../events/in_accel_y_raw_thresh_rising_value +What: /sys/.../events/in_accel_y_raw_thresh_falling_value +What: /sys/.../events/in_accel_z_raw_thresh_rising_value +What: /sys/.../events/in_accel_z_raw_thresh_falling_value +What: /sys/.../events/in_anglvel_x_raw_thresh_rising_value +What: /sys/.../events/in_anglvel_x_raw_thresh_falling_value +What: /sys/.../events/in_anglvel_y_raw_thresh_rising_value +What: /sys/.../events/in_anglvel_y_raw_thresh_falling_value +What: /sys/.../events/in_anglvel_z_raw_thresh_rising_value +What: /sys/.../events/in_anglvel_z_raw_thresh_falling_value +What: /sys/.../events/in_magn_x_raw_thresh_rising_value +What: /sys/.../events/in_magn_x_raw_thresh_falling_value +What: /sys/.../events/in_magn_y_raw_thresh_rising_value +What: /sys/.../events/in_magn_y_raw_thresh_falling_value +What: /sys/.../events/in_magn_z_raw_thresh_rising_value +What: /sys/.../events/in_magn_z_raw_thresh_falling_value +What: /sys/.../events/in_voltageY_supply_raw_thresh_rising_value +What: /sys/.../events/in_voltageY_supply_raw_thresh_falling_value +What: /sys/.../events/in_voltageY_raw_thresh_rising_value +What: /sys/.../events/in_voltageY_raw_thresh_falling_value +What: /sys/.../events/in_tempY_raw_thresh_rising_value +What: /sys/.../events/in_tempY_raw_thresh_falling_value +What: /sys/.../events/in_illuminance0_thresh_falling_value +what: /sys/.../events/in_illuminance0_thresh_rising_value +what: /sys/.../events/in_proximity0_thresh_falling_value +what: /sys/.../events/in_proximity0_thresh_rising_value +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Specifies the value of threshold that the device is comparing + against for the events enabled by + Y[_name]_thresh[_rising|falling]_en. + If separate attributes exist for the two directions, but + direction is not specified for this attribute, then a single + threshold value applies to both directions. + The raw or input element of the name indicates whether the + value is in raw device units or in processed units (as _raw + and _input do on sysfs direct channel read attributes). + +What: /sys/.../events/in_accel_x_raw_roc_rising_value +What: /sys/.../events/in_accel_x_raw_roc_falling_value +What: /sys/.../events/in_accel_y_raw_roc_rising_value +What: /sys/.../events/in_accel_y_raw_roc_falling_value +What: /sys/.../events/in_accel_z_raw_roc_rising_value +What: /sys/.../events/in_accel_z_raw_roc_falling_value +What: /sys/.../events/in_anglvel_x_raw_roc_rising_value +What: /sys/.../events/in_anglvel_x_raw_roc_falling_value +What: /sys/.../events/in_anglvel_y_raw_roc_rising_value +What: /sys/.../events/in_anglvel_y_raw_roc_falling_value +What: /sys/.../events/in_anglvel_z_raw_roc_rising_value +What: /sys/.../events/in_anglvel_z_raw_roc_falling_value +What: /sys/.../events/in_magn_x_raw_roc_rising_value +What: /sys/.../events/in_magn_x_raw_roc_falling_value +What: /sys/.../events/in_magn_y_raw_roc_rising_value +What: /sys/.../events/in_magn_y_raw_roc_falling_value +What: /sys/.../events/in_magn_z_raw_roc_rising_value +What: /sys/.../events/in_magn_z_raw_roc_falling_value +What: /sys/.../events/in_voltageY_supply_raw_roc_rising_value +What: /sys/.../events/in_voltageY_supply_raw_roc_falling_value +What: /sys/.../events/in_voltageY_raw_roc_rising_value +What: /sys/.../events/in_voltageY_raw_roc_falling_value +What: /sys/.../events/in_tempY_raw_roc_rising_value +What: /sys/.../events/in_tempY_raw_roc_falling_value +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Specifies the value of rate of change threshold that the + device is comparing against for the events enabled by + [Y][_name]_roc[_rising|falling]_en. + If separate attributes exist for the two directions, + but direction is not specified for this attribute, + then a single threshold value applies to both directions. + The raw or input element of the name indicates whether the + value is in raw device units or in processed units (as _raw + and _input do on sysfs direct channel read attributes). + +What: /sys/.../events/in_accel_x_thresh_rising_period +What: /sys/.../events/in_accel_x_thresh_falling_period +hat: /sys/.../events/in_accel_x_roc_rising_period +What: /sys/.../events/in_accel_x_roc_falling_period +What: /sys/.../events/in_accel_y_thresh_rising_period +What: /sys/.../events/in_accel_y_thresh_falling_period +What: /sys/.../events/in_accel_y_roc_rising_period +What: /sys/.../events/in_accel_y_roc_falling_period +What: /sys/.../events/in_accel_z_thresh_rising_period +What: /sys/.../events/in_accel_z_thresh_falling_period +What: /sys/.../events/in_accel_z_roc_rising_period +What: /sys/.../events/in_accel_z_roc_falling_period +What: /sys/.../events/in_anglvel_x_thresh_rising_period +What: /sys/.../events/in_anglvel_x_thresh_falling_period +What: /sys/.../events/in_anglvel_x_roc_rising_period +What: /sys/.../events/in_anglvel_x_roc_falling_period +What: /sys/.../events/in_anglvel_y_thresh_rising_period +What: /sys/.../events/in_anglvel_y_thresh_falling_period +What: /sys/.../events/in_anglvel_y_roc_rising_period +What: /sys/.../events/in_anglvel_y_roc_falling_period +What: /sys/.../events/in_anglvel_z_thresh_rising_period +What: /sys/.../events/in_anglvel_z_thresh_falling_period +What: /sys/.../events/in_anglvel_z_roc_rising_period +What: /sys/.../events/in_anglvel_z_roc_falling_period +What: /sys/.../events/in_magn_x_thresh_rising_period +What: /sys/.../events/in_magn_x_thresh_falling_period +What: /sys/.../events/in_magn_x_roc_rising_period +What: /sys/.../events/in_magn_x_roc_falling_period +What: /sys/.../events/in_magn_y_thresh_rising_period +What: /sys/.../events/in_magn_y_thresh_falling_period +What: /sys/.../events/in_magn_y_roc_rising_period +What: /sys/.../events/in_magn_y_roc_falling_period +What: /sys/.../events/in_magn_z_thresh_rising_period +What: /sys/.../events/in_magn_z_thresh_falling_period +What: /sys/.../events/in_magn_z_roc_rising_period +What: /sys/.../events/in_magn_z_roc_falling_period +What: /sys/.../events/in_voltageY_supply_thresh_rising_period +What: /sys/.../events/in_voltageY_supply_thresh_falling_period +What: /sys/.../events/in_voltageY_supply_roc_rising_period +What: /sys/.../events/in_voltageY_supply_roc_falling_period +What: /sys/.../events/in_voltageY_thresh_rising_period +What: /sys/.../events/in_voltageY_thresh_falling_period +What: /sys/.../events/in_voltageY_roc_rising_period +What: /sys/.../events/in_voltageY_roc_falling_period +What: /sys/.../events/in_tempY_thresh_rising_period +What: /sys/.../events/in_tempY_thresh_falling_period +What: /sys/.../events/in_tempY_roc_rising_period +What: /sys/.../events/in_tempY_roc_falling_period +What: /sys/.../events/in_accel_x&y&z_mag_falling_period +What: /sys/.../events/in_intensity0_thresh_period +What: /sys/.../events/in_proximity0_thresh_period +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Period of time (in seconds) for which the condition must be + met before an event is generated. If direction is not + specified then this period applies to both directions. + +What: /sys/.../iio:deviceX/events/in_accel_mag_en +What: /sys/.../iio:deviceX/events/in_accel_mag_rising_en +What: /sys/.../iio:deviceX/events/in_accel_mag_falling_en +What: /sys/.../iio:deviceX/events/in_accel_x_mag_en +What: /sys/.../iio:deviceX/events/in_accel_x_mag_rising_en +What: /sys/.../iio:deviceX/events/in_accel_x_mag_falling_en +What: /sys/.../iio:deviceX/events/in_accel_y_mag_en +What: /sys/.../iio:deviceX/events/in_accel_y_mag_rising_en +What: /sys/.../iio:deviceX/events/in_accel_y_mag_falling_en +What: /sys/.../iio:deviceX/events/in_accel_z_mag_en +What: /sys/.../iio:deviceX/events/in_accel_z_mag_rising_en +What: /sys/.../iio:deviceX/events/in_accel_z_mag_falling_en +What: /sys/.../iio:deviceX/events/in_accel_x&y&z_mag_rising_en +What: /sys/.../iio:deviceX/events/in_accel_x&y&z_mag_falling_en +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Similar to in_accel_x_thresh[_rising|_falling]_en, but here the + magnitude of the channel is compared to the threshold, not its + signed value. + +What: /sys/.../events/in_accel_raw_mag_value +What: /sys/.../events/in_accel_x_raw_mag_rising_value +What: /sys/.../events/in_accel_y_raw_mag_rising_value +What: /sys/.../events/in_accel_z_raw_mag_rising_value +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + The value to which the magnitude of the channel is compared. If + number or direction is not specified, applies to all channels of + this type. + +What: /sys/bus/iio/devices/iio:deviceX/trigger/current_trigger +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + The name of the trigger source being used, as per string given + in /sys/class/iio/triggerY/name. + +What: /sys/bus/iio/devices/iio:deviceX/buffer/length +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Number of scans contained by the buffer. + +What: /sys/bus/iio/devices/iio:deviceX/buffer/bytes_per_datum +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Bytes per scan. Due to alignment fun, the scan may be larger + than implied directly by the scan_element parameters. + +What: /sys/bus/iio/devices/iio:deviceX/buffer/enable +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Actually start the buffer capture up. Will start trigger + if first device and appropriate. + +What: /sys/bus/iio/devices/iio:deviceX/buffer/scan_elements +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Directory containing interfaces for elements that will be + captured for a single triggered sample set in the buffer. + +What: /sys/.../buffer/scan_elements/in_accel_x_en +What: /sys/.../buffer/scan_elements/in_accel_y_en +What: /sys/.../buffer/scan_elements/in_accel_z_en +What: /sys/.../buffer/scan_elements/in_anglvel_x_en +What: /sys/.../buffer/scan_elements/in_anglvel_y_en +What: /sys/.../buffer/scan_elements/in_anglvel_z_en +What: /sys/.../buffer/scan_elements/in_magn_x_en +What: /sys/.../buffer/scan_elements/in_magn_y_en +What: /sys/.../buffer/scan_elements/in_magn_z_en +What: /sys/.../buffer/scan_elements/in_timestamp_en +What: /sys/.../buffer/scan_elements/in_voltageY_supply_en +What: /sys/.../buffer/scan_elements/in_voltageY_en +What: /sys/.../buffer/scan_elements/in_voltageY-voltageZ_en +What: /sys/.../buffer/scan_elements/in_incli_x_en +What: /sys/.../buffer/scan_elements/in_incli_y_en +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Scan element control for triggered data capture. + +What: /sys/.../buffer/scan_elements/in_accel_type +What: /sys/.../buffer/scan_elements/in_anglvel_type +What: /sys/.../buffer/scan_elements/in_magn_type +What: /sys/.../buffer/scan_elements/in_incli_type +What: /sys/.../buffer/scan_elements/in_voltageY_type +What: /sys/.../buffer/scan_elements/in_voltage-in_type +What: /sys/.../buffer/scan_elements/in_voltageY_supply_type +What: /sys/.../buffer/scan_elements/in_timestamp_type +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Description of the scan element data storage within the buffer + and hence the form in which it is read from user-space. + Form is [be|le]:[s|u]bits/storagebits[>>shift]. + be or le specifies big or little endian. s or u specifies if + signed (2's complement) or unsigned. bits is the number of bits + of data and storagebits is the space (after padding) that it + occupies in the buffer. shift if specified, is the shift that + needs to be applied prior to masking out unused bits. Some + devices put their data in the middle of the transferred elements + with additional information on both sides. Note that some + devices will have additional information in the unused bits + so to get a clean value, the bits value must be used to mask + the buffer output value appropriately. The storagebits value + also specifies the data alignment. So s48/64>>2 will be a + signed 48 bit integer stored in a 64 bit location aligned to + a a64 bit boundary. To obtain the clean value, shift right 2 + and apply a mask to zero the top 16 bits of the result. + For other storage combinations this attribute will be extended + appropriately. + +What: /sys/.../buffer/scan_elements/in_accel_type_available +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + If the type parameter can take one of a small set of values, + this attribute lists them. + +What: /sys/.../buffer/scan_elements/in_voltageY_index +What: /sys/.../buffer/scan_elements/in_voltageY_supply_index +What: /sys/.../buffer/scan_elements/in_accel_x_index +What: /sys/.../buffer/scan_elements/in_accel_y_index +What: /sys/.../buffer/scan_elements/in_accel_z_index +What: /sys/.../buffer/scan_elements/in_anglvel_x_index +What: /sys/.../buffer/scan_elements/in_anglvel_y_index +What: /sys/.../buffer/scan_elements/in_anglvel_z_index +What: /sys/.../buffer/scan_elements/in_magn_x_index +What: /sys/.../buffer/scan_elements/in_magn_y_index +What: /sys/.../buffer/scan_elements/in_magn_z_index +What: /sys/.../buffer/scan_elements/in_incli_x_index +What: /sys/.../buffer/scan_elements/in_incli_y_index +What: /sys/.../buffer/scan_elements/in_timestamp_index +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + A single positive integer specifying the position of this + scan element in the buffer. Note these are not dependent on + what is enabled and may not be contiguous. Thus for user-space + to establish the full layout these must be used in conjunction + with all _en attributes to establish which channels are present, + and the relevant _type attributes to establish the data storage + format. + +What: /sys/.../iio:deviceX/in_anglvel_z_quadrature_correction_raw +KernelVersion: 2.6.38 +Contact: linux-iio@vger.kernel.org +Description: + This attribute is used to read the amount of quadrature error + present in the device at a given time. diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio b/drivers/staging/iio/Documentation/sysfs-bus-iio deleted file mode 100644 index 2ce4dad..0000000 --- a/drivers/staging/iio/Documentation/sysfs-bus-iio +++ /dev/null @@ -1,730 +0,0 @@ -What: /sys/bus/iio/devices/iio:deviceX -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Hardware chip or device accessed by one communication port. - Corresponds to a grouping of sensor channels. X is the IIO - index of the device. - -What: /sys/bus/iio/devices/triggerX -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - An event driven driver of data capture to an in kernel buffer. - May be provided by a device driver that also has an IIO device - based on hardware generated events (e.g. data ready) or - provided by a separate driver for other hardware (e.g. - periodic timer, GPIO or high resolution timer). - Contains trigger type specific elements. These do not - generalize well and hence are not documented in this file. - X is the IIO index of the trigger. - -What: /sys/bus/iio/devices/iio:deviceX/buffer -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Directory of attributes relating to the buffer for the device. - -What: /sys/bus/iio/devices/iio:deviceX/name -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Description of the physical chip / device for device X. - Typically a part number. - -What: /sys/bus/iio/devices/iio:deviceX/sampling_frequency -What: /sys/bus/iio/devices/iio:deviceX/buffer/sampling_frequency -What: /sys/bus/iio/devices/triggerX/sampling_frequency -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Some devices have internal clocks. This parameter sets the - resulting sampling frequency. In many devices this - parameter has an effect on input filters etc rather than - simply controlling when the input is sampled. As this - effects datardy triggers, hardware buffers and the sysfs - direct access interfaces, it may be found in any of the - relevant directories. If it effects all of the above - then it is to be found in the base device directory. - -What: /sys/bus/iio/devices/iio:deviceX/sampling_frequency_available -What: /sys/.../iio:deviceX/buffer/sampling_frequency_available -What: /sys/bus/iio/devices/triggerX/sampling_frequency_available -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - When the internal sampling clock can only take a small - discrete set of values, this file lists those available. - -What: /sys/bus/iio/devices/iio:deviceX/oversampling_ratio -KernelVersion: 2.6.38 -Contact: linux-iio@vger.kernel.org -Description: - Hardware dependent ADC oversampling. Controls the sampling ratio - of the digital filter if available. - -What: /sys/bus/iio/devices/iio:deviceX/oversampling_ratio_available -KernelVersion: 2.6.38 -Contact: linux-iio@vger.kernel.org -Description: - Hardware dependent values supported by the oversampling filter. - -What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_raw -What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_raw -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Raw (unscaled no bias removal etc) voltage measurement from - channel Y. In special cases where the channel does not - correspond to externally available input one of the named - versions may be used. The number must always be specified and - unique to allow association with event codes. Units after - application of scale and offset are microvolts. - -What: /sys/bus/iio/devices/iio:deviceX/in_voltageY-voltageZ_raw -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Raw (unscaled) differential voltage measurement equivalent to - channel Y - channel Z where these channel numbers apply to the - physically equivalent inputs when non differential readings are - separately available. In differential only parts, then all that - is required is a consistent labeling. Units after application - of scale and offset are microvolts. - -What: /sys/bus/iio/devices/iio:deviceX/in_capacitanceY_raw -KernelVersion: 3.2 -Contact: linux-iio@vger.kernel.org -Description: - Raw capacitance measurement from channel Y. Units after - application of scale and offset are nanofarads. - -What: /sys/.../iio:deviceX/in_capacitanceY-in_capacitanceZ_raw -KernelVersion: 3.2 -Contact: linux-iio@vger.kernel.org -Description: - Raw differential capacitance measurement equivalent to - channel Y - channel Z where these channel numbers apply to the - physically equivalent inputs when non differential readings are - separately available. In differential only parts, then all that - is required is a consistent labeling. Units after application - of scale and offset are nanofarads. - -What: /sys/bus/iio/devices/iio:deviceX/in_temp_raw -What: /sys/bus/iio/devices/iio:deviceX/in_tempX_raw -What: /sys/bus/iio/devices/iio:deviceX/in_temp_x_raw -What: /sys/bus/iio/devices/iio:deviceX/in_temp_y_raw -What: /sys/bus/iio/devices/iio:deviceX/in_temp_z_raw -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Raw (unscaled no bias removal etc) temperature measurement. - If an axis is specified it generally means that the temperature - sensor is associated with one part of a compound device (e.g. - a gyroscope axis). Units after application of scale and offset - are milli degrees Celsuis. - -What: /sys/bus/iio/devices/iio:deviceX/in_tempX_input -KernelVersion: 2.6.38 -Contact: linux-iio@vger.kernel.org -Description: - Scaled temperature measurement in milli degrees Celsius. - -What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_raw -What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_raw -What: /sys/bus/iio/devices/iio:deviceX/in_accel_z_raw -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Acceleration in direction x, y or z (may be arbitrarily assigned - but should match other such assignments on device). - Has all of the equivalent parameters as per voltageY. Units - after application of scale and offset are m/s^2. - -What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_x_raw -What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_raw -What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_raw -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Angular velocity about axis x, y or z (may be arbitrarily - assigned) Data converted by application of offset then scale to - radians per second. Has all the equivalent parameters as - per voltageY. Units after application of scale and offset are - radians per second. - -What: /sys/bus/iio/devices/iio:deviceX/in_incli_x_raw -What: /sys/bus/iio/devices/iio:deviceX/in_incli_y_raw -What: /sys/bus/iio/devices/iio:deviceX/in_incli_z_raw -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Inclination raw reading about axis x, y or z (may be - arbitrarily assigned). Data converted by application of offset - and scale to Degrees. - -What: /sys/bus/iio/devices/iio:deviceX/in_magn_x_raw -What: /sys/bus/iio/devices/iio:deviceX/in_magn_y_raw -What: /sys/bus/iio/devices/iio:deviceX/in_magn_z_raw -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Magnetic field along axis x, y or z (may be arbitrarily - assigned). Data converted by application of offset - then scale to Gauss. - -What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_peak_raw -What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_peak_raw -What: /sys/bus/iio/devices/iio:deviceX/in_accel_z_peak_raw -KernelVersion: 2.6.36 -Contact: linux-iio@vger.kernel.org -Description: - Highest value since some reset condition. These - attributes allow access to this and are otherwise - the direct equivalent of the Y[_name]_raw attributes. - -What: /sys/bus/iio/devices/iio:deviceX/in_accel_xyz_squared_peak_raw -KernelVersion: 2.6.36 -Contact: linux-iio@vger.kernel.org -Description: - A computed peak value based on the sum squared magnitude of - the underlying value in the specified directions. - -What: /sys/bus/iio/devices/iio:deviceX/in_accel_offset -What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_offset -What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_offset -What: /sys/bus/iio/devices/iio:deviceX/in_accel_z_offset -What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_offset -What: /sys/bus/iio/devices/iio:deviceX/in_voltage_offset -What: /sys/bus/iio/devices/iio:deviceX/in_tempY_offset -What: /sys/bus/iio/devices/iio:deviceX/in_temp_offset -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - If known for a device, offset to be added to [Y]_raw prior - to scaling by [Y]_scale in order to obtain value in the - units as specified in [y]_raw documentation. - Not present if the offset is always 0 or unknown. If Y or - axis is not present, then the offset applies to all - in channels of . - May be writable if a variable offset can be applied on the - device. Note that this is different to calibbias which - is for devices (or drivers) that apply offsets to compensate - for variation between different instances of the part, typically - adjusted by using some hardware supported calibration procedure. - Calibbias is applied internally, offset is applied in userspace - to the _raw output. - -What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_scale -What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_scale -What: /sys/bus/iio/devices/iio:deviceX/in_voltage_scale -What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_scale -What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale -What: /sys/bus/iio/devices/iio:deviceX/in_accel_peak_scale -What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_scale -What: /sys/bus/iio/devices/iio:deviceX/in_magn_scale -What: /sys/bus/iio/devices/iio:deviceX/in_magn_x_scale -What: /sys/bus/iio/devices/iio:deviceX/in_magn_y_scale -What: /sys/bus/iio/devices/iio:deviceX/in_magn_z_scale -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - If known for a device, scale to be applied to Y[_name]_raw - post addition of [Y][_name]_offset in order to obtain the - measured value in units as specified in - [Y][_name]_raw documentation. If shared across all in - channels then Y and are not present and the value is - called [Y][_name]_scale. The peak modifier means this - value is applied to Y[_name]_peak_raw values. - -What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_calibbias -What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_calibbias -What: /sys/bus/iio/devices/iio:deviceX/in_accel_z_calibbias -What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_x_calibbias -What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_calibbias -What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_calibbias -What: /sys/bus/iio/devices/iio:deviceX/in_illuminance0_calibbias -What: /sys/bus/iio/devices/iio:deviceX/in_proximity0_calibbias -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Hardware applied calibration offset. (assumed to fix production - inaccuracies). - -What /sys/bus/iio/devices/iio:deviceX/in_voltageY_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_voltage_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_accel_x_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_accel_y_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_accel_z_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_anglvel_x_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_calibscale -what /sys/bus/iio/devices/iio:deviceX/in_illuminance0_calibscale -what /sys/bus/iio/devices/iio:deviceX/in_proximity0_calibscale -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Hardware applied calibration scale factor. (assumed to fix - production inaccuracies). If shared across all channels, - _calibscale is used. - -What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale_available -What: /sys/.../iio:deviceX/in_voltageX_scale_available -What: /sys/.../iio:deviceX/in_voltage-voltage_scale_available -What: /sys/.../iio:deviceX/out_voltageX_scale_available -What: /sys/.../iio:deviceX/in_capacitance_scale_available -KernelVersion: 2.635 -Contact: linux-iio@vger.kernel.org -Description: - If a discrete set of scale values are available, they - are listed in this attribute. - -What: /sys/.../in_accel_filter_low_pass_3db_frequency -What: /sys/.../in_magn_filter_low_pass_3db_frequency -What: /sys/.../in_anglvel_filter_low_pass_3db_frequency -KernelVersion: 3.2 -Contact: linux-iio@vger.kernel.org -Description: - If a known or controllable low pass filter is applied - to the underlying data channel, then this parameter - gives the 3dB frequency of the filter in Hz. - -What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_raw -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Raw (unscaled, no bias etc.) output voltage for - channel Y. The number must always be specified and - unique if the output corresponds to a single channel. - -What: /sys/bus/iio/devices/iio:deviceX/out_voltageY&Z_raw -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Raw (unscaled, no bias etc.) output voltage for an aggregate of - channel Y, channel Z, etc. This interface is available in cases - where a single output sets the value for multiple channels - simultaneously. - -What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown_mode -What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown_mode -KernelVersion: 2.6.38 -Contact: linux-iio@vger.kernel.org -Description: - Specifies the output powerdown mode. - DAC output stage is disconnected from the amplifier and - 1kohm_to_gnd: connected to ground via an 1kOhm resistor - 100kohm_to_gnd: connected to ground via an 100kOhm resistor - three_state: left floating - For a list of available output power down options read - outX_powerdown_mode_available. If Y is not present the - mode is shared across all outputs. - -What: /sys/.../iio:deviceX/out_votlageY_powerdown_mode_available -What: /sys/.../iio:deviceX/out_voltage_powerdown_mode_available -KernelVersion: 2.6.38 -Contact: linux-iio@vger.kernel.org -Description: - Lists all available output power down modes. - If Y is not present the mode is shared across all outputs. - -What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown -What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown -KernelVersion: 2.6.38 -Contact: linux-iio@vger.kernel.org -Description: - Writing 1 causes output Y to enter the power down mode specified - by the corresponding outY_powerdown_mode. Clearing returns to - normal operation. Y may be suppressed if all outputs are - controlled together. - -What: /sys/bus/iio/devices/iio:deviceX/events -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Configuration of which hardware generated events are passed up - to user-space. - -What: /sys/.../iio:deviceX/events/in_accel_x_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_accel_x_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_accel_y_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_accel_y_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_accel_z_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_accel_z_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_anglvel_x_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_anglvel_x_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_anglvel_y_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_anglvel_y_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_anglvel_z_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_anglvel_z_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_magn_x_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_magn_x_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_magn_y_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_magn_y_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_magn_z_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_magn_z_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_voltageY_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_voltageY_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_tempY_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_tempY_thresh_falling_en -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Event generated when channel passes a threshold in the specified - (_rising|_falling) direction. If the direction is not specified, - then either the device will report an event which ever direction - a single threshold value is passed in (e.g. - [Y][_name]__thresh_value) or - [Y][_name]__thresh_rising_value and - [Y][_name]__thresh_falling_value may take - different values, but the device can only enable both thresholds - or neither. - Note the driver will assume the last p events requested are - to be enabled where p is however many it supports (which may - vary depending on the exact set requested. So if you want to be - sure you have set what you think you have, check the contents of - these attributes after everything is configured. Drivers may - have to buffer any parameters so that they are consistent when - a given event type is enabled a future point (and not those for - whatever event was previously enabled). - -What: /sys/.../iio:deviceX/events/in_accel_x_roc_rising_en -What: /sys/.../iio:deviceX/events/in_accel_x_roc_falling_en -What: /sys/.../iio:deviceX/events/in_accel_y_roc_rising_en -What: /sys/.../iio:deviceX/events/in_accel_y_roc_falling_en -What: /sys/.../iio:deviceX/events/in_accel_z_roc_rising_en -What: /sys/.../iio:deviceX/events/in_accel_z_roc_falling_en -What: /sys/.../iio:deviceX/events/in_anglvel_x_roc_rising_en -What: /sys/.../iio:deviceX/events/in_anglvel_x_roc_falling_en -What: /sys/.../iio:deviceX/events/in_anglvel_y_roc_rising_en -What: /sys/.../iio:deviceX/events/in_anglvel_y_roc_falling_en -What: /sys/.../iio:deviceX/events/in_anglvel_z_roc_rising_en -What: /sys/.../iio:deviceX/events/in_anglvel_z_roc_falling_en -What: /sys/.../iio:deviceX/events/in_magn_x_roc_rising_en -What: /sys/.../iio:deviceX/events/in_magn_x_roc_falling_en -What: /sys/.../iio:deviceX/events/in_magn_y_roc_rising_en -What: /sys/.../iio:deviceX/events/in_magn_y_roc_falling_en -What: /sys/.../iio:deviceX/events/in_magn_z_roc_rising_en -What: /sys/.../iio:deviceX/events/in_magn_z_roc_falling_en -What: /sys/.../iio:deviceX/events/in_voltageY_supply_roc_rising_en -What: /sys/.../iio:deviceX/events/in_voltageY_supply_roc_falling_en -What: /sys/.../iio:deviceX/events/in_voltageY_roc_rising_en -What: /sys/.../iio:deviceX/events/in_voltageY_roc_falling_en -What: /sys/.../iio:deviceX/events/in_tempY_roc_rising_en -What: /sys/.../iio:deviceX/events/in_tempY_roc_falling_en -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Event generated when channel passes a threshold on the rate of - change (1st differential) in the specified (_rising|_falling) - direction. If the direction is not specified, then either the - device will report an event which ever direction a single - threshold value is passed in (e.g. - [Y][_name]__roc_value) or - [Y][_name]__roc_rising_value and - [Y][_name]__roc_falling_value may take - different values, but the device can only enable both rate of - change thresholds or neither. - Note the driver will assume the last p events requested are - to be enabled where p is however many it supports (which may - vary depending on the exact set requested. So if you want to be - sure you have set what you think you have, check the contents of - these attributes after everything is configured. Drivers may - have to buffer any parameters so that they are consistent when - a given event type is enabled a future point (and not those for - whatever event was previously enabled). - -What: /sys/.../events/in_accel_x_raw_thresh_rising_value -What: /sys/.../events/in_accel_x_raw_thresh_falling_value -What: /sys/.../events/in_accel_y_raw_thresh_rising_value -What: /sys/.../events/in_accel_y_raw_thresh_falling_value -What: /sys/.../events/in_accel_z_raw_thresh_rising_value -What: /sys/.../events/in_accel_z_raw_thresh_falling_value -What: /sys/.../events/in_anglvel_x_raw_thresh_rising_value -What: /sys/.../events/in_anglvel_x_raw_thresh_falling_value -What: /sys/.../events/in_anglvel_y_raw_thresh_rising_value -What: /sys/.../events/in_anglvel_y_raw_thresh_falling_value -What: /sys/.../events/in_anglvel_z_raw_thresh_rising_value -What: /sys/.../events/in_anglvel_z_raw_thresh_falling_value -What: /sys/.../events/in_magn_x_raw_thresh_rising_value -What: /sys/.../events/in_magn_x_raw_thresh_falling_value -What: /sys/.../events/in_magn_y_raw_thresh_rising_value -What: /sys/.../events/in_magn_y_raw_thresh_falling_value -What: /sys/.../events/in_magn_z_raw_thresh_rising_value -What: /sys/.../events/in_magn_z_raw_thresh_falling_value -What: /sys/.../events/in_voltageY_supply_raw_thresh_rising_value -What: /sys/.../events/in_voltageY_supply_raw_thresh_falling_value -What: /sys/.../events/in_voltageY_raw_thresh_rising_value -What: /sys/.../events/in_voltageY_raw_thresh_falling_value -What: /sys/.../events/in_tempY_raw_thresh_rising_value -What: /sys/.../events/in_tempY_raw_thresh_falling_value -What: /sys/.../events/in_illuminance0_thresh_falling_value -what: /sys/.../events/in_illuminance0_thresh_rising_value -what: /sys/.../events/in_proximity0_thresh_falling_value -what: /sys/.../events/in_proximity0_thresh_rising_value -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Specifies the value of threshold that the device is comparing - against for the events enabled by - Y[_name]_thresh[_rising|falling]_en. - If separate attributes exist for the two directions, but - direction is not specified for this attribute, then a single - threshold value applies to both directions. - The raw or input element of the name indicates whether the - value is in raw device units or in processed units (as _raw - and _input do on sysfs direct channel read attributes). - -What: /sys/.../events/in_accel_x_raw_roc_rising_value -What: /sys/.../events/in_accel_x_raw_roc_falling_value -What: /sys/.../events/in_accel_y_raw_roc_rising_value -What: /sys/.../events/in_accel_y_raw_roc_falling_value -What: /sys/.../events/in_accel_z_raw_roc_rising_value -What: /sys/.../events/in_accel_z_raw_roc_falling_value -What: /sys/.../events/in_anglvel_x_raw_roc_rising_value -What: /sys/.../events/in_anglvel_x_raw_roc_falling_value -What: /sys/.../events/in_anglvel_y_raw_roc_rising_value -What: /sys/.../events/in_anglvel_y_raw_roc_falling_value -What: /sys/.../events/in_anglvel_z_raw_roc_rising_value -What: /sys/.../events/in_anglvel_z_raw_roc_falling_value -What: /sys/.../events/in_magn_x_raw_roc_rising_value -What: /sys/.../events/in_magn_x_raw_roc_falling_value -What: /sys/.../events/in_magn_y_raw_roc_rising_value -What: /sys/.../events/in_magn_y_raw_roc_falling_value -What: /sys/.../events/in_magn_z_raw_roc_rising_value -What: /sys/.../events/in_magn_z_raw_roc_falling_value -What: /sys/.../events/in_voltageY_supply_raw_roc_rising_value -What: /sys/.../events/in_voltageY_supply_raw_roc_falling_value -What: /sys/.../events/in_voltageY_raw_roc_rising_value -What: /sys/.../events/in_voltageY_raw_roc_falling_value -What: /sys/.../events/in_tempY_raw_roc_rising_value -What: /sys/.../events/in_tempY_raw_roc_falling_value -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Specifies the value of rate of change threshold that the - device is comparing against for the events enabled by - [Y][_name]_roc[_rising|falling]_en. - If separate attributes exist for the two directions, - but direction is not specified for this attribute, - then a single threshold value applies to both directions. - The raw or input element of the name indicates whether the - value is in raw device units or in processed units (as _raw - and _input do on sysfs direct channel read attributes). - -What: /sys/.../events/in_accel_x_thresh_rising_period -What: /sys/.../events/in_accel_x_thresh_falling_period -hat: /sys/.../events/in_accel_x_roc_rising_period -What: /sys/.../events/in_accel_x_roc_falling_period -What: /sys/.../events/in_accel_y_thresh_rising_period -What: /sys/.../events/in_accel_y_thresh_falling_period -What: /sys/.../events/in_accel_y_roc_rising_period -What: /sys/.../events/in_accel_y_roc_falling_period -What: /sys/.../events/in_accel_z_thresh_rising_period -What: /sys/.../events/in_accel_z_thresh_falling_period -What: /sys/.../events/in_accel_z_roc_rising_period -What: /sys/.../events/in_accel_z_roc_falling_period -What: /sys/.../events/in_anglvel_x_thresh_rising_period -What: /sys/.../events/in_anglvel_x_thresh_falling_period -What: /sys/.../events/in_anglvel_x_roc_rising_period -What: /sys/.../events/in_anglvel_x_roc_falling_period -What: /sys/.../events/in_anglvel_y_thresh_rising_period -What: /sys/.../events/in_anglvel_y_thresh_falling_period -What: /sys/.../events/in_anglvel_y_roc_rising_period -What: /sys/.../events/in_anglvel_y_roc_falling_period -What: /sys/.../events/in_anglvel_z_thresh_rising_period -What: /sys/.../events/in_anglvel_z_thresh_falling_period -What: /sys/.../events/in_anglvel_z_roc_rising_period -What: /sys/.../events/in_anglvel_z_roc_falling_period -What: /sys/.../events/in_magn_x_thresh_rising_period -What: /sys/.../events/in_magn_x_thresh_falling_period -What: /sys/.../events/in_magn_x_roc_rising_period -What: /sys/.../events/in_magn_x_roc_falling_period -What: /sys/.../events/in_magn_y_thresh_rising_period -What: /sys/.../events/in_magn_y_thresh_falling_period -What: /sys/.../events/in_magn_y_roc_rising_period -What: /sys/.../events/in_magn_y_roc_falling_period -What: /sys/.../events/in_magn_z_thresh_rising_period -What: /sys/.../events/in_magn_z_thresh_falling_period -What: /sys/.../events/in_magn_z_roc_rising_period -What: /sys/.../events/in_magn_z_roc_falling_period -What: /sys/.../events/in_voltageY_supply_thresh_rising_period -What: /sys/.../events/in_voltageY_supply_thresh_falling_period -What: /sys/.../events/in_voltageY_supply_roc_rising_period -What: /sys/.../events/in_voltageY_supply_roc_falling_period -What: /sys/.../events/in_voltageY_thresh_rising_period -What: /sys/.../events/in_voltageY_thresh_falling_period -What: /sys/.../events/in_voltageY_roc_rising_period -What: /sys/.../events/in_voltageY_roc_falling_period -What: /sys/.../events/in_tempY_thresh_rising_period -What: /sys/.../events/in_tempY_thresh_falling_period -What: /sys/.../events/in_tempY_roc_rising_period -What: /sys/.../events/in_tempY_roc_falling_period -What: /sys/.../events/in_accel_x&y&z_mag_falling_period -What: /sys/.../events/in_intensity0_thresh_period -What: /sys/.../events/in_proximity0_thresh_period -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Period of time (in seconds) for which the condition must be - met before an event is generated. If direction is not - specified then this period applies to both directions. - -What: /sys/.../iio:deviceX/events/in_accel_mag_en -What: /sys/.../iio:deviceX/events/in_accel_mag_rising_en -What: /sys/.../iio:deviceX/events/in_accel_mag_falling_en -What: /sys/.../iio:deviceX/events/in_accel_x_mag_en -What: /sys/.../iio:deviceX/events/in_accel_x_mag_rising_en -What: /sys/.../iio:deviceX/events/in_accel_x_mag_falling_en -What: /sys/.../iio:deviceX/events/in_accel_y_mag_en -What: /sys/.../iio:deviceX/events/in_accel_y_mag_rising_en -What: /sys/.../iio:deviceX/events/in_accel_y_mag_falling_en -What: /sys/.../iio:deviceX/events/in_accel_z_mag_en -What: /sys/.../iio:deviceX/events/in_accel_z_mag_rising_en -What: /sys/.../iio:deviceX/events/in_accel_z_mag_falling_en -What: /sys/.../iio:deviceX/events/in_accel_x&y&z_mag_rising_en -What: /sys/.../iio:deviceX/events/in_accel_x&y&z_mag_falling_en -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Similar to in_accel_x_thresh[_rising|_falling]_en, but here the - magnitude of the channel is compared to the threshold, not its - signed value. - -What: /sys/.../events/in_accel_raw_mag_value -What: /sys/.../events/in_accel_x_raw_mag_rising_value -What: /sys/.../events/in_accel_y_raw_mag_rising_value -What: /sys/.../events/in_accel_z_raw_mag_rising_value -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - The value to which the magnitude of the channel is compared. If - number or direction is not specified, applies to all channels of - this type. - -What: /sys/bus/iio/devices/iio:deviceX/trigger/current_trigger -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - The name of the trigger source being used, as per string given - in /sys/class/iio/triggerY/name. - -What: /sys/bus/iio/devices/iio:deviceX/buffer/length -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Number of scans contained by the buffer. - -What: /sys/bus/iio/devices/iio:deviceX/buffer/bytes_per_datum -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Bytes per scan. Due to alignment fun, the scan may be larger - than implied directly by the scan_element parameters. - -What: /sys/bus/iio/devices/iio:deviceX/buffer/enable -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Actually start the buffer capture up. Will start trigger - if first device and appropriate. - -What: /sys/bus/iio/devices/iio:deviceX/buffer/scan_elements -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Directory containing interfaces for elements that will be - captured for a single triggered sample set in the buffer. - -What: /sys/.../buffer/scan_elements/in_accel_x_en -What: /sys/.../buffer/scan_elements/in_accel_y_en -What: /sys/.../buffer/scan_elements/in_accel_z_en -What: /sys/.../buffer/scan_elements/in_anglvel_x_en -What: /sys/.../buffer/scan_elements/in_anglvel_y_en -What: /sys/.../buffer/scan_elements/in_anglvel_z_en -What: /sys/.../buffer/scan_elements/in_magn_x_en -What: /sys/.../buffer/scan_elements/in_magn_y_en -What: /sys/.../buffer/scan_elements/in_magn_z_en -What: /sys/.../buffer/scan_elements/in_timestamp_en -What: /sys/.../buffer/scan_elements/in_voltageY_supply_en -What: /sys/.../buffer/scan_elements/in_voltageY_en -What: /sys/.../buffer/scan_elements/in_voltageY-voltageZ_en -What: /sys/.../buffer/scan_elements/in_incli_x_en -What: /sys/.../buffer/scan_elements/in_incli_y_en -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Scan element control for triggered data capture. - -What: /sys/.../buffer/scan_elements/in_accel_type -What: /sys/.../buffer/scan_elements/in_anglvel_type -What: /sys/.../buffer/scan_elements/in_magn_type -What: /sys/.../buffer/scan_elements/in_incli_type -What: /sys/.../buffer/scan_elements/in_voltageY_type -What: /sys/.../buffer/scan_elements/in_voltage-in_type -What: /sys/.../buffer/scan_elements/in_voltageY_supply_type -What: /sys/.../buffer/scan_elements/in_timestamp_type -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Description of the scan element data storage within the buffer - and hence the form in which it is read from user-space. - Form is [be|le]:[s|u]bits/storagebits[>>shift]. - be or le specifies big or little endian. s or u specifies if - signed (2's complement) or unsigned. bits is the number of bits - of data and storagebits is the space (after padding) that it - occupies in the buffer. shift if specified, is the shift that - needs to be applied prior to masking out unused bits. Some - devices put their data in the middle of the transferred elements - with additional information on both sides. Note that some - devices will have additional information in the unused bits - so to get a clean value, the bits value must be used to mask - the buffer output value appropriately. The storagebits value - also specifies the data alignment. So s48/64>>2 will be a - signed 48 bit integer stored in a 64 bit location aligned to - a a64 bit boundary. To obtain the clean value, shift right 2 - and apply a mask to zero the top 16 bits of the result. - For other storage combinations this attribute will be extended - appropriately. - -What: /sys/.../buffer/scan_elements/in_accel_type_available -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - If the type parameter can take one of a small set of values, - this attribute lists them. - -What: /sys/.../buffer/scan_elements/in_voltageY_index -What: /sys/.../buffer/scan_elements/in_voltageY_supply_index -What: /sys/.../buffer/scan_elements/in_accel_x_index -What: /sys/.../buffer/scan_elements/in_accel_y_index -What: /sys/.../buffer/scan_elements/in_accel_z_index -What: /sys/.../buffer/scan_elements/in_anglvel_x_index -What: /sys/.../buffer/scan_elements/in_anglvel_y_index -What: /sys/.../buffer/scan_elements/in_anglvel_z_index -What: /sys/.../buffer/scan_elements/in_magn_x_index -What: /sys/.../buffer/scan_elements/in_magn_y_index -What: /sys/.../buffer/scan_elements/in_magn_z_index -What: /sys/.../buffer/scan_elements/in_incli_x_index -What: /sys/.../buffer/scan_elements/in_incli_y_index -What: /sys/.../buffer/scan_elements/in_timestamp_index -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - A single positive integer specifying the position of this - scan element in the buffer. Note these are not dependent on - what is enabled and may not be contiguous. Thus for user-space - to establish the full layout these must be used in conjunction - with all _en attributes to establish which channels are present, - and the relevant _type attributes to establish the data storage - format. - -What: /sys/.../iio:deviceX/in_anglvel_z_quadrature_correction_raw -KernelVersion: 2.6.38 -Contact: linux-iio@vger.kernel.org -Description: - This attribute is used to read the amount of quadrature error - present in the device at a given time. -- cgit v0.10.2 From 25958ce32cd57dd91b42fa414b101d127e818c84 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 25 Apr 2012 11:25:46 -0700 Subject: staging: vme: vme.c: fix minor coding style issues Fix up some broken printk strings that were spanning multiple lines, making it hard to search for them. Cc: Manohar Vanga Cc: Martyn Welch Cc: "Emilio G. Cota" Cc: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c index 70722ae..fd51c2d 100644 --- a/drivers/staging/vme/vme.c +++ b/drivers/staging/vme/vme.c @@ -98,14 +98,13 @@ void *vme_alloc_consistent(struct vme_resource *resource, size_t size, } if (bridge->parent == NULL) { - printk(KERN_ERR "Dev entry NULL for" - " bridge %s\n", bridge->name); + printk(KERN_ERR "Dev entry NULL for bridge %s\n", bridge->name); return NULL; } if (bridge->alloc_consistent == NULL) { - printk(KERN_ERR "alloc_consistent not supported by" - " bridge %s\n", bridge->name); + printk(KERN_ERR "alloc_consistent not supported by bridge %s\n", + bridge->name); return NULL; } @@ -133,14 +132,13 @@ void vme_free_consistent(struct vme_resource *resource, size_t size, } if (bridge->parent == NULL) { - printk(KERN_ERR "Dev entry NULL for" - " bridge %s\n", bridge->name); + printk(KERN_ERR "Dev entry NULL for bridge %s\n", bridge->name); return; } if (bridge->free_consistent == NULL) { - printk(KERN_ERR "free_consistent not supported by" - " bridge %s\n", bridge->name); + printk(KERN_ERR "free_consistent not supported by bridge %s\n", + bridge->name); return; } @@ -747,15 +745,13 @@ struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, u32 type) attributes = kmalloc(sizeof(struct vme_dma_attr), GFP_KERNEL); if (attributes == NULL) { - printk(KERN_ERR "Unable to allocate memory for attributes " - "structure\n"); + printk(KERN_ERR "Unable to allocate memory for attributes structure\n"); goto err_attr; } pattern_attr = kmalloc(sizeof(struct vme_dma_pattern), GFP_KERNEL); if (pattern_attr == NULL) { - printk(KERN_ERR "Unable to allocate memory for pattern " - "attributes\n"); + printk(KERN_ERR "Unable to allocate memory for pattern attributes\n"); goto err_pat; } @@ -786,15 +782,13 @@ struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t address) attributes = kmalloc(sizeof(struct vme_dma_attr), GFP_KERNEL); if (attributes == NULL) { - printk(KERN_ERR "Unable to allocate memory for attributes " - "structure\n"); + printk(KERN_ERR "Unable to allocate memory for attributes structure\n"); goto err_attr; } pci_attr = kmalloc(sizeof(struct vme_dma_pci), GFP_KERNEL); if (pci_attr == NULL) { - printk(KERN_ERR "Unable to allocate memory for pci " - "attributes\n"); + printk(KERN_ERR "Unable to allocate memory for pci attributes\n"); goto err_pci; } @@ -826,15 +820,13 @@ struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long address, attributes = kmalloc( sizeof(struct vme_dma_attr), GFP_KERNEL); if (attributes == NULL) { - printk(KERN_ERR "Unable to allocate memory for attributes " - "structure\n"); + printk(KERN_ERR "Unable to allocate memory for attributes structure\n"); goto err_attr; } vme_attr = kmalloc(sizeof(struct vme_dma_vme), GFP_KERNEL); if (vme_attr == NULL) { - printk(KERN_ERR "Unable to allocate memory for vme " - "attributes\n"); + printk(KERN_ERR "Unable to allocate memory for vme attributes\n"); goto err_vme; } @@ -982,8 +974,8 @@ void vme_irq_handler(struct vme_bridge *bridge, int level, int statid) if (call != NULL) call(level, statid, priv_data); else - printk(KERN_WARNING "Spurilous VME interrupt, level:%x, " - "vector:%x\n", level, statid); + printk(KERN_WARNING "Spurilous VME interrupt, level:%x, vector:%x\n", + level, statid); } EXPORT_SYMBOL(vme_irq_handler); @@ -1112,8 +1104,7 @@ struct vme_resource *vme_lm_request(struct vme_dev *vdev) struct vme_lm_resource, list); if (lm == NULL) { - printk(KERN_ERR "Registered NULL Location Monitor " - "resource\n"); + printk(KERN_ERR "Registered NULL Location Monitor resource\n"); continue; } -- cgit v0.10.2 From 8176df8e95df4c867457076190cfb18f2d7ff18c Mon Sep 17 00:00:00 2001 From: Rupesh Gujare Date: Wed, 25 Apr 2012 23:54:58 +0100 Subject: staging: ozwpan: Fix bug where kfree is called twice. Signed-off-by: Rupesh Gujare Signed-off-by: Chris Kelly Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ozwpan/ozpd.c b/drivers/staging/ozwpan/ozpd.c index 2b45d3d..04cd57f 100644 --- a/drivers/staging/ozwpan/ozpd.c +++ b/drivers/staging/ozwpan/ozpd.c @@ -383,8 +383,6 @@ static void oz_tx_frame_free(struct oz_pd *pd, struct oz_tx_frame *f) pd->tx_pool = &f->link; pd->tx_pool_count++; f = 0; - } else { - kfree(f); } spin_unlock_bh(&pd->tx_frame_lock); if (f) -- cgit v0.10.2 From db3b9e990e75573402cda22faf933760f076c033 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 26 Apr 2012 12:34:58 -0700 Subject: Staging: VME: move VME drivers out of staging This moves the VME core, VME board drivers, and VME bridge drivers out of the drivers/staging/vme/ area to drivers/vme/. The VME device drivers have not moved out yet due to some API questions they are still working through, that should happen soon, hopefully. Cc: Martyn Welch Cc: Manohar Vanga Cc: Vincent Bossier Cc: "Emilio G. Cota" Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/Kconfig b/drivers/Kconfig index 0265cb1..e245779 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -142,4 +142,6 @@ source "drivers/devfreq/Kconfig" source "drivers/iio/Kconfig" +source "drivers/vme/Kconfig" + endmenu diff --git a/drivers/Makefile b/drivers/Makefile index cdbe362..08b78e0 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -135,3 +135,4 @@ obj-$(CONFIG_HYPERV) += hv/ obj-$(CONFIG_PM_DEVFREQ) += devfreq/ obj-$(CONFIG_IIO) += iio/ +obj-$(CONFIG_VME_BUS) += vme/ diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 8d406b5..60221ef 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -72,8 +72,6 @@ source "drivers/staging/vt6655/Kconfig" source "drivers/staging/vt6656/Kconfig" -source "drivers/staging/vme/Kconfig" - source "drivers/staging/sep/Kconfig" source "drivers/staging/iio/Kconfig" diff --git a/drivers/staging/vme/Kconfig b/drivers/staging/vme/Kconfig deleted file mode 100644 index 6411ae5..0000000 --- a/drivers/staging/vme/Kconfig +++ /dev/null @@ -1,19 +0,0 @@ -# -# VME configuration. -# - -menuconfig VME_BUS - tristate "VME bridge support" - depends on PCI - ---help--- - If you say Y here you get support for the VME bridge Framework. - -if VME_BUS - -source "drivers/staging/vme/bridges/Kconfig" - -source "drivers/staging/vme/devices/Kconfig" - -source "drivers/staging/vme/boards/Kconfig" - -endif # VME diff --git a/drivers/staging/vme/Makefile b/drivers/staging/vme/Makefile index b4ea3f8..accdb72 100644 --- a/drivers/staging/vme/Makefile +++ b/drivers/staging/vme/Makefile @@ -1,8 +1 @@ -# -# Makefile for the VME bridge device drivers. -# -obj-$(CONFIG_VME_BUS) += vme.o - -obj-y += bridges/ obj-y += devices/ -obj-y += boards/ diff --git a/drivers/staging/vme/TODO b/drivers/staging/vme/TODO deleted file mode 100644 index 79f0033..0000000 --- a/drivers/staging/vme/TODO +++ /dev/null @@ -1,5 +0,0 @@ - TODO - ==== - -- Add one or more device drivers which use the VME framework. - diff --git a/drivers/staging/vme/boards/Kconfig b/drivers/staging/vme/boards/Kconfig deleted file mode 100644 index 7616313..0000000 --- a/drivers/staging/vme/boards/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -comment "VME Board Drivers" - -config VMIVME_7805 - tristate "VMIVME-7805" - help - If you say Y here you get support for the VMIVME-7805 board. - This board has an additional control interface to the Universe II - chip. This driver has to be included if you want to access VME bus - with VMIVME-7805 board. diff --git a/drivers/staging/vme/boards/Makefile b/drivers/staging/vme/boards/Makefile deleted file mode 100644 index 4365834..0000000 --- a/drivers/staging/vme/boards/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the VME board drivers. -# - -obj-$(CONFIG_VMIVME_7805) += vme_vmivme7805.o diff --git a/drivers/staging/vme/boards/vme_vmivme7805.c b/drivers/staging/vme/boards/vme_vmivme7805.c deleted file mode 100644 index 8e05bb4..0000000 --- a/drivers/staging/vme/boards/vme_vmivme7805.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Support for the VMIVME-7805 board access to the Universe II bridge. - * - * Author: Arthur Benilov - * Copyright 2010 Ion Beam Application, 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. - */ - -#include -#include -#include -#include -#include -#include - -#include "vme_vmivme7805.h" - -static int __init vmic_init(void); -static int vmic_probe(struct pci_dev *, const struct pci_device_id *); -static void vmic_remove(struct pci_dev *); -static void __exit vmic_exit(void); - -/** Base address to access FPGA register */ -static void *vmic_base; - -static const char driver_name[] = "vmivme_7805"; - -static DEFINE_PCI_DEVICE_TABLE(vmic_ids) = { - { PCI_DEVICE(PCI_VENDOR_ID_VMIC, PCI_DEVICE_ID_VTIMR) }, - { }, -}; - -static struct pci_driver vmic_driver = { - .name = driver_name, - .id_table = vmic_ids, - .probe = vmic_probe, - .remove = vmic_remove, -}; - -static int __init vmic_init(void) -{ - return pci_register_driver(&vmic_driver); -} - -static int vmic_probe(struct pci_dev *pdev, const struct pci_device_id *id) -{ - int retval; - u32 data; - - /* Enable the device */ - retval = pci_enable_device(pdev); - if (retval) { - dev_err(&pdev->dev, "Unable to enable device\n"); - goto err; - } - - /* Map Registers */ - retval = pci_request_regions(pdev, driver_name); - if (retval) { - dev_err(&pdev->dev, "Unable to reserve resources\n"); - goto err_resource; - } - - /* Map registers in BAR 0 */ - vmic_base = ioremap_nocache(pci_resource_start(pdev, 0), 16); - if (!vmic_base) { - dev_err(&pdev->dev, "Unable to remap CRG region\n"); - retval = -EIO; - goto err_remap; - } - - /* Clear the FPGA VME IF contents */ - iowrite32(0, vmic_base + VME_CONTROL); - - /* Clear any initial BERR */ - data = ioread32(vmic_base + VME_CONTROL) & 0x00000FFF; - data |= BM_VME_CONTROL_BERRST; - iowrite32(data, vmic_base + VME_CONTROL); - - /* Enable the vme interface and byte swapping */ - data = ioread32(vmic_base + VME_CONTROL) & 0x00000FFF; - data = data | BM_VME_CONTROL_MASTER_ENDIAN | - BM_VME_CONTROL_SLAVE_ENDIAN | - BM_VME_CONTROL_ABLE | - BM_VME_CONTROL_BERRI | - BM_VME_CONTROL_BPENA | - BM_VME_CONTROL_VBENA; - iowrite32(data, vmic_base + VME_CONTROL); - - return 0; - -err_remap: - pci_release_regions(pdev); -err_resource: - pci_disable_device(pdev); -err: - return retval; -} - -static void vmic_remove(struct pci_dev *pdev) -{ - iounmap(vmic_base); - pci_release_regions(pdev); - pci_disable_device(pdev); - -} - -static void __exit vmic_exit(void) -{ - pci_unregister_driver(&vmic_driver); -} - -MODULE_DESCRIPTION("VMIVME-7805 board support driver"); -MODULE_AUTHOR("Arthur Benilov "); -MODULE_LICENSE("GPL"); - -module_init(vmic_init); -module_exit(vmic_exit); - diff --git a/drivers/staging/vme/boards/vme_vmivme7805.h b/drivers/staging/vme/boards/vme_vmivme7805.h deleted file mode 100644 index 44c2c44..0000000 --- a/drivers/staging/vme/boards/vme_vmivme7805.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * vmivme_7805.h - * - * Support for the VMIVME-7805 board access to the Universe II bridge. - * - * Author: Arthur Benilov - * Copyright 2010 Ion Beam Application, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - - -#ifndef _VMIVME_7805_H -#define _VMIVME_7805_H - -#ifndef PCI_VENDOR_ID_VMIC -#define PCI_VENDOR_ID_VMIC 0x114A -#endif - -#ifndef PCI_DEVICE_ID_VTIMR -#define PCI_DEVICE_ID_VTIMR 0x0004 -#endif - -#define VME_CONTROL 0x0000 -#define BM_VME_CONTROL_MASTER_ENDIAN 0x0001 -#define BM_VME_CONTROL_SLAVE_ENDIAN 0x0002 -#define BM_VME_CONTROL_ABLE 0x0004 -#define BM_VME_CONTROL_BERRI 0x0040 -#define BM_VME_CONTROL_BERRST 0x0080 -#define BM_VME_CONTROL_BPENA 0x0400 -#define BM_VME_CONTROL_VBENA 0x0800 - -#endif /* _VMIVME_7805_H */ - diff --git a/drivers/staging/vme/bridges/Kconfig b/drivers/staging/vme/bridges/Kconfig deleted file mode 100644 index 9331064..0000000 --- a/drivers/staging/vme/bridges/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -comment "VME Bridge Drivers" - -config VME_CA91CX42 - tristate "Universe II" - depends on VIRT_TO_BUS - help - If you say Y here you get support for the Tundra CA91C142 - (Universe II) VME bridge chip. - -config VME_TSI148 - tristate "Tempe" - depends on VIRT_TO_BUS - help - If you say Y here you get support for the Tundra TSI148 VME bridge - chip. diff --git a/drivers/staging/vme/bridges/Makefile b/drivers/staging/vme/bridges/Makefile deleted file mode 100644 index 59638af..0000000 --- a/drivers/staging/vme/bridges/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -obj-$(CONFIG_VME_CA91CX42) += vme_ca91cx42.o -obj-$(CONFIG_VME_TSI148) += vme_tsi148.o diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c deleted file mode 100644 index 515b8b8..0000000 --- a/drivers/staging/vme/bridges/vme_ca91cx42.c +++ /dev/null @@ -1,1959 +0,0 @@ -/* - * Support for the Tundra Universe I/II VME-PCI Bridge Chips - * - * Author: Martyn Welch - * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. - * - * Based on work by Tom Armistead and Ajit Prem - * Copyright 2004 Motorola Inc. - * - * Derived from ca91c042.c by Michael Wyrick - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../vme.h" -#include "../vme_bridge.h" -#include "vme_ca91cx42.h" - -static int __init ca91cx42_init(void); -static int ca91cx42_probe(struct pci_dev *, const struct pci_device_id *); -static void ca91cx42_remove(struct pci_dev *); -static void __exit ca91cx42_exit(void); - -/* Module parameters */ -static int geoid; - -static const char driver_name[] = "vme_ca91cx42"; - -static DEFINE_PCI_DEVICE_TABLE(ca91cx42_ids) = { - { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_CA91C142) }, - { }, -}; - -static struct pci_driver ca91cx42_driver = { - .name = driver_name, - .id_table = ca91cx42_ids, - .probe = ca91cx42_probe, - .remove = ca91cx42_remove, -}; - -static u32 ca91cx42_DMA_irqhandler(struct ca91cx42_driver *bridge) -{ - wake_up(&bridge->dma_queue); - - return CA91CX42_LINT_DMA; -} - -static u32 ca91cx42_LM_irqhandler(struct ca91cx42_driver *bridge, u32 stat) -{ - int i; - u32 serviced = 0; - - for (i = 0; i < 4; i++) { - if (stat & CA91CX42_LINT_LM[i]) { - /* We only enable interrupts if the callback is set */ - bridge->lm_callback[i](i); - serviced |= CA91CX42_LINT_LM[i]; - } - } - - return serviced; -} - -/* XXX This needs to be split into 4 queues */ -static u32 ca91cx42_MB_irqhandler(struct ca91cx42_driver *bridge, int mbox_mask) -{ - wake_up(&bridge->mbox_queue); - - return CA91CX42_LINT_MBOX; -} - -static u32 ca91cx42_IACK_irqhandler(struct ca91cx42_driver *bridge) -{ - wake_up(&bridge->iack_queue); - - return CA91CX42_LINT_SW_IACK; -} - -static u32 ca91cx42_VERR_irqhandler(struct vme_bridge *ca91cx42_bridge) -{ - int val; - struct ca91cx42_driver *bridge; - - bridge = ca91cx42_bridge->driver_priv; - - val = ioread32(bridge->base + DGCS); - - if (!(val & 0x00000800)) { - dev_err(ca91cx42_bridge->parent, "ca91cx42_VERR_irqhandler DMA " - "Read Error DGCS=%08X\n", val); - } - - return CA91CX42_LINT_VERR; -} - -static u32 ca91cx42_LERR_irqhandler(struct vme_bridge *ca91cx42_bridge) -{ - int val; - struct ca91cx42_driver *bridge; - - bridge = ca91cx42_bridge->driver_priv; - - val = ioread32(bridge->base + DGCS); - - if (!(val & 0x00000800)) - dev_err(ca91cx42_bridge->parent, "ca91cx42_LERR_irqhandler DMA " - "Read Error DGCS=%08X\n", val); - - return CA91CX42_LINT_LERR; -} - - -static u32 ca91cx42_VIRQ_irqhandler(struct vme_bridge *ca91cx42_bridge, - int stat) -{ - int vec, i, serviced = 0; - struct ca91cx42_driver *bridge; - - bridge = ca91cx42_bridge->driver_priv; - - - for (i = 7; i > 0; i--) { - if (stat & (1 << i)) { - vec = ioread32(bridge->base + - CA91CX42_V_STATID[i]) & 0xff; - - vme_irq_handler(ca91cx42_bridge, i, vec); - - serviced |= (1 << i); - } - } - - return serviced; -} - -static irqreturn_t ca91cx42_irqhandler(int irq, void *ptr) -{ - u32 stat, enable, serviced = 0; - struct vme_bridge *ca91cx42_bridge; - struct ca91cx42_driver *bridge; - - ca91cx42_bridge = ptr; - - bridge = ca91cx42_bridge->driver_priv; - - enable = ioread32(bridge->base + LINT_EN); - stat = ioread32(bridge->base + LINT_STAT); - - /* Only look at unmasked interrupts */ - stat &= enable; - - if (unlikely(!stat)) - return IRQ_NONE; - - if (stat & CA91CX42_LINT_DMA) - serviced |= ca91cx42_DMA_irqhandler(bridge); - if (stat & (CA91CX42_LINT_LM0 | CA91CX42_LINT_LM1 | CA91CX42_LINT_LM2 | - CA91CX42_LINT_LM3)) - serviced |= ca91cx42_LM_irqhandler(bridge, stat); - if (stat & CA91CX42_LINT_MBOX) - serviced |= ca91cx42_MB_irqhandler(bridge, stat); - if (stat & CA91CX42_LINT_SW_IACK) - serviced |= ca91cx42_IACK_irqhandler(bridge); - if (stat & CA91CX42_LINT_VERR) - serviced |= ca91cx42_VERR_irqhandler(ca91cx42_bridge); - if (stat & CA91CX42_LINT_LERR) - serviced |= ca91cx42_LERR_irqhandler(ca91cx42_bridge); - if (stat & (CA91CX42_LINT_VIRQ1 | CA91CX42_LINT_VIRQ2 | - CA91CX42_LINT_VIRQ3 | CA91CX42_LINT_VIRQ4 | - CA91CX42_LINT_VIRQ5 | CA91CX42_LINT_VIRQ6 | - CA91CX42_LINT_VIRQ7)) - serviced |= ca91cx42_VIRQ_irqhandler(ca91cx42_bridge, stat); - - /* Clear serviced interrupts */ - iowrite32(serviced, bridge->base + LINT_STAT); - - return IRQ_HANDLED; -} - -static int ca91cx42_irq_init(struct vme_bridge *ca91cx42_bridge) -{ - int result, tmp; - struct pci_dev *pdev; - struct ca91cx42_driver *bridge; - - bridge = ca91cx42_bridge->driver_priv; - - /* Need pdev */ - pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, dev); - - /* Initialise list for VME bus errors */ - INIT_LIST_HEAD(&ca91cx42_bridge->vme_errors); - - mutex_init(&ca91cx42_bridge->irq_mtx); - - /* Disable interrupts from PCI to VME */ - iowrite32(0, bridge->base + VINT_EN); - - /* Disable PCI interrupts */ - iowrite32(0, bridge->base + LINT_EN); - /* Clear Any Pending PCI Interrupts */ - iowrite32(0x00FFFFFF, bridge->base + LINT_STAT); - - result = request_irq(pdev->irq, ca91cx42_irqhandler, IRQF_SHARED, - driver_name, ca91cx42_bridge); - if (result) { - dev_err(&pdev->dev, "Can't get assigned pci irq vector %02X\n", - pdev->irq); - return result; - } - - /* Ensure all interrupts are mapped to PCI Interrupt 0 */ - iowrite32(0, bridge->base + LINT_MAP0); - iowrite32(0, bridge->base + LINT_MAP1); - iowrite32(0, bridge->base + LINT_MAP2); - - /* Enable DMA, mailbox & LM Interrupts */ - tmp = CA91CX42_LINT_MBOX3 | CA91CX42_LINT_MBOX2 | CA91CX42_LINT_MBOX1 | - CA91CX42_LINT_MBOX0 | CA91CX42_LINT_SW_IACK | - CA91CX42_LINT_VERR | CA91CX42_LINT_LERR | CA91CX42_LINT_DMA; - - iowrite32(tmp, bridge->base + LINT_EN); - - return 0; -} - -static void ca91cx42_irq_exit(struct ca91cx42_driver *bridge, - struct pci_dev *pdev) -{ - /* Disable interrupts from PCI to VME */ - iowrite32(0, bridge->base + VINT_EN); - - /* Disable PCI interrupts */ - iowrite32(0, bridge->base + LINT_EN); - /* Clear Any Pending PCI Interrupts */ - iowrite32(0x00FFFFFF, bridge->base + LINT_STAT); - - free_irq(pdev->irq, pdev); -} - -static int ca91cx42_iack_received(struct ca91cx42_driver *bridge, int level) -{ - u32 tmp; - - tmp = ioread32(bridge->base + LINT_STAT); - - if (tmp & (1 << level)) - return 0; - else - return 1; -} - -/* - * Set up an VME interrupt - */ -static void ca91cx42_irq_set(struct vme_bridge *ca91cx42_bridge, int level, - int state, int sync) - -{ - struct pci_dev *pdev; - u32 tmp; - struct ca91cx42_driver *bridge; - - bridge = ca91cx42_bridge->driver_priv; - - /* Enable IRQ level */ - tmp = ioread32(bridge->base + LINT_EN); - - if (state == 0) - tmp &= ~CA91CX42_LINT_VIRQ[level]; - else - tmp |= CA91CX42_LINT_VIRQ[level]; - - iowrite32(tmp, bridge->base + LINT_EN); - - if ((state == 0) && (sync != 0)) { - pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, - dev); - - synchronize_irq(pdev->irq); - } -} - -static int ca91cx42_irq_generate(struct vme_bridge *ca91cx42_bridge, int level, - int statid) -{ - u32 tmp; - struct ca91cx42_driver *bridge; - - bridge = ca91cx42_bridge->driver_priv; - - /* Universe can only generate even vectors */ - if (statid & 1) - return -EINVAL; - - mutex_lock(&bridge->vme_int); - - tmp = ioread32(bridge->base + VINT_EN); - - /* Set Status/ID */ - iowrite32(statid << 24, bridge->base + STATID); - - /* Assert VMEbus IRQ */ - tmp = tmp | (1 << (level + 24)); - iowrite32(tmp, bridge->base + VINT_EN); - - /* Wait for IACK */ - wait_event_interruptible(bridge->iack_queue, - ca91cx42_iack_received(bridge, level)); - - /* Return interrupt to low state */ - tmp = ioread32(bridge->base + VINT_EN); - tmp = tmp & ~(1 << (level + 24)); - iowrite32(tmp, bridge->base + VINT_EN); - - mutex_unlock(&bridge->vme_int); - - return 0; -} - -static int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled, - unsigned long long vme_base, unsigned long long size, - dma_addr_t pci_base, u32 aspace, u32 cycle) -{ - unsigned int i, addr = 0, granularity; - unsigned int temp_ctl = 0; - unsigned int vme_bound, pci_offset; - struct vme_bridge *ca91cx42_bridge; - struct ca91cx42_driver *bridge; - - ca91cx42_bridge = image->parent; - - bridge = ca91cx42_bridge->driver_priv; - - i = image->number; - - switch (aspace) { - case VME_A16: - addr |= CA91CX42_VSI_CTL_VAS_A16; - break; - case VME_A24: - addr |= CA91CX42_VSI_CTL_VAS_A24; - break; - case VME_A32: - addr |= CA91CX42_VSI_CTL_VAS_A32; - break; - case VME_USER1: - addr |= CA91CX42_VSI_CTL_VAS_USER1; - break; - case VME_USER2: - addr |= CA91CX42_VSI_CTL_VAS_USER2; - break; - case VME_A64: - case VME_CRCSR: - case VME_USER3: - case VME_USER4: - default: - dev_err(ca91cx42_bridge->parent, "Invalid address space\n"); - return -EINVAL; - break; - } - - /* - * Bound address is a valid address for the window, adjust - * accordingly - */ - vme_bound = vme_base + size; - pci_offset = pci_base - vme_base; - - if ((i == 0) || (i == 4)) - granularity = 0x1000; - else - granularity = 0x10000; - - if (vme_base & (granularity - 1)) { - dev_err(ca91cx42_bridge->parent, "Invalid VME base " - "alignment\n"); - return -EINVAL; - } - if (vme_bound & (granularity - 1)) { - dev_err(ca91cx42_bridge->parent, "Invalid VME bound " - "alignment\n"); - return -EINVAL; - } - if (pci_offset & (granularity - 1)) { - dev_err(ca91cx42_bridge->parent, "Invalid PCI Offset " - "alignment\n"); - return -EINVAL; - } - - /* Disable while we are mucking around */ - temp_ctl = ioread32(bridge->base + CA91CX42_VSI_CTL[i]); - temp_ctl &= ~CA91CX42_VSI_CTL_EN; - iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]); - - /* Setup mapping */ - iowrite32(vme_base, bridge->base + CA91CX42_VSI_BS[i]); - iowrite32(vme_bound, bridge->base + CA91CX42_VSI_BD[i]); - iowrite32(pci_offset, bridge->base + CA91CX42_VSI_TO[i]); - - /* Setup address space */ - temp_ctl &= ~CA91CX42_VSI_CTL_VAS_M; - temp_ctl |= addr; - - /* Setup cycle types */ - temp_ctl &= ~(CA91CX42_VSI_CTL_PGM_M | CA91CX42_VSI_CTL_SUPER_M); - if (cycle & VME_SUPER) - temp_ctl |= CA91CX42_VSI_CTL_SUPER_SUPR; - if (cycle & VME_USER) - temp_ctl |= CA91CX42_VSI_CTL_SUPER_NPRIV; - if (cycle & VME_PROG) - temp_ctl |= CA91CX42_VSI_CTL_PGM_PGM; - if (cycle & VME_DATA) - temp_ctl |= CA91CX42_VSI_CTL_PGM_DATA; - - /* Write ctl reg without enable */ - iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]); - - if (enabled) - temp_ctl |= CA91CX42_VSI_CTL_EN; - - iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]); - - return 0; -} - -static int ca91cx42_slave_get(struct vme_slave_resource *image, int *enabled, - unsigned long long *vme_base, unsigned long long *size, - dma_addr_t *pci_base, u32 *aspace, u32 *cycle) -{ - unsigned int i, granularity = 0, ctl = 0; - unsigned long long vme_bound, pci_offset; - struct ca91cx42_driver *bridge; - - bridge = image->parent->driver_priv; - - i = image->number; - - if ((i == 0) || (i == 4)) - granularity = 0x1000; - else - granularity = 0x10000; - - /* Read Registers */ - ctl = ioread32(bridge->base + CA91CX42_VSI_CTL[i]); - - *vme_base = ioread32(bridge->base + CA91CX42_VSI_BS[i]); - vme_bound = ioread32(bridge->base + CA91CX42_VSI_BD[i]); - pci_offset = ioread32(bridge->base + CA91CX42_VSI_TO[i]); - - *pci_base = (dma_addr_t)vme_base + pci_offset; - *size = (unsigned long long)((vme_bound - *vme_base) + granularity); - - *enabled = 0; - *aspace = 0; - *cycle = 0; - - if (ctl & CA91CX42_VSI_CTL_EN) - *enabled = 1; - - if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_A16) - *aspace = VME_A16; - if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_A24) - *aspace = VME_A24; - if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_A32) - *aspace = VME_A32; - if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_USER1) - *aspace = VME_USER1; - if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_USER2) - *aspace = VME_USER2; - - if (ctl & CA91CX42_VSI_CTL_SUPER_SUPR) - *cycle |= VME_SUPER; - if (ctl & CA91CX42_VSI_CTL_SUPER_NPRIV) - *cycle |= VME_USER; - if (ctl & CA91CX42_VSI_CTL_PGM_PGM) - *cycle |= VME_PROG; - if (ctl & CA91CX42_VSI_CTL_PGM_DATA) - *cycle |= VME_DATA; - - return 0; -} - -/* - * Allocate and map PCI Resource - */ -static int ca91cx42_alloc_resource(struct vme_master_resource *image, - unsigned long long size) -{ - unsigned long long existing_size; - int retval = 0; - struct pci_dev *pdev; - struct vme_bridge *ca91cx42_bridge; - - ca91cx42_bridge = image->parent; - - /* Find pci_dev container of dev */ - if (ca91cx42_bridge->parent == NULL) { - dev_err(ca91cx42_bridge->parent, "Dev entry NULL\n"); - return -EINVAL; - } - pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, dev); - - existing_size = (unsigned long long)(image->bus_resource.end - - image->bus_resource.start); - - /* If the existing size is OK, return */ - if (existing_size == (size - 1)) - return 0; - - if (existing_size != 0) { - iounmap(image->kern_base); - image->kern_base = NULL; - kfree(image->bus_resource.name); - release_resource(&image->bus_resource); - memset(&image->bus_resource, 0, sizeof(struct resource)); - } - - if (image->bus_resource.name == NULL) { - image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_ATOMIC); - if (image->bus_resource.name == NULL) { - dev_err(ca91cx42_bridge->parent, "Unable to allocate " - "memory for resource name\n"); - retval = -ENOMEM; - goto err_name; - } - } - - sprintf((char *)image->bus_resource.name, "%s.%d", - ca91cx42_bridge->name, image->number); - - image->bus_resource.start = 0; - image->bus_resource.end = (unsigned long)size; - image->bus_resource.flags = IORESOURCE_MEM; - - retval = pci_bus_alloc_resource(pdev->bus, - &image->bus_resource, size, size, PCIBIOS_MIN_MEM, - 0, NULL, NULL); - if (retval) { - dev_err(ca91cx42_bridge->parent, "Failed to allocate mem " - "resource for window %d size 0x%lx start 0x%lx\n", - image->number, (unsigned long)size, - (unsigned long)image->bus_resource.start); - goto err_resource; - } - - image->kern_base = ioremap_nocache( - image->bus_resource.start, size); - if (image->kern_base == NULL) { - dev_err(ca91cx42_bridge->parent, "Failed to remap resource\n"); - retval = -ENOMEM; - goto err_remap; - } - - return 0; - -err_remap: - release_resource(&image->bus_resource); -err_resource: - kfree(image->bus_resource.name); - memset(&image->bus_resource, 0, sizeof(struct resource)); -err_name: - return retval; -} - -/* - * Free and unmap PCI Resource - */ -static void ca91cx42_free_resource(struct vme_master_resource *image) -{ - iounmap(image->kern_base); - image->kern_base = NULL; - release_resource(&image->bus_resource); - kfree(image->bus_resource.name); - memset(&image->bus_resource, 0, sizeof(struct resource)); -} - - -static int ca91cx42_master_set(struct vme_master_resource *image, int enabled, - unsigned long long vme_base, unsigned long long size, u32 aspace, - u32 cycle, u32 dwidth) -{ - int retval = 0; - unsigned int i, granularity = 0; - unsigned int temp_ctl = 0; - unsigned long long pci_bound, vme_offset, pci_base; - struct vme_bridge *ca91cx42_bridge; - struct ca91cx42_driver *bridge; - - ca91cx42_bridge = image->parent; - - bridge = ca91cx42_bridge->driver_priv; - - i = image->number; - - if ((i == 0) || (i == 4)) - granularity = 0x1000; - else - granularity = 0x10000; - - /* Verify input data */ - if (vme_base & (granularity - 1)) { - dev_err(ca91cx42_bridge->parent, "Invalid VME Window " - "alignment\n"); - retval = -EINVAL; - goto err_window; - } - if (size & (granularity - 1)) { - dev_err(ca91cx42_bridge->parent, "Invalid VME Window " - "alignment\n"); - retval = -EINVAL; - goto err_window; - } - - spin_lock(&image->lock); - - /* - * Let's allocate the resource here rather than further up the stack as - * it avoids pushing loads of bus dependent stuff up the stack - */ - retval = ca91cx42_alloc_resource(image, size); - if (retval) { - spin_unlock(&image->lock); - dev_err(ca91cx42_bridge->parent, "Unable to allocate memory " - "for resource name\n"); - retval = -ENOMEM; - goto err_res; - } - - pci_base = (unsigned long long)image->bus_resource.start; - - /* - * Bound address is a valid address for the window, adjust - * according to window granularity. - */ - pci_bound = pci_base + size; - vme_offset = vme_base - pci_base; - - /* Disable while we are mucking around */ - temp_ctl = ioread32(bridge->base + CA91CX42_LSI_CTL[i]); - temp_ctl &= ~CA91CX42_LSI_CTL_EN; - iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]); - - /* Setup cycle types */ - temp_ctl &= ~CA91CX42_LSI_CTL_VCT_M; - if (cycle & VME_BLT) - temp_ctl |= CA91CX42_LSI_CTL_VCT_BLT; - if (cycle & VME_MBLT) - temp_ctl |= CA91CX42_LSI_CTL_VCT_MBLT; - - /* Setup data width */ - temp_ctl &= ~CA91CX42_LSI_CTL_VDW_M; - switch (dwidth) { - case VME_D8: - temp_ctl |= CA91CX42_LSI_CTL_VDW_D8; - break; - case VME_D16: - temp_ctl |= CA91CX42_LSI_CTL_VDW_D16; - break; - case VME_D32: - temp_ctl |= CA91CX42_LSI_CTL_VDW_D32; - break; - case VME_D64: - temp_ctl |= CA91CX42_LSI_CTL_VDW_D64; - break; - default: - spin_unlock(&image->lock); - dev_err(ca91cx42_bridge->parent, "Invalid data width\n"); - retval = -EINVAL; - goto err_dwidth; - break; - } - - /* Setup address space */ - temp_ctl &= ~CA91CX42_LSI_CTL_VAS_M; - switch (aspace) { - case VME_A16: - temp_ctl |= CA91CX42_LSI_CTL_VAS_A16; - break; - case VME_A24: - temp_ctl |= CA91CX42_LSI_CTL_VAS_A24; - break; - case VME_A32: - temp_ctl |= CA91CX42_LSI_CTL_VAS_A32; - break; - case VME_CRCSR: - temp_ctl |= CA91CX42_LSI_CTL_VAS_CRCSR; - break; - case VME_USER1: - temp_ctl |= CA91CX42_LSI_CTL_VAS_USER1; - break; - case VME_USER2: - temp_ctl |= CA91CX42_LSI_CTL_VAS_USER2; - break; - case VME_A64: - case VME_USER3: - case VME_USER4: - default: - spin_unlock(&image->lock); - dev_err(ca91cx42_bridge->parent, "Invalid address space\n"); - retval = -EINVAL; - goto err_aspace; - break; - } - - temp_ctl &= ~(CA91CX42_LSI_CTL_PGM_M | CA91CX42_LSI_CTL_SUPER_M); - if (cycle & VME_SUPER) - temp_ctl |= CA91CX42_LSI_CTL_SUPER_SUPR; - if (cycle & VME_PROG) - temp_ctl |= CA91CX42_LSI_CTL_PGM_PGM; - - /* Setup mapping */ - iowrite32(pci_base, bridge->base + CA91CX42_LSI_BS[i]); - iowrite32(pci_bound, bridge->base + CA91CX42_LSI_BD[i]); - iowrite32(vme_offset, bridge->base + CA91CX42_LSI_TO[i]); - - /* Write ctl reg without enable */ - iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]); - - if (enabled) - temp_ctl |= CA91CX42_LSI_CTL_EN; - - iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]); - - spin_unlock(&image->lock); - return 0; - -err_aspace: -err_dwidth: - ca91cx42_free_resource(image); -err_res: -err_window: - return retval; -} - -static int __ca91cx42_master_get(struct vme_master_resource *image, - int *enabled, unsigned long long *vme_base, unsigned long long *size, - u32 *aspace, u32 *cycle, u32 *dwidth) -{ - unsigned int i, ctl; - unsigned long long pci_base, pci_bound, vme_offset; - struct ca91cx42_driver *bridge; - - bridge = image->parent->driver_priv; - - i = image->number; - - ctl = ioread32(bridge->base + CA91CX42_LSI_CTL[i]); - - pci_base = ioread32(bridge->base + CA91CX42_LSI_BS[i]); - vme_offset = ioread32(bridge->base + CA91CX42_LSI_TO[i]); - pci_bound = ioread32(bridge->base + CA91CX42_LSI_BD[i]); - - *vme_base = pci_base + vme_offset; - *size = (unsigned long long)(pci_bound - pci_base); - - *enabled = 0; - *aspace = 0; - *cycle = 0; - *dwidth = 0; - - if (ctl & CA91CX42_LSI_CTL_EN) - *enabled = 1; - - /* Setup address space */ - switch (ctl & CA91CX42_LSI_CTL_VAS_M) { - case CA91CX42_LSI_CTL_VAS_A16: - *aspace = VME_A16; - break; - case CA91CX42_LSI_CTL_VAS_A24: - *aspace = VME_A24; - break; - case CA91CX42_LSI_CTL_VAS_A32: - *aspace = VME_A32; - break; - case CA91CX42_LSI_CTL_VAS_CRCSR: - *aspace = VME_CRCSR; - break; - case CA91CX42_LSI_CTL_VAS_USER1: - *aspace = VME_USER1; - break; - case CA91CX42_LSI_CTL_VAS_USER2: - *aspace = VME_USER2; - break; - } - - /* XXX Not sure howto check for MBLT */ - /* Setup cycle types */ - if (ctl & CA91CX42_LSI_CTL_VCT_BLT) - *cycle |= VME_BLT; - else - *cycle |= VME_SCT; - - if (ctl & CA91CX42_LSI_CTL_SUPER_SUPR) - *cycle |= VME_SUPER; - else - *cycle |= VME_USER; - - if (ctl & CA91CX42_LSI_CTL_PGM_PGM) - *cycle = VME_PROG; - else - *cycle = VME_DATA; - - /* Setup data width */ - switch (ctl & CA91CX42_LSI_CTL_VDW_M) { - case CA91CX42_LSI_CTL_VDW_D8: - *dwidth = VME_D8; - break; - case CA91CX42_LSI_CTL_VDW_D16: - *dwidth = VME_D16; - break; - case CA91CX42_LSI_CTL_VDW_D32: - *dwidth = VME_D32; - break; - case CA91CX42_LSI_CTL_VDW_D64: - *dwidth = VME_D64; - break; - } - - return 0; -} - -static int ca91cx42_master_get(struct vme_master_resource *image, int *enabled, - unsigned long long *vme_base, unsigned long long *size, u32 *aspace, - u32 *cycle, u32 *dwidth) -{ - int retval; - - spin_lock(&image->lock); - - retval = __ca91cx42_master_get(image, enabled, vme_base, size, aspace, - cycle, dwidth); - - spin_unlock(&image->lock); - - return retval; -} - -static ssize_t ca91cx42_master_read(struct vme_master_resource *image, - void *buf, size_t count, loff_t offset) -{ - ssize_t retval; - void *addr = image->kern_base + offset; - unsigned int done = 0; - unsigned int count32; - - if (count == 0) - return 0; - - spin_lock(&image->lock); - - /* The following code handles VME address alignment problem - * in order to assure the maximal data width cycle. - * We cannot use memcpy_xxx directly here because it - * may cut data transfer in 8-bits cycles, thus making - * D16 cycle impossible. - * From the other hand, the bridge itself assures that - * maximal configured data cycle is used and splits it - * automatically for non-aligned addresses. - */ - if ((uintptr_t)addr & 0x1) { - *(u8 *)buf = ioread8(addr); - done += 1; - if (done == count) - goto out; - } - if ((uintptr_t)addr & 0x2) { - if ((count - done) < 2) { - *(u8 *)(buf + done) = ioread8(addr + done); - done += 1; - goto out; - } else { - *(u16 *)(buf + done) = ioread16(addr + done); - done += 2; - } - } - - count32 = (count - done) & ~0x3; - if (count32 > 0) { - memcpy_fromio(buf + done, addr + done, (unsigned int)count); - done += count32; - } - - if ((count - done) & 0x2) { - *(u16 *)(buf + done) = ioread16(addr + done); - done += 2; - } - if ((count - done) & 0x1) { - *(u8 *)(buf + done) = ioread8(addr + done); - done += 1; - } -out: - retval = count; - spin_unlock(&image->lock); - - return retval; -} - -static ssize_t ca91cx42_master_write(struct vme_master_resource *image, - void *buf, size_t count, loff_t offset) -{ - ssize_t retval; - void *addr = image->kern_base + offset; - unsigned int done = 0; - unsigned int count32; - - if (count == 0) - return 0; - - spin_lock(&image->lock); - - /* Here we apply for the same strategy we do in master_read - * function in order to assure D16 cycle when required. - */ - if ((uintptr_t)addr & 0x1) { - iowrite8(*(u8 *)buf, addr); - done += 1; - if (done == count) - goto out; - } - if ((uintptr_t)addr & 0x2) { - if ((count - done) < 2) { - iowrite8(*(u8 *)(buf + done), addr + done); - done += 1; - goto out; - } else { - iowrite16(*(u16 *)(buf + done), addr + done); - done += 2; - } - } - - count32 = (count - done) & ~0x3; - if (count32 > 0) { - memcpy_toio(addr + done, buf + done, count32); - done += count32; - } - - if ((count - done) & 0x2) { - iowrite16(*(u16 *)(buf + done), addr + done); - done += 2; - } - if ((count - done) & 0x1) { - iowrite8(*(u8 *)(buf + done), addr + done); - done += 1; - } -out: - retval = count; - - spin_unlock(&image->lock); - - return retval; -} - -static unsigned int ca91cx42_master_rmw(struct vme_master_resource *image, - unsigned int mask, unsigned int compare, unsigned int swap, - loff_t offset) -{ - u32 result; - uintptr_t pci_addr; - int i; - struct ca91cx42_driver *bridge; - struct device *dev; - - bridge = image->parent->driver_priv; - dev = image->parent->parent; - - /* Find the PCI address that maps to the desired VME address */ - i = image->number; - - /* Locking as we can only do one of these at a time */ - mutex_lock(&bridge->vme_rmw); - - /* Lock image */ - spin_lock(&image->lock); - - pci_addr = (uintptr_t)image->kern_base + offset; - - /* Address must be 4-byte aligned */ - if (pci_addr & 0x3) { - dev_err(dev, "RMW Address not 4-byte aligned\n"); - result = -EINVAL; - goto out; - } - - /* Ensure RMW Disabled whilst configuring */ - iowrite32(0, bridge->base + SCYC_CTL); - - /* Configure registers */ - iowrite32(mask, bridge->base + SCYC_EN); - iowrite32(compare, bridge->base + SCYC_CMP); - iowrite32(swap, bridge->base + SCYC_SWP); - iowrite32(pci_addr, bridge->base + SCYC_ADDR); - - /* Enable RMW */ - iowrite32(CA91CX42_SCYC_CTL_CYC_RMW, bridge->base + SCYC_CTL); - - /* Kick process off with a read to the required address. */ - result = ioread32(image->kern_base + offset); - - /* Disable RMW */ - iowrite32(0, bridge->base + SCYC_CTL); - -out: - spin_unlock(&image->lock); - - mutex_unlock(&bridge->vme_rmw); - - return result; -} - -static int ca91cx42_dma_list_add(struct vme_dma_list *list, - struct vme_dma_attr *src, struct vme_dma_attr *dest, size_t count) -{ - struct ca91cx42_dma_entry *entry, *prev; - struct vme_dma_pci *pci_attr; - struct vme_dma_vme *vme_attr; - dma_addr_t desc_ptr; - int retval = 0; - struct device *dev; - - dev = list->parent->parent->parent; - - /* XXX descriptor must be aligned on 64-bit boundaries */ - entry = kmalloc(sizeof(struct ca91cx42_dma_entry), GFP_KERNEL); - if (entry == NULL) { - dev_err(dev, "Failed to allocate memory for dma resource " - "structure\n"); - retval = -ENOMEM; - goto err_mem; - } - - /* Test descriptor alignment */ - if ((unsigned long)&entry->descriptor & CA91CX42_DCPP_M) { - dev_err(dev, "Descriptor not aligned to 16 byte boundary as " - "required: %p\n", &entry->descriptor); - retval = -EINVAL; - goto err_align; - } - - memset(&entry->descriptor, 0, sizeof(struct ca91cx42_dma_descriptor)); - - if (dest->type == VME_DMA_VME) { - entry->descriptor.dctl |= CA91CX42_DCTL_L2V; - vme_attr = dest->private; - pci_attr = src->private; - } else { - vme_attr = src->private; - pci_attr = dest->private; - } - - /* Check we can do fulfill required attributes */ - if ((vme_attr->aspace & ~(VME_A16 | VME_A24 | VME_A32 | VME_USER1 | - VME_USER2)) != 0) { - - dev_err(dev, "Unsupported cycle type\n"); - retval = -EINVAL; - goto err_aspace; - } - - if ((vme_attr->cycle & ~(VME_SCT | VME_BLT | VME_SUPER | VME_USER | - VME_PROG | VME_DATA)) != 0) { - - dev_err(dev, "Unsupported cycle type\n"); - retval = -EINVAL; - goto err_cycle; - } - - /* Check to see if we can fulfill source and destination */ - if (!(((src->type == VME_DMA_PCI) && (dest->type == VME_DMA_VME)) || - ((src->type == VME_DMA_VME) && (dest->type == VME_DMA_PCI)))) { - - dev_err(dev, "Cannot perform transfer with this " - "source-destination combination\n"); - retval = -EINVAL; - goto err_direct; - } - - /* Setup cycle types */ - if (vme_attr->cycle & VME_BLT) - entry->descriptor.dctl |= CA91CX42_DCTL_VCT_BLT; - - /* Setup data width */ - switch (vme_attr->dwidth) { - case VME_D8: - entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D8; - break; - case VME_D16: - entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D16; - break; - case VME_D32: - entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D32; - break; - case VME_D64: - entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D64; - break; - default: - dev_err(dev, "Invalid data width\n"); - return -EINVAL; - } - - /* Setup address space */ - switch (vme_attr->aspace) { - case VME_A16: - entry->descriptor.dctl |= CA91CX42_DCTL_VAS_A16; - break; - case VME_A24: - entry->descriptor.dctl |= CA91CX42_DCTL_VAS_A24; - break; - case VME_A32: - entry->descriptor.dctl |= CA91CX42_DCTL_VAS_A32; - break; - case VME_USER1: - entry->descriptor.dctl |= CA91CX42_DCTL_VAS_USER1; - break; - case VME_USER2: - entry->descriptor.dctl |= CA91CX42_DCTL_VAS_USER2; - break; - default: - dev_err(dev, "Invalid address space\n"); - return -EINVAL; - break; - } - - if (vme_attr->cycle & VME_SUPER) - entry->descriptor.dctl |= CA91CX42_DCTL_SUPER_SUPR; - if (vme_attr->cycle & VME_PROG) - entry->descriptor.dctl |= CA91CX42_DCTL_PGM_PGM; - - entry->descriptor.dtbc = count; - entry->descriptor.dla = pci_attr->address; - entry->descriptor.dva = vme_attr->address; - entry->descriptor.dcpp = CA91CX42_DCPP_NULL; - - /* Add to list */ - list_add_tail(&entry->list, &list->entries); - - /* Fill out previous descriptors "Next Address" */ - if (entry->list.prev != &list->entries) { - prev = list_entry(entry->list.prev, struct ca91cx42_dma_entry, - list); - /* We need the bus address for the pointer */ - desc_ptr = virt_to_bus(&entry->descriptor); - prev->descriptor.dcpp = desc_ptr & ~CA91CX42_DCPP_M; - } - - return 0; - -err_cycle: -err_aspace: -err_direct: -err_align: - kfree(entry); -err_mem: - return retval; -} - -static int ca91cx42_dma_busy(struct vme_bridge *ca91cx42_bridge) -{ - u32 tmp; - struct ca91cx42_driver *bridge; - - bridge = ca91cx42_bridge->driver_priv; - - tmp = ioread32(bridge->base + DGCS); - - if (tmp & CA91CX42_DGCS_ACT) - return 0; - else - return 1; -} - -static int ca91cx42_dma_list_exec(struct vme_dma_list *list) -{ - struct vme_dma_resource *ctrlr; - struct ca91cx42_dma_entry *entry; - int retval = 0; - dma_addr_t bus_addr; - u32 val; - struct device *dev; - struct ca91cx42_driver *bridge; - - ctrlr = list->parent; - - bridge = ctrlr->parent->driver_priv; - dev = ctrlr->parent->parent; - - mutex_lock(&ctrlr->mtx); - - if (!(list_empty(&ctrlr->running))) { - /* - * XXX We have an active DMA transfer and currently haven't - * sorted out the mechanism for "pending" DMA transfers. - * Return busy. - */ - /* Need to add to pending here */ - mutex_unlock(&ctrlr->mtx); - return -EBUSY; - } else { - list_add(&list->list, &ctrlr->running); - } - - /* Get first bus address and write into registers */ - entry = list_first_entry(&list->entries, struct ca91cx42_dma_entry, - list); - - bus_addr = virt_to_bus(&entry->descriptor); - - mutex_unlock(&ctrlr->mtx); - - iowrite32(0, bridge->base + DTBC); - iowrite32(bus_addr & ~CA91CX42_DCPP_M, bridge->base + DCPP); - - /* Start the operation */ - val = ioread32(bridge->base + DGCS); - - /* XXX Could set VMEbus On and Off Counters here */ - val &= (CA91CX42_DGCS_VON_M | CA91CX42_DGCS_VOFF_M); - - val |= (CA91CX42_DGCS_CHAIN | CA91CX42_DGCS_STOP | CA91CX42_DGCS_HALT | - CA91CX42_DGCS_DONE | CA91CX42_DGCS_LERR | CA91CX42_DGCS_VERR | - CA91CX42_DGCS_PERR); - - iowrite32(val, bridge->base + DGCS); - - val |= CA91CX42_DGCS_GO; - - iowrite32(val, bridge->base + DGCS); - - wait_event_interruptible(bridge->dma_queue, - ca91cx42_dma_busy(ctrlr->parent)); - - /* - * Read status register, this register is valid until we kick off a - * new transfer. - */ - val = ioread32(bridge->base + DGCS); - - if (val & (CA91CX42_DGCS_LERR | CA91CX42_DGCS_VERR | - CA91CX42_DGCS_PERR)) { - - dev_err(dev, "ca91c042: DMA Error. DGCS=%08X\n", val); - val = ioread32(bridge->base + DCTL); - } - - /* Remove list from running list */ - mutex_lock(&ctrlr->mtx); - list_del(&list->list); - mutex_unlock(&ctrlr->mtx); - - return retval; - -} - -static int ca91cx42_dma_list_empty(struct vme_dma_list *list) -{ - struct list_head *pos, *temp; - struct ca91cx42_dma_entry *entry; - - /* detach and free each entry */ - list_for_each_safe(pos, temp, &list->entries) { - list_del(pos); - entry = list_entry(pos, struct ca91cx42_dma_entry, list); - kfree(entry); - } - - return 0; -} - -/* - * All 4 location monitors reside at the same base - this is therefore a - * system wide configuration. - * - * This does not enable the LM monitor - that should be done when the first - * callback is attached and disabled when the last callback is removed. - */ -static int ca91cx42_lm_set(struct vme_lm_resource *lm, - unsigned long long lm_base, u32 aspace, u32 cycle) -{ - u32 temp_base, lm_ctl = 0; - int i; - struct ca91cx42_driver *bridge; - struct device *dev; - - bridge = lm->parent->driver_priv; - dev = lm->parent->parent; - - /* Check the alignment of the location monitor */ - temp_base = (u32)lm_base; - if (temp_base & 0xffff) { - dev_err(dev, "Location monitor must be aligned to 64KB " - "boundary"); - return -EINVAL; - } - - mutex_lock(&lm->mtx); - - /* If we already have a callback attached, we can't move it! */ - for (i = 0; i < lm->monitors; i++) { - if (bridge->lm_callback[i] != NULL) { - mutex_unlock(&lm->mtx); - dev_err(dev, "Location monitor callback attached, " - "can't reset\n"); - return -EBUSY; - } - } - - switch (aspace) { - case VME_A16: - lm_ctl |= CA91CX42_LM_CTL_AS_A16; - break; - case VME_A24: - lm_ctl |= CA91CX42_LM_CTL_AS_A24; - break; - case VME_A32: - lm_ctl |= CA91CX42_LM_CTL_AS_A32; - break; - default: - mutex_unlock(&lm->mtx); - dev_err(dev, "Invalid address space\n"); - return -EINVAL; - break; - } - - if (cycle & VME_SUPER) - lm_ctl |= CA91CX42_LM_CTL_SUPR; - if (cycle & VME_USER) - lm_ctl |= CA91CX42_LM_CTL_NPRIV; - if (cycle & VME_PROG) - lm_ctl |= CA91CX42_LM_CTL_PGM; - if (cycle & VME_DATA) - lm_ctl |= CA91CX42_LM_CTL_DATA; - - iowrite32(lm_base, bridge->base + LM_BS); - iowrite32(lm_ctl, bridge->base + LM_CTL); - - mutex_unlock(&lm->mtx); - - return 0; -} - -/* Get configuration of the callback monitor and return whether it is enabled - * or disabled. - */ -static int ca91cx42_lm_get(struct vme_lm_resource *lm, - unsigned long long *lm_base, u32 *aspace, u32 *cycle) -{ - u32 lm_ctl, enabled = 0; - struct ca91cx42_driver *bridge; - - bridge = lm->parent->driver_priv; - - mutex_lock(&lm->mtx); - - *lm_base = (unsigned long long)ioread32(bridge->base + LM_BS); - lm_ctl = ioread32(bridge->base + LM_CTL); - - if (lm_ctl & CA91CX42_LM_CTL_EN) - enabled = 1; - - if ((lm_ctl & CA91CX42_LM_CTL_AS_M) == CA91CX42_LM_CTL_AS_A16) - *aspace = VME_A16; - if ((lm_ctl & CA91CX42_LM_CTL_AS_M) == CA91CX42_LM_CTL_AS_A24) - *aspace = VME_A24; - if ((lm_ctl & CA91CX42_LM_CTL_AS_M) == CA91CX42_LM_CTL_AS_A32) - *aspace = VME_A32; - - *cycle = 0; - if (lm_ctl & CA91CX42_LM_CTL_SUPR) - *cycle |= VME_SUPER; - if (lm_ctl & CA91CX42_LM_CTL_NPRIV) - *cycle |= VME_USER; - if (lm_ctl & CA91CX42_LM_CTL_PGM) - *cycle |= VME_PROG; - if (lm_ctl & CA91CX42_LM_CTL_DATA) - *cycle |= VME_DATA; - - mutex_unlock(&lm->mtx); - - return enabled; -} - -/* - * Attach a callback to a specific location monitor. - * - * Callback will be passed the monitor triggered. - */ -static int ca91cx42_lm_attach(struct vme_lm_resource *lm, int monitor, - void (*callback)(int)) -{ - u32 lm_ctl, tmp; - struct ca91cx42_driver *bridge; - struct device *dev; - - bridge = lm->parent->driver_priv; - dev = lm->parent->parent; - - mutex_lock(&lm->mtx); - - /* Ensure that the location monitor is configured - need PGM or DATA */ - lm_ctl = ioread32(bridge->base + LM_CTL); - if ((lm_ctl & (CA91CX42_LM_CTL_PGM | CA91CX42_LM_CTL_DATA)) == 0) { - mutex_unlock(&lm->mtx); - dev_err(dev, "Location monitor not properly configured\n"); - return -EINVAL; - } - - /* Check that a callback isn't already attached */ - if (bridge->lm_callback[monitor] != NULL) { - mutex_unlock(&lm->mtx); - dev_err(dev, "Existing callback attached\n"); - return -EBUSY; - } - - /* Attach callback */ - bridge->lm_callback[monitor] = callback; - - /* Enable Location Monitor interrupt */ - tmp = ioread32(bridge->base + LINT_EN); - tmp |= CA91CX42_LINT_LM[monitor]; - iowrite32(tmp, bridge->base + LINT_EN); - - /* Ensure that global Location Monitor Enable set */ - if ((lm_ctl & CA91CX42_LM_CTL_EN) == 0) { - lm_ctl |= CA91CX42_LM_CTL_EN; - iowrite32(lm_ctl, bridge->base + LM_CTL); - } - - mutex_unlock(&lm->mtx); - - return 0; -} - -/* - * Detach a callback function forn a specific location monitor. - */ -static int ca91cx42_lm_detach(struct vme_lm_resource *lm, int monitor) -{ - u32 tmp; - struct ca91cx42_driver *bridge; - - bridge = lm->parent->driver_priv; - - mutex_lock(&lm->mtx); - - /* Disable Location Monitor and ensure previous interrupts are clear */ - tmp = ioread32(bridge->base + LINT_EN); - tmp &= ~CA91CX42_LINT_LM[monitor]; - iowrite32(tmp, bridge->base + LINT_EN); - - iowrite32(CA91CX42_LINT_LM[monitor], - bridge->base + LINT_STAT); - - /* Detach callback */ - bridge->lm_callback[monitor] = NULL; - - /* If all location monitors disabled, disable global Location Monitor */ - if ((tmp & (CA91CX42_LINT_LM0 | CA91CX42_LINT_LM1 | CA91CX42_LINT_LM2 | - CA91CX42_LINT_LM3)) == 0) { - tmp = ioread32(bridge->base + LM_CTL); - tmp &= ~CA91CX42_LM_CTL_EN; - iowrite32(tmp, bridge->base + LM_CTL); - } - - mutex_unlock(&lm->mtx); - - return 0; -} - -static int ca91cx42_slot_get(struct vme_bridge *ca91cx42_bridge) -{ - u32 slot = 0; - struct ca91cx42_driver *bridge; - - bridge = ca91cx42_bridge->driver_priv; - - if (!geoid) { - slot = ioread32(bridge->base + VCSR_BS); - slot = ((slot & CA91CX42_VCSR_BS_SLOT_M) >> 27); - } else - slot = geoid; - - return (int)slot; - -} - -void *ca91cx42_alloc_consistent(struct device *parent, size_t size, - dma_addr_t *dma) -{ - struct pci_dev *pdev; - - /* Find pci_dev container of dev */ - pdev = container_of(parent, struct pci_dev, dev); - - return pci_alloc_consistent(pdev, size, dma); -} - -void ca91cx42_free_consistent(struct device *parent, size_t size, void *vaddr, - dma_addr_t dma) -{ - struct pci_dev *pdev; - - /* Find pci_dev container of dev */ - pdev = container_of(parent, struct pci_dev, dev); - - pci_free_consistent(pdev, size, vaddr, dma); -} - -static int __init ca91cx42_init(void) -{ - return pci_register_driver(&ca91cx42_driver); -} - -/* - * Configure CR/CSR space - * - * Access to the CR/CSR can be configured at power-up. The location of the - * CR/CSR registers in the CR/CSR address space is determined by the boards - * Auto-ID or Geographic address. This function ensures that the window is - * enabled at an offset consistent with the boards geopgraphic address. - */ -static int ca91cx42_crcsr_init(struct vme_bridge *ca91cx42_bridge, - struct pci_dev *pdev) -{ - unsigned int crcsr_addr; - int tmp, slot; - struct ca91cx42_driver *bridge; - - bridge = ca91cx42_bridge->driver_priv; - - slot = ca91cx42_slot_get(ca91cx42_bridge); - - /* Write CSR Base Address if slot ID is supplied as a module param */ - if (geoid) - iowrite32(geoid << 27, bridge->base + VCSR_BS); - - dev_info(&pdev->dev, "CR/CSR Offset: %d\n", slot); - if (slot == 0) { - dev_err(&pdev->dev, "Slot number is unset, not configuring " - "CR/CSR space\n"); - return -EINVAL; - } - - /* Allocate mem for CR/CSR image */ - bridge->crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE, - &bridge->crcsr_bus); - if (bridge->crcsr_kernel == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for CR/CSR " - "image\n"); - return -ENOMEM; - } - - memset(bridge->crcsr_kernel, 0, VME_CRCSR_BUF_SIZE); - - crcsr_addr = slot * (512 * 1024); - iowrite32(bridge->crcsr_bus - crcsr_addr, bridge->base + VCSR_TO); - - tmp = ioread32(bridge->base + VCSR_CTL); - tmp |= CA91CX42_VCSR_CTL_EN; - iowrite32(tmp, bridge->base + VCSR_CTL); - - return 0; -} - -static void ca91cx42_crcsr_exit(struct vme_bridge *ca91cx42_bridge, - struct pci_dev *pdev) -{ - u32 tmp; - struct ca91cx42_driver *bridge; - - bridge = ca91cx42_bridge->driver_priv; - - /* Turn off CR/CSR space */ - tmp = ioread32(bridge->base + VCSR_CTL); - tmp &= ~CA91CX42_VCSR_CTL_EN; - iowrite32(tmp, bridge->base + VCSR_CTL); - - /* Free image */ - iowrite32(0, bridge->base + VCSR_TO); - - pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, bridge->crcsr_kernel, - bridge->crcsr_bus); -} - -static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) -{ - int retval, i; - u32 data; - struct list_head *pos = NULL; - struct vme_bridge *ca91cx42_bridge; - struct ca91cx42_driver *ca91cx42_device; - struct vme_master_resource *master_image; - struct vme_slave_resource *slave_image; - struct vme_dma_resource *dma_ctrlr; - struct vme_lm_resource *lm; - - /* We want to support more than one of each bridge so we need to - * dynamically allocate the bridge structure - */ - ca91cx42_bridge = kzalloc(sizeof(struct vme_bridge), GFP_KERNEL); - - if (ca91cx42_bridge == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for device " - "structure\n"); - retval = -ENOMEM; - goto err_struct; - } - - ca91cx42_device = kzalloc(sizeof(struct ca91cx42_driver), GFP_KERNEL); - - if (ca91cx42_device == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for device " - "structure\n"); - retval = -ENOMEM; - goto err_driver; - } - - ca91cx42_bridge->driver_priv = ca91cx42_device; - - /* Enable the device */ - retval = pci_enable_device(pdev); - if (retval) { - dev_err(&pdev->dev, "Unable to enable device\n"); - goto err_enable; - } - - /* Map Registers */ - retval = pci_request_regions(pdev, driver_name); - if (retval) { - dev_err(&pdev->dev, "Unable to reserve resources\n"); - goto err_resource; - } - - /* map registers in BAR 0 */ - ca91cx42_device->base = ioremap_nocache(pci_resource_start(pdev, 0), - 4096); - if (!ca91cx42_device->base) { - dev_err(&pdev->dev, "Unable to remap CRG region\n"); - retval = -EIO; - goto err_remap; - } - - /* Check to see if the mapping worked out */ - data = ioread32(ca91cx42_device->base + CA91CX42_PCI_ID) & 0x0000FFFF; - if (data != PCI_VENDOR_ID_TUNDRA) { - dev_err(&pdev->dev, "PCI_ID check failed\n"); - retval = -EIO; - goto err_test; - } - - /* Initialize wait queues & mutual exclusion flags */ - init_waitqueue_head(&ca91cx42_device->dma_queue); - init_waitqueue_head(&ca91cx42_device->iack_queue); - mutex_init(&ca91cx42_device->vme_int); - mutex_init(&ca91cx42_device->vme_rmw); - - ca91cx42_bridge->parent = &pdev->dev; - strcpy(ca91cx42_bridge->name, driver_name); - - /* Setup IRQ */ - retval = ca91cx42_irq_init(ca91cx42_bridge); - if (retval != 0) { - dev_err(&pdev->dev, "Chip Initialization failed.\n"); - goto err_irq; - } - - /* Add master windows to list */ - INIT_LIST_HEAD(&ca91cx42_bridge->master_resources); - for (i = 0; i < CA91C142_MAX_MASTER; i++) { - master_image = kmalloc(sizeof(struct vme_master_resource), - GFP_KERNEL); - if (master_image == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for " - "master resource structure\n"); - retval = -ENOMEM; - goto err_master; - } - master_image->parent = ca91cx42_bridge; - spin_lock_init(&master_image->lock); - master_image->locked = 0; - master_image->number = i; - master_image->address_attr = VME_A16 | VME_A24 | VME_A32 | - VME_CRCSR | VME_USER1 | VME_USER2; - master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | - VME_SUPER | VME_USER | VME_PROG | VME_DATA; - master_image->width_attr = VME_D8 | VME_D16 | VME_D32 | VME_D64; - memset(&master_image->bus_resource, 0, - sizeof(struct resource)); - master_image->kern_base = NULL; - list_add_tail(&master_image->list, - &ca91cx42_bridge->master_resources); - } - - /* Add slave windows to list */ - INIT_LIST_HEAD(&ca91cx42_bridge->slave_resources); - for (i = 0; i < CA91C142_MAX_SLAVE; i++) { - slave_image = kmalloc(sizeof(struct vme_slave_resource), - GFP_KERNEL); - if (slave_image == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for " - "slave resource structure\n"); - retval = -ENOMEM; - goto err_slave; - } - slave_image->parent = ca91cx42_bridge; - mutex_init(&slave_image->mtx); - slave_image->locked = 0; - slave_image->number = i; - slave_image->address_attr = VME_A24 | VME_A32 | VME_USER1 | - VME_USER2; - - /* Only windows 0 and 4 support A16 */ - if (i == 0 || i == 4) - slave_image->address_attr |= VME_A16; - - slave_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | - VME_SUPER | VME_USER | VME_PROG | VME_DATA; - list_add_tail(&slave_image->list, - &ca91cx42_bridge->slave_resources); - } - - /* Add dma engines to list */ - INIT_LIST_HEAD(&ca91cx42_bridge->dma_resources); - for (i = 0; i < CA91C142_MAX_DMA; i++) { - dma_ctrlr = kmalloc(sizeof(struct vme_dma_resource), - GFP_KERNEL); - if (dma_ctrlr == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for " - "dma resource structure\n"); - retval = -ENOMEM; - goto err_dma; - } - dma_ctrlr->parent = ca91cx42_bridge; - mutex_init(&dma_ctrlr->mtx); - dma_ctrlr->locked = 0; - dma_ctrlr->number = i; - dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM | - VME_DMA_MEM_TO_VME; - INIT_LIST_HEAD(&dma_ctrlr->pending); - INIT_LIST_HEAD(&dma_ctrlr->running); - list_add_tail(&dma_ctrlr->list, - &ca91cx42_bridge->dma_resources); - } - - /* Add location monitor to list */ - INIT_LIST_HEAD(&ca91cx42_bridge->lm_resources); - lm = kmalloc(sizeof(struct vme_lm_resource), GFP_KERNEL); - if (lm == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for " - "location monitor resource structure\n"); - retval = -ENOMEM; - goto err_lm; - } - lm->parent = ca91cx42_bridge; - mutex_init(&lm->mtx); - lm->locked = 0; - lm->number = 1; - lm->monitors = 4; - list_add_tail(&lm->list, &ca91cx42_bridge->lm_resources); - - ca91cx42_bridge->slave_get = ca91cx42_slave_get; - ca91cx42_bridge->slave_set = ca91cx42_slave_set; - ca91cx42_bridge->master_get = ca91cx42_master_get; - ca91cx42_bridge->master_set = ca91cx42_master_set; - ca91cx42_bridge->master_read = ca91cx42_master_read; - ca91cx42_bridge->master_write = ca91cx42_master_write; - ca91cx42_bridge->master_rmw = ca91cx42_master_rmw; - ca91cx42_bridge->dma_list_add = ca91cx42_dma_list_add; - ca91cx42_bridge->dma_list_exec = ca91cx42_dma_list_exec; - ca91cx42_bridge->dma_list_empty = ca91cx42_dma_list_empty; - ca91cx42_bridge->irq_set = ca91cx42_irq_set; - ca91cx42_bridge->irq_generate = ca91cx42_irq_generate; - ca91cx42_bridge->lm_set = ca91cx42_lm_set; - ca91cx42_bridge->lm_get = ca91cx42_lm_get; - ca91cx42_bridge->lm_attach = ca91cx42_lm_attach; - ca91cx42_bridge->lm_detach = ca91cx42_lm_detach; - ca91cx42_bridge->slot_get = ca91cx42_slot_get; - ca91cx42_bridge->alloc_consistent = ca91cx42_alloc_consistent; - ca91cx42_bridge->free_consistent = ca91cx42_free_consistent; - - data = ioread32(ca91cx42_device->base + MISC_CTL); - dev_info(&pdev->dev, "Board is%s the VME system controller\n", - (data & CA91CX42_MISC_CTL_SYSCON) ? "" : " not"); - dev_info(&pdev->dev, "Slot ID is %d\n", - ca91cx42_slot_get(ca91cx42_bridge)); - - if (ca91cx42_crcsr_init(ca91cx42_bridge, pdev)) - dev_err(&pdev->dev, "CR/CSR configuration failed.\n"); - - /* Need to save ca91cx42_bridge pointer locally in link list for use in - * ca91cx42_remove() - */ - retval = vme_register_bridge(ca91cx42_bridge); - if (retval != 0) { - dev_err(&pdev->dev, "Chip Registration failed.\n"); - goto err_reg; - } - - pci_set_drvdata(pdev, ca91cx42_bridge); - - return 0; - -err_reg: - ca91cx42_crcsr_exit(ca91cx42_bridge, pdev); -err_lm: - /* resources are stored in link list */ - list_for_each(pos, &ca91cx42_bridge->lm_resources) { - lm = list_entry(pos, struct vme_lm_resource, list); - list_del(pos); - kfree(lm); - } -err_dma: - /* resources are stored in link list */ - list_for_each(pos, &ca91cx42_bridge->dma_resources) { - dma_ctrlr = list_entry(pos, struct vme_dma_resource, list); - list_del(pos); - kfree(dma_ctrlr); - } -err_slave: - /* resources are stored in link list */ - list_for_each(pos, &ca91cx42_bridge->slave_resources) { - slave_image = list_entry(pos, struct vme_slave_resource, list); - list_del(pos); - kfree(slave_image); - } -err_master: - /* resources are stored in link list */ - list_for_each(pos, &ca91cx42_bridge->master_resources) { - master_image = list_entry(pos, struct vme_master_resource, - list); - list_del(pos); - kfree(master_image); - } - - ca91cx42_irq_exit(ca91cx42_device, pdev); -err_irq: -err_test: - iounmap(ca91cx42_device->base); -err_remap: - pci_release_regions(pdev); -err_resource: - pci_disable_device(pdev); -err_enable: - kfree(ca91cx42_device); -err_driver: - kfree(ca91cx42_bridge); -err_struct: - return retval; - -} - -static void ca91cx42_remove(struct pci_dev *pdev) -{ - struct list_head *pos = NULL; - struct vme_master_resource *master_image; - struct vme_slave_resource *slave_image; - struct vme_dma_resource *dma_ctrlr; - struct vme_lm_resource *lm; - struct ca91cx42_driver *bridge; - struct vme_bridge *ca91cx42_bridge = pci_get_drvdata(pdev); - - bridge = ca91cx42_bridge->driver_priv; - - - /* Turn off Ints */ - iowrite32(0, bridge->base + LINT_EN); - - /* Turn off the windows */ - iowrite32(0x00800000, bridge->base + LSI0_CTL); - iowrite32(0x00800000, bridge->base + LSI1_CTL); - iowrite32(0x00800000, bridge->base + LSI2_CTL); - iowrite32(0x00800000, bridge->base + LSI3_CTL); - iowrite32(0x00800000, bridge->base + LSI4_CTL); - iowrite32(0x00800000, bridge->base + LSI5_CTL); - iowrite32(0x00800000, bridge->base + LSI6_CTL); - iowrite32(0x00800000, bridge->base + LSI7_CTL); - iowrite32(0x00F00000, bridge->base + VSI0_CTL); - iowrite32(0x00F00000, bridge->base + VSI1_CTL); - iowrite32(0x00F00000, bridge->base + VSI2_CTL); - iowrite32(0x00F00000, bridge->base + VSI3_CTL); - iowrite32(0x00F00000, bridge->base + VSI4_CTL); - iowrite32(0x00F00000, bridge->base + VSI5_CTL); - iowrite32(0x00F00000, bridge->base + VSI6_CTL); - iowrite32(0x00F00000, bridge->base + VSI7_CTL); - - vme_unregister_bridge(ca91cx42_bridge); - - ca91cx42_crcsr_exit(ca91cx42_bridge, pdev); - - /* resources are stored in link list */ - list_for_each(pos, &ca91cx42_bridge->lm_resources) { - lm = list_entry(pos, struct vme_lm_resource, list); - list_del(pos); - kfree(lm); - } - - /* resources are stored in link list */ - list_for_each(pos, &ca91cx42_bridge->dma_resources) { - dma_ctrlr = list_entry(pos, struct vme_dma_resource, list); - list_del(pos); - kfree(dma_ctrlr); - } - - /* resources are stored in link list */ - list_for_each(pos, &ca91cx42_bridge->slave_resources) { - slave_image = list_entry(pos, struct vme_slave_resource, list); - list_del(pos); - kfree(slave_image); - } - - /* resources are stored in link list */ - list_for_each(pos, &ca91cx42_bridge->master_resources) { - master_image = list_entry(pos, struct vme_master_resource, - list); - list_del(pos); - kfree(master_image); - } - - ca91cx42_irq_exit(bridge, pdev); - - iounmap(bridge->base); - - pci_release_regions(pdev); - - pci_disable_device(pdev); - - kfree(ca91cx42_bridge); -} - -static void __exit ca91cx42_exit(void) -{ - pci_unregister_driver(&ca91cx42_driver); -} - -MODULE_PARM_DESC(geoid, "Override geographical addressing"); -module_param(geoid, int, 0); - -MODULE_DESCRIPTION("VME driver for the Tundra Universe II VME bridge"); -MODULE_LICENSE("GPL"); - -module_init(ca91cx42_init); -module_exit(ca91cx42_exit); diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.h b/drivers/staging/vme/bridges/vme_ca91cx42.h deleted file mode 100644 index 02a7c79..0000000 --- a/drivers/staging/vme/bridges/vme_ca91cx42.h +++ /dev/null @@ -1,583 +0,0 @@ -/* - * ca91c042.h - * - * Support for the Tundra Universe 1 and Universe II VME bridge chips - * - * Author: Tom Armistead - * Updated by Ajit Prem - * Copyright 2004 Motorola Inc. - * - * Further updated by Martyn Welch - * Copyright 2009 GE Intelligent Platforms Embedded Systems, Inc. - * - * Derived from ca91c042.h by Michael Wyrick - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef _CA91CX42_H -#define _CA91CX42_H - -#ifndef PCI_VENDOR_ID_TUNDRA -#define PCI_VENDOR_ID_TUNDRA 0x10e3 -#endif - -#ifndef PCI_DEVICE_ID_TUNDRA_CA91C142 -#define PCI_DEVICE_ID_TUNDRA_CA91C142 0x0000 -#endif - -/* - * Define the number of each that the CA91C142 supports. - */ -#define CA91C142_MAX_MASTER 8 /* Max Master Windows */ -#define CA91C142_MAX_SLAVE 8 /* Max Slave Windows */ -#define CA91C142_MAX_DMA 1 /* Max DMA Controllers */ -#define CA91C142_MAX_MAILBOX 4 /* Max Mail Box registers */ - -/* Structure used to hold driver specific information */ -struct ca91cx42_driver { - void __iomem *base; /* Base Address of device registers */ - wait_queue_head_t dma_queue; - wait_queue_head_t iack_queue; - wait_queue_head_t mbox_queue; - void (*lm_callback[4])(int); /* Called in interrupt handler */ - void *crcsr_kernel; - dma_addr_t crcsr_bus; - struct mutex vme_rmw; /* Only one RMW cycle at a time */ - struct mutex vme_int; /* - * Only one VME interrupt can be - * generated at a time, provide locking - */ -}; - -/* See Page 2-77 in the Universe User Manual */ -struct ca91cx42_dma_descriptor { - unsigned int dctl; /* DMA Control */ - unsigned int dtbc; /* Transfer Byte Count */ - unsigned int dla; /* PCI Address */ - unsigned int res1; /* Reserved */ - unsigned int dva; /* Vme Address */ - unsigned int res2; /* Reserved */ - unsigned int dcpp; /* Pointer to Numed Cmd Packet with rPN */ - unsigned int res3; /* Reserved */ -}; - -struct ca91cx42_dma_entry { - struct ca91cx42_dma_descriptor descriptor; - struct list_head list; -}; - -/* Universe Register Offsets */ -/* general PCI configuration registers */ -#define CA91CX42_PCI_ID 0x000 -#define CA91CX42_PCI_CSR 0x004 -#define CA91CX42_PCI_CLASS 0x008 -#define CA91CX42_PCI_MISC0 0x00C -#define CA91CX42_PCI_BS 0x010 -#define CA91CX42_PCI_MISC1 0x03C - -#define LSI0_CTL 0x0100 -#define LSI0_BS 0x0104 -#define LSI0_BD 0x0108 -#define LSI0_TO 0x010C - -#define LSI1_CTL 0x0114 -#define LSI1_BS 0x0118 -#define LSI1_BD 0x011C -#define LSI1_TO 0x0120 - -#define LSI2_CTL 0x0128 -#define LSI2_BS 0x012C -#define LSI2_BD 0x0130 -#define LSI2_TO 0x0134 - -#define LSI3_CTL 0x013C -#define LSI3_BS 0x0140 -#define LSI3_BD 0x0144 -#define LSI3_TO 0x0148 - -#define LSI4_CTL 0x01A0 -#define LSI4_BS 0x01A4 -#define LSI4_BD 0x01A8 -#define LSI4_TO 0x01AC - -#define LSI5_CTL 0x01B4 -#define LSI5_BS 0x01B8 -#define LSI5_BD 0x01BC -#define LSI5_TO 0x01C0 - -#define LSI6_CTL 0x01C8 -#define LSI6_BS 0x01CC -#define LSI6_BD 0x01D0 -#define LSI6_TO 0x01D4 - -#define LSI7_CTL 0x01DC -#define LSI7_BS 0x01E0 -#define LSI7_BD 0x01E4 -#define LSI7_TO 0x01E8 - -static const int CA91CX42_LSI_CTL[] = { LSI0_CTL, LSI1_CTL, LSI2_CTL, LSI3_CTL, - LSI4_CTL, LSI5_CTL, LSI6_CTL, LSI7_CTL }; - -static const int CA91CX42_LSI_BS[] = { LSI0_BS, LSI1_BS, LSI2_BS, LSI3_BS, - LSI4_BS, LSI5_BS, LSI6_BS, LSI7_BS }; - -static const int CA91CX42_LSI_BD[] = { LSI0_BD, LSI1_BD, LSI2_BD, LSI3_BD, - LSI4_BD, LSI5_BD, LSI6_BD, LSI7_BD }; - -static const int CA91CX42_LSI_TO[] = { LSI0_TO, LSI1_TO, LSI2_TO, LSI3_TO, - LSI4_TO, LSI5_TO, LSI6_TO, LSI7_TO }; - -#define SCYC_CTL 0x0170 -#define SCYC_ADDR 0x0174 -#define SCYC_EN 0x0178 -#define SCYC_CMP 0x017C -#define SCYC_SWP 0x0180 -#define LMISC 0x0184 -#define SLSI 0x0188 -#define L_CMDERR 0x018C -#define LAERR 0x0190 - -#define DCTL 0x0200 -#define DTBC 0x0204 -#define DLA 0x0208 -#define DVA 0x0210 -#define DCPP 0x0218 -#define DGCS 0x0220 -#define D_LLUE 0x0224 - -#define LINT_EN 0x0300 -#define LINT_STAT 0x0304 -#define LINT_MAP0 0x0308 -#define LINT_MAP1 0x030C -#define VINT_EN 0x0310 -#define VINT_STAT 0x0314 -#define VINT_MAP0 0x0318 -#define VINT_MAP1 0x031C -#define STATID 0x0320 - -#define V1_STATID 0x0324 -#define V2_STATID 0x0328 -#define V3_STATID 0x032C -#define V4_STATID 0x0330 -#define V5_STATID 0x0334 -#define V6_STATID 0x0338 -#define V7_STATID 0x033C - -static const int CA91CX42_V_STATID[8] = { 0, V1_STATID, V2_STATID, V3_STATID, - V4_STATID, V5_STATID, V6_STATID, - V7_STATID }; - -#define LINT_MAP2 0x0340 -#define VINT_MAP2 0x0344 - -#define MBOX0 0x0348 -#define MBOX1 0x034C -#define MBOX2 0x0350 -#define MBOX3 0x0354 -#define SEMA0 0x0358 -#define SEMA1 0x035C - -#define MAST_CTL 0x0400 -#define MISC_CTL 0x0404 -#define MISC_STAT 0x0408 -#define USER_AM 0x040C - -#define VSI0_CTL 0x0F00 -#define VSI0_BS 0x0F04 -#define VSI0_BD 0x0F08 -#define VSI0_TO 0x0F0C - -#define VSI1_CTL 0x0F14 -#define VSI1_BS 0x0F18 -#define VSI1_BD 0x0F1C -#define VSI1_TO 0x0F20 - -#define VSI2_CTL 0x0F28 -#define VSI2_BS 0x0F2C -#define VSI2_BD 0x0F30 -#define VSI2_TO 0x0F34 - -#define VSI3_CTL 0x0F3C -#define VSI3_BS 0x0F40 -#define VSI3_BD 0x0F44 -#define VSI3_TO 0x0F48 - -#define LM_CTL 0x0F64 -#define LM_BS 0x0F68 - -#define VRAI_CTL 0x0F70 - -#define VRAI_BS 0x0F74 -#define VCSR_CTL 0x0F80 -#define VCSR_TO 0x0F84 -#define V_AMERR 0x0F88 -#define VAERR 0x0F8C - -#define VSI4_CTL 0x0F90 -#define VSI4_BS 0x0F94 -#define VSI4_BD 0x0F98 -#define VSI4_TO 0x0F9C - -#define VSI5_CTL 0x0FA4 -#define VSI5_BS 0x0FA8 -#define VSI5_BD 0x0FAC -#define VSI5_TO 0x0FB0 - -#define VSI6_CTL 0x0FB8 -#define VSI6_BS 0x0FBC -#define VSI6_BD 0x0FC0 -#define VSI6_TO 0x0FC4 - -#define VSI7_CTL 0x0FCC -#define VSI7_BS 0x0FD0 -#define VSI7_BD 0x0FD4 -#define VSI7_TO 0x0FD8 - -static const int CA91CX42_VSI_CTL[] = { VSI0_CTL, VSI1_CTL, VSI2_CTL, VSI3_CTL, - VSI4_CTL, VSI5_CTL, VSI6_CTL, VSI7_CTL }; - -static const int CA91CX42_VSI_BS[] = { VSI0_BS, VSI1_BS, VSI2_BS, VSI3_BS, - VSI4_BS, VSI5_BS, VSI6_BS, VSI7_BS }; - -static const int CA91CX42_VSI_BD[] = { VSI0_BD, VSI1_BD, VSI2_BD, VSI3_BD, - VSI4_BD, VSI5_BD, VSI6_BD, VSI7_BD }; - -static const int CA91CX42_VSI_TO[] = { VSI0_TO, VSI1_TO, VSI2_TO, VSI3_TO, - VSI4_TO, VSI5_TO, VSI6_TO, VSI7_TO }; - -#define VCSR_CLR 0x0FF4 -#define VCSR_SET 0x0FF8 -#define VCSR_BS 0x0FFC - -/* - * PCI Class Register - * offset 008 - */ -#define CA91CX42_BM_PCI_CLASS_BASE 0xFF000000 -#define CA91CX42_OF_PCI_CLASS_BASE 24 -#define CA91CX42_BM_PCI_CLASS_SUB 0x00FF0000 -#define CA91CX42_OF_PCI_CLASS_SUB 16 -#define CA91CX42_BM_PCI_CLASS_PROG 0x0000FF00 -#define CA91CX42_OF_PCI_CLASS_PROG 8 -#define CA91CX42_BM_PCI_CLASS_RID 0x000000FF -#define CA91CX42_OF_PCI_CLASS_RID 0 - -#define CA91CX42_OF_PCI_CLASS_RID_UNIVERSE_I 0 -#define CA91CX42_OF_PCI_CLASS_RID_UNIVERSE_II 1 - -/* - * PCI Misc Register - * offset 00C - */ -#define CA91CX42_BM_PCI_MISC0_BISTC 0x80000000 -#define CA91CX42_BM_PCI_MISC0_SBIST 0x60000000 -#define CA91CX42_BM_PCI_MISC0_CCODE 0x0F000000 -#define CA91CX42_BM_PCI_MISC0_MFUNCT 0x00800000 -#define CA91CX42_BM_PCI_MISC0_LAYOUT 0x007F0000 -#define CA91CX42_BM_PCI_MISC0_LTIMER 0x0000FF00 -#define CA91CX42_OF_PCI_MISC0_LTIMER 8 - - -/* - * LSI Control Register - * offset 100 - */ -#define CA91CX42_LSI_CTL_EN (1<<31) -#define CA91CX42_LSI_CTL_PWEN (1<<30) - -#define CA91CX42_LSI_CTL_VDW_M (3<<22) -#define CA91CX42_LSI_CTL_VDW_D8 0 -#define CA91CX42_LSI_CTL_VDW_D16 (1<<22) -#define CA91CX42_LSI_CTL_VDW_D32 (1<<23) -#define CA91CX42_LSI_CTL_VDW_D64 (3<<22) - -#define CA91CX42_LSI_CTL_VAS_M (7<<16) -#define CA91CX42_LSI_CTL_VAS_A16 0 -#define CA91CX42_LSI_CTL_VAS_A24 (1<<16) -#define CA91CX42_LSI_CTL_VAS_A32 (1<<17) -#define CA91CX42_LSI_CTL_VAS_CRCSR (5<<16) -#define CA91CX42_LSI_CTL_VAS_USER1 (3<<17) -#define CA91CX42_LSI_CTL_VAS_USER2 (7<<16) - -#define CA91CX42_LSI_CTL_PGM_M (1<<14) -#define CA91CX42_LSI_CTL_PGM_DATA 0 -#define CA91CX42_LSI_CTL_PGM_PGM (1<<14) - -#define CA91CX42_LSI_CTL_SUPER_M (1<<12) -#define CA91CX42_LSI_CTL_SUPER_NPRIV 0 -#define CA91CX42_LSI_CTL_SUPER_SUPR (1<<12) - -#define CA91CX42_LSI_CTL_VCT_M (1<<8) -#define CA91CX42_LSI_CTL_VCT_BLT (1<<8) -#define CA91CX42_LSI_CTL_VCT_MBLT (1<<8) -#define CA91CX42_LSI_CTL_LAS (1<<0) - -/* - * SCYC_CTL Register - * offset 178 - */ -#define CA91CX42_SCYC_CTL_LAS_PCIMEM 0 -#define CA91CX42_SCYC_CTL_LAS_PCIIO (1<<2) - -#define CA91CX42_SCYC_CTL_CYC_M (3<<0) -#define CA91CX42_SCYC_CTL_CYC_RMW (1<<0) -#define CA91CX42_SCYC_CTL_CYC_ADOH (1<<1) - -/* - * LMISC Register - * offset 184 - */ -#define CA91CX42_BM_LMISC_CRT 0xF0000000 -#define CA91CX42_OF_LMISC_CRT 28 -#define CA91CX42_BM_LMISC_CWT 0x0F000000 -#define CA91CX42_OF_LMISC_CWT 24 - -/* - * SLSI Register - * offset 188 - */ -#define CA91CX42_BM_SLSI_EN 0x80000000 -#define CA91CX42_BM_SLSI_PWEN 0x40000000 -#define CA91CX42_BM_SLSI_VDW 0x00F00000 -#define CA91CX42_OF_SLSI_VDW 20 -#define CA91CX42_BM_SLSI_PGM 0x0000F000 -#define CA91CX42_OF_SLSI_PGM 12 -#define CA91CX42_BM_SLSI_SUPER 0x00000F00 -#define CA91CX42_OF_SLSI_SUPER 8 -#define CA91CX42_BM_SLSI_BS 0x000000F6 -#define CA91CX42_OF_SLSI_BS 2 -#define CA91CX42_BM_SLSI_LAS 0x00000003 -#define CA91CX42_OF_SLSI_LAS 0 -#define CA91CX42_BM_SLSI_RESERVED 0x3F0F0000 - -/* - * DCTL Register - * offset 200 - */ -#define CA91CX42_DCTL_L2V (1<<31) -#define CA91CX42_DCTL_VDW_M (3<<22) -#define CA91CX42_DCTL_VDW_M (3<<22) -#define CA91CX42_DCTL_VDW_D8 0 -#define CA91CX42_DCTL_VDW_D16 (1<<22) -#define CA91CX42_DCTL_VDW_D32 (1<<23) -#define CA91CX42_DCTL_VDW_D64 (3<<22) - -#define CA91CX42_DCTL_VAS_M (7<<16) -#define CA91CX42_DCTL_VAS_A16 0 -#define CA91CX42_DCTL_VAS_A24 (1<<16) -#define CA91CX42_DCTL_VAS_A32 (1<<17) -#define CA91CX42_DCTL_VAS_USER1 (3<<17) -#define CA91CX42_DCTL_VAS_USER2 (7<<16) - -#define CA91CX42_DCTL_PGM_M (1<<14) -#define CA91CX42_DCTL_PGM_DATA 0 -#define CA91CX42_DCTL_PGM_PGM (1<<14) - -#define CA91CX42_DCTL_SUPER_M (1<<12) -#define CA91CX42_DCTL_SUPER_NPRIV 0 -#define CA91CX42_DCTL_SUPER_SUPR (1<<12) - -#define CA91CX42_DCTL_VCT_M (1<<8) -#define CA91CX42_DCTL_VCT_BLT (1<<8) -#define CA91CX42_DCTL_LD64EN (1<<7) - -/* - * DCPP Register - * offset 218 - */ -#define CA91CX42_DCPP_M 0xf -#define CA91CX42_DCPP_NULL (1<<0) - -/* - * DMA General Control/Status Register (DGCS) - * offset 220 - */ -#define CA91CX42_DGCS_GO (1<<31) -#define CA91CX42_DGCS_STOP_REQ (1<<30) -#define CA91CX42_DGCS_HALT_REQ (1<<29) -#define CA91CX42_DGCS_CHAIN (1<<27) - -#define CA91CX42_DGCS_VON_M (7<<20) - -#define CA91CX42_DGCS_VOFF_M (0xf<<16) - -#define CA91CX42_DGCS_ACT (1<<15) -#define CA91CX42_DGCS_STOP (1<<14) -#define CA91CX42_DGCS_HALT (1<<13) -#define CA91CX42_DGCS_DONE (1<<11) -#define CA91CX42_DGCS_LERR (1<<10) -#define CA91CX42_DGCS_VERR (1<<9) -#define CA91CX42_DGCS_PERR (1<<8) -#define CA91CX42_DGCS_INT_STOP (1<<6) -#define CA91CX42_DGCS_INT_HALT (1<<5) -#define CA91CX42_DGCS_INT_DONE (1<<3) -#define CA91CX42_DGCS_INT_LERR (1<<2) -#define CA91CX42_DGCS_INT_VERR (1<<1) -#define CA91CX42_DGCS_INT_PERR (1<<0) - -/* - * PCI Interrupt Enable Register - * offset 300 - */ -#define CA91CX42_LINT_LM3 0x00800000 -#define CA91CX42_LINT_LM2 0x00400000 -#define CA91CX42_LINT_LM1 0x00200000 -#define CA91CX42_LINT_LM0 0x00100000 -#define CA91CX42_LINT_MBOX3 0x00080000 -#define CA91CX42_LINT_MBOX2 0x00040000 -#define CA91CX42_LINT_MBOX1 0x00020000 -#define CA91CX42_LINT_MBOX0 0x00010000 -#define CA91CX42_LINT_ACFAIL 0x00008000 -#define CA91CX42_LINT_SYSFAIL 0x00004000 -#define CA91CX42_LINT_SW_INT 0x00002000 -#define CA91CX42_LINT_SW_IACK 0x00001000 - -#define CA91CX42_LINT_VERR 0x00000400 -#define CA91CX42_LINT_LERR 0x00000200 -#define CA91CX42_LINT_DMA 0x00000100 -#define CA91CX42_LINT_VIRQ7 0x00000080 -#define CA91CX42_LINT_VIRQ6 0x00000040 -#define CA91CX42_LINT_VIRQ5 0x00000020 -#define CA91CX42_LINT_VIRQ4 0x00000010 -#define CA91CX42_LINT_VIRQ3 0x00000008 -#define CA91CX42_LINT_VIRQ2 0x00000004 -#define CA91CX42_LINT_VIRQ1 0x00000002 -#define CA91CX42_LINT_VOWN 0x00000001 - -static const int CA91CX42_LINT_VIRQ[] = { 0, CA91CX42_LINT_VIRQ1, - CA91CX42_LINT_VIRQ2, CA91CX42_LINT_VIRQ3, - CA91CX42_LINT_VIRQ4, CA91CX42_LINT_VIRQ5, - CA91CX42_LINT_VIRQ6, CA91CX42_LINT_VIRQ7 }; - -#define CA91CX42_LINT_MBOX 0x000F0000 - -static const int CA91CX42_LINT_LM[] = { CA91CX42_LINT_LM0, CA91CX42_LINT_LM1, - CA91CX42_LINT_LM2, CA91CX42_LINT_LM3 }; - -/* - * MAST_CTL Register - * offset 400 - */ -#define CA91CX42_BM_MAST_CTL_MAXRTRY 0xF0000000 -#define CA91CX42_OF_MAST_CTL_MAXRTRY 28 -#define CA91CX42_BM_MAST_CTL_PWON 0x0F000000 -#define CA91CX42_OF_MAST_CTL_PWON 24 -#define CA91CX42_BM_MAST_CTL_VRL 0x00C00000 -#define CA91CX42_OF_MAST_CTL_VRL 22 -#define CA91CX42_BM_MAST_CTL_VRM 0x00200000 -#define CA91CX42_BM_MAST_CTL_VREL 0x00100000 -#define CA91CX42_BM_MAST_CTL_VOWN 0x00080000 -#define CA91CX42_BM_MAST_CTL_VOWN_ACK 0x00040000 -#define CA91CX42_BM_MAST_CTL_PABS 0x00001000 -#define CA91CX42_BM_MAST_CTL_BUS_NO 0x0000000F -#define CA91CX42_OF_MAST_CTL_BUS_NO 0 - -/* - * MISC_CTL Register - * offset 404 - */ -#define CA91CX42_MISC_CTL_VBTO 0xF0000000 -#define CA91CX42_MISC_CTL_VARB 0x04000000 -#define CA91CX42_MISC_CTL_VARBTO 0x03000000 -#define CA91CX42_MISC_CTL_SW_LRST 0x00800000 -#define CA91CX42_MISC_CTL_SW_SRST 0x00400000 -#define CA91CX42_MISC_CTL_BI 0x00100000 -#define CA91CX42_MISC_CTL_ENGBI 0x00080000 -#define CA91CX42_MISC_CTL_RESCIND 0x00040000 -#define CA91CX42_MISC_CTL_SYSCON 0x00020000 -#define CA91CX42_MISC_CTL_V64AUTO 0x00010000 -#define CA91CX42_MISC_CTL_RESERVED 0x0820FFFF - -#define CA91CX42_OF_MISC_CTL_VARBTO 24 -#define CA91CX42_OF_MISC_CTL_VBTO 28 - -/* - * MISC_STAT Register - * offset 408 - */ -#define CA91CX42_BM_MISC_STAT_ENDIAN 0x80000000 -#define CA91CX42_BM_MISC_STAT_LCLSIZE 0x40000000 -#define CA91CX42_BM_MISC_STAT_DY4AUTO 0x08000000 -#define CA91CX42_BM_MISC_STAT_MYBBSY 0x00200000 -#define CA91CX42_BM_MISC_STAT_DY4DONE 0x00080000 -#define CA91CX42_BM_MISC_STAT_TXFE 0x00040000 -#define CA91CX42_BM_MISC_STAT_RXFE 0x00020000 -#define CA91CX42_BM_MISC_STAT_DY4AUTOID 0x0000FF00 -#define CA91CX42_OF_MISC_STAT_DY4AUTOID 8 - -/* - * VSI Control Register - * offset F00 - */ -#define CA91CX42_VSI_CTL_EN (1<<31) -#define CA91CX42_VSI_CTL_PWEN (1<<30) -#define CA91CX42_VSI_CTL_PREN (1<<29) - -#define CA91CX42_VSI_CTL_PGM_M (3<<22) -#define CA91CX42_VSI_CTL_PGM_DATA (1<<22) -#define CA91CX42_VSI_CTL_PGM_PGM (1<<23) - -#define CA91CX42_VSI_CTL_SUPER_M (3<<20) -#define CA91CX42_VSI_CTL_SUPER_NPRIV (1<<20) -#define CA91CX42_VSI_CTL_SUPER_SUPR (1<<21) - -#define CA91CX42_VSI_CTL_VAS_M (7<<16) -#define CA91CX42_VSI_CTL_VAS_A16 0 -#define CA91CX42_VSI_CTL_VAS_A24 (1<<16) -#define CA91CX42_VSI_CTL_VAS_A32 (1<<17) -#define CA91CX42_VSI_CTL_VAS_USER1 (3<<17) -#define CA91CX42_VSI_CTL_VAS_USER2 (7<<16) - -#define CA91CX42_VSI_CTL_LD64EN (1<<7) -#define CA91CX42_VSI_CTL_LLRMW (1<<6) - -#define CA91CX42_VSI_CTL_LAS_M (3<<0) -#define CA91CX42_VSI_CTL_LAS_PCI_MS 0 -#define CA91CX42_VSI_CTL_LAS_PCI_IO (1<<0) -#define CA91CX42_VSI_CTL_LAS_PCI_CONF (1<<1) - -/* LM_CTL Register - * offset F64 - */ -#define CA91CX42_LM_CTL_EN (1<<31) -#define CA91CX42_LM_CTL_PGM (1<<23) -#define CA91CX42_LM_CTL_DATA (1<<22) -#define CA91CX42_LM_CTL_SUPR (1<<21) -#define CA91CX42_LM_CTL_NPRIV (1<<20) -#define CA91CX42_LM_CTL_AS_M (5<<16) -#define CA91CX42_LM_CTL_AS_A16 0 -#define CA91CX42_LM_CTL_AS_A24 (1<<16) -#define CA91CX42_LM_CTL_AS_A32 (1<<17) - -/* - * VRAI_CTL Register - * offset F70 - */ -#define CA91CX42_BM_VRAI_CTL_EN 0x80000000 -#define CA91CX42_BM_VRAI_CTL_PGM 0x00C00000 -#define CA91CX42_OF_VRAI_CTL_PGM 22 -#define CA91CX42_BM_VRAI_CTL_SUPER 0x00300000 -#define CA91CX42_OF_VRAI_CTL_SUPER 20 -#define CA91CX42_BM_VRAI_CTL_VAS 0x00030000 -#define CA91CX42_OF_VRAI_CTL_VAS 16 - -/* VCSR_CTL Register - * offset F80 - */ -#define CA91CX42_VCSR_CTL_EN (1<<31) - -#define CA91CX42_VCSR_CTL_LAS_M (3<<0) -#define CA91CX42_VCSR_CTL_LAS_PCI_MS 0 -#define CA91CX42_VCSR_CTL_LAS_PCI_IO (1<<0) -#define CA91CX42_VCSR_CTL_LAS_PCI_CONF (1<<1) - -/* VCSR_BS Register - * offset FFC - */ -#define CA91CX42_VCSR_BS_SLOT_M (0x1F<<27) - -#endif /* _CA91CX42_H */ diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c deleted file mode 100644 index ced5942..0000000 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ /dev/null @@ -1,2691 +0,0 @@ -/* - * Support for the Tundra TSI148 VME-PCI Bridge Chip - * - * Author: Martyn Welch - * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. - * - * Based on work by Tom Armistead and Ajit Prem - * Copyright 2004 Motorola 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../vme.h" -#include "../vme_bridge.h" -#include "vme_tsi148.h" - -static int __init tsi148_init(void); -static int tsi148_probe(struct pci_dev *, const struct pci_device_id *); -static void tsi148_remove(struct pci_dev *); -static void __exit tsi148_exit(void); - - -/* Module parameter */ -static bool err_chk; -static int geoid; - -static const char driver_name[] = "vme_tsi148"; - -static DEFINE_PCI_DEVICE_TABLE(tsi148_ids) = { - { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_TSI148) }, - { }, -}; - -static struct pci_driver tsi148_driver = { - .name = driver_name, - .id_table = tsi148_ids, - .probe = tsi148_probe, - .remove = tsi148_remove, -}; - -static void reg_join(unsigned int high, unsigned int low, - unsigned long long *variable) -{ - *variable = (unsigned long long)high << 32; - *variable |= (unsigned long long)low; -} - -static void reg_split(unsigned long long variable, unsigned int *high, - unsigned int *low) -{ - *low = (unsigned int)variable & 0xFFFFFFFF; - *high = (unsigned int)(variable >> 32); -} - -/* - * Wakes up DMA queue. - */ -static u32 tsi148_DMA_irqhandler(struct tsi148_driver *bridge, - int channel_mask) -{ - u32 serviced = 0; - - if (channel_mask & TSI148_LCSR_INTS_DMA0S) { - wake_up(&bridge->dma_queue[0]); - serviced |= TSI148_LCSR_INTC_DMA0C; - } - if (channel_mask & TSI148_LCSR_INTS_DMA1S) { - wake_up(&bridge->dma_queue[1]); - serviced |= TSI148_LCSR_INTC_DMA1C; - } - - return serviced; -} - -/* - * Wake up location monitor queue - */ -static u32 tsi148_LM_irqhandler(struct tsi148_driver *bridge, u32 stat) -{ - int i; - u32 serviced = 0; - - for (i = 0; i < 4; i++) { - if (stat & TSI148_LCSR_INTS_LMS[i]) { - /* We only enable interrupts if the callback is set */ - bridge->lm_callback[i](i); - serviced |= TSI148_LCSR_INTC_LMC[i]; - } - } - - return serviced; -} - -/* - * Wake up mail box queue. - * - * XXX This functionality is not exposed up though API. - */ -static u32 tsi148_MB_irqhandler(struct vme_bridge *tsi148_bridge, u32 stat) -{ - int i; - u32 val; - u32 serviced = 0; - struct tsi148_driver *bridge; - - bridge = tsi148_bridge->driver_priv; - - for (i = 0; i < 4; i++) { - if (stat & TSI148_LCSR_INTS_MBS[i]) { - val = ioread32be(bridge->base + TSI148_GCSR_MBOX[i]); - dev_err(tsi148_bridge->parent, "VME Mailbox %d received" - ": 0x%x\n", i, val); - serviced |= TSI148_LCSR_INTC_MBC[i]; - } - } - - return serviced; -} - -/* - * Display error & status message when PERR (PCI) exception interrupt occurs. - */ -static u32 tsi148_PERR_irqhandler(struct vme_bridge *tsi148_bridge) -{ - struct tsi148_driver *bridge; - - bridge = tsi148_bridge->driver_priv; - - dev_err(tsi148_bridge->parent, "PCI Exception at address: 0x%08x:%08x, " - "attributes: %08x\n", - ioread32be(bridge->base + TSI148_LCSR_EDPAU), - ioread32be(bridge->base + TSI148_LCSR_EDPAL), - ioread32be(bridge->base + TSI148_LCSR_EDPAT)); - - dev_err(tsi148_bridge->parent, "PCI-X attribute reg: %08x, PCI-X split " - "completion reg: %08x\n", - ioread32be(bridge->base + TSI148_LCSR_EDPXA), - ioread32be(bridge->base + TSI148_LCSR_EDPXS)); - - iowrite32be(TSI148_LCSR_EDPAT_EDPCL, bridge->base + TSI148_LCSR_EDPAT); - - return TSI148_LCSR_INTC_PERRC; -} - -/* - * Save address and status when VME error interrupt occurs. - */ -static u32 tsi148_VERR_irqhandler(struct vme_bridge *tsi148_bridge) -{ - unsigned int error_addr_high, error_addr_low; - unsigned long long error_addr; - u32 error_attrib; - struct vme_bus_error *error; - struct tsi148_driver *bridge; - - bridge = tsi148_bridge->driver_priv; - - error_addr_high = ioread32be(bridge->base + TSI148_LCSR_VEAU); - error_addr_low = ioread32be(bridge->base + TSI148_LCSR_VEAL); - error_attrib = ioread32be(bridge->base + TSI148_LCSR_VEAT); - - reg_join(error_addr_high, error_addr_low, &error_addr); - - /* Check for exception register overflow (we have lost error data) */ - if (error_attrib & TSI148_LCSR_VEAT_VEOF) { - dev_err(tsi148_bridge->parent, "VME Bus Exception Overflow " - "Occurred\n"); - } - - error = kmalloc(sizeof(struct vme_bus_error), GFP_ATOMIC); - if (error) { - error->address = error_addr; - error->attributes = error_attrib; - list_add_tail(&error->list, &tsi148_bridge->vme_errors); - } else { - dev_err(tsi148_bridge->parent, "Unable to alloc memory for " - "VMEbus Error reporting\n"); - dev_err(tsi148_bridge->parent, "VME Bus Error at address: " - "0x%llx, attributes: %08x\n", error_addr, error_attrib); - } - - /* Clear Status */ - iowrite32be(TSI148_LCSR_VEAT_VESCL, bridge->base + TSI148_LCSR_VEAT); - - return TSI148_LCSR_INTC_VERRC; -} - -/* - * Wake up IACK queue. - */ -static u32 tsi148_IACK_irqhandler(struct tsi148_driver *bridge) -{ - wake_up(&bridge->iack_queue); - - return TSI148_LCSR_INTC_IACKC; -} - -/* - * Calling VME bus interrupt callback if provided. - */ -static u32 tsi148_VIRQ_irqhandler(struct vme_bridge *tsi148_bridge, - u32 stat) -{ - int vec, i, serviced = 0; - struct tsi148_driver *bridge; - - bridge = tsi148_bridge->driver_priv; - - for (i = 7; i > 0; i--) { - if (stat & (1 << i)) { - /* - * Note: Even though the registers are defined as - * 32-bits in the spec, we only want to issue 8-bit - * IACK cycles on the bus, read from offset 3. - */ - vec = ioread8(bridge->base + TSI148_LCSR_VIACK[i] + 3); - - vme_irq_handler(tsi148_bridge, i, vec); - - serviced |= (1 << i); - } - } - - return serviced; -} - -/* - * Top level interrupt handler. Clears appropriate interrupt status bits and - * then calls appropriate sub handler(s). - */ -static irqreturn_t tsi148_irqhandler(int irq, void *ptr) -{ - u32 stat, enable, serviced = 0; - struct vme_bridge *tsi148_bridge; - struct tsi148_driver *bridge; - - tsi148_bridge = ptr; - - bridge = tsi148_bridge->driver_priv; - - /* Determine which interrupts are unmasked and set */ - enable = ioread32be(bridge->base + TSI148_LCSR_INTEO); - stat = ioread32be(bridge->base + TSI148_LCSR_INTS); - - /* Only look at unmasked interrupts */ - stat &= enable; - - if (unlikely(!stat)) - return IRQ_NONE; - - /* Call subhandlers as appropriate */ - /* DMA irqs */ - if (stat & (TSI148_LCSR_INTS_DMA1S | TSI148_LCSR_INTS_DMA0S)) - serviced |= tsi148_DMA_irqhandler(bridge, stat); - - /* Location monitor irqs */ - if (stat & (TSI148_LCSR_INTS_LM3S | TSI148_LCSR_INTS_LM2S | - TSI148_LCSR_INTS_LM1S | TSI148_LCSR_INTS_LM0S)) - serviced |= tsi148_LM_irqhandler(bridge, stat); - - /* Mail box irqs */ - if (stat & (TSI148_LCSR_INTS_MB3S | TSI148_LCSR_INTS_MB2S | - TSI148_LCSR_INTS_MB1S | TSI148_LCSR_INTS_MB0S)) - serviced |= tsi148_MB_irqhandler(tsi148_bridge, stat); - - /* PCI bus error */ - if (stat & TSI148_LCSR_INTS_PERRS) - serviced |= tsi148_PERR_irqhandler(tsi148_bridge); - - /* VME bus error */ - if (stat & TSI148_LCSR_INTS_VERRS) - serviced |= tsi148_VERR_irqhandler(tsi148_bridge); - - /* IACK irq */ - if (stat & TSI148_LCSR_INTS_IACKS) - serviced |= tsi148_IACK_irqhandler(bridge); - - /* VME bus irqs */ - if (stat & (TSI148_LCSR_INTS_IRQ7S | TSI148_LCSR_INTS_IRQ6S | - TSI148_LCSR_INTS_IRQ5S | TSI148_LCSR_INTS_IRQ4S | - TSI148_LCSR_INTS_IRQ3S | TSI148_LCSR_INTS_IRQ2S | - TSI148_LCSR_INTS_IRQ1S)) - serviced |= tsi148_VIRQ_irqhandler(tsi148_bridge, stat); - - /* Clear serviced interrupts */ - iowrite32be(serviced, bridge->base + TSI148_LCSR_INTC); - - return IRQ_HANDLED; -} - -static int tsi148_irq_init(struct vme_bridge *tsi148_bridge) -{ - int result; - unsigned int tmp; - struct pci_dev *pdev; - struct tsi148_driver *bridge; - - pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev); - - bridge = tsi148_bridge->driver_priv; - - /* Initialise list for VME bus errors */ - INIT_LIST_HEAD(&tsi148_bridge->vme_errors); - - mutex_init(&tsi148_bridge->irq_mtx); - - result = request_irq(pdev->irq, - tsi148_irqhandler, - IRQF_SHARED, - driver_name, tsi148_bridge); - if (result) { - dev_err(tsi148_bridge->parent, "Can't get assigned pci irq " - "vector %02X\n", pdev->irq); - return result; - } - - /* Enable and unmask interrupts */ - tmp = TSI148_LCSR_INTEO_DMA1EO | TSI148_LCSR_INTEO_DMA0EO | - TSI148_LCSR_INTEO_MB3EO | TSI148_LCSR_INTEO_MB2EO | - TSI148_LCSR_INTEO_MB1EO | TSI148_LCSR_INTEO_MB0EO | - TSI148_LCSR_INTEO_PERREO | TSI148_LCSR_INTEO_VERREO | - TSI148_LCSR_INTEO_IACKEO; - - /* This leaves the following interrupts masked. - * TSI148_LCSR_INTEO_VIEEO - * TSI148_LCSR_INTEO_SYSFLEO - * TSI148_LCSR_INTEO_ACFLEO - */ - - /* Don't enable Location Monitor interrupts here - they will be - * enabled when the location monitors are properly configured and - * a callback has been attached. - * TSI148_LCSR_INTEO_LM0EO - * TSI148_LCSR_INTEO_LM1EO - * TSI148_LCSR_INTEO_LM2EO - * TSI148_LCSR_INTEO_LM3EO - */ - - /* Don't enable VME interrupts until we add a handler, else the board - * will respond to it and we don't want that unless it knows how to - * properly deal with it. - * TSI148_LCSR_INTEO_IRQ7EO - * TSI148_LCSR_INTEO_IRQ6EO - * TSI148_LCSR_INTEO_IRQ5EO - * TSI148_LCSR_INTEO_IRQ4EO - * TSI148_LCSR_INTEO_IRQ3EO - * TSI148_LCSR_INTEO_IRQ2EO - * TSI148_LCSR_INTEO_IRQ1EO - */ - - iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO); - iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN); - - return 0; -} - -static void tsi148_irq_exit(struct vme_bridge *tsi148_bridge, - struct pci_dev *pdev) -{ - struct tsi148_driver *bridge = tsi148_bridge->driver_priv; - - /* Turn off interrupts */ - iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEO); - iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEN); - - /* Clear all interrupts */ - iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_INTC); - - /* Detach interrupt handler */ - free_irq(pdev->irq, tsi148_bridge); -} - -/* - * Check to see if an IACk has been received, return true (1) or false (0). - */ -static int tsi148_iack_received(struct tsi148_driver *bridge) -{ - u32 tmp; - - tmp = ioread32be(bridge->base + TSI148_LCSR_VICR); - - if (tmp & TSI148_LCSR_VICR_IRQS) - return 0; - else - return 1; -} - -/* - * Configure VME interrupt - */ -static void tsi148_irq_set(struct vme_bridge *tsi148_bridge, int level, - int state, int sync) -{ - struct pci_dev *pdev; - u32 tmp; - struct tsi148_driver *bridge; - - bridge = tsi148_bridge->driver_priv; - - /* We need to do the ordering differently for enabling and disabling */ - if (state == 0) { - tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN); - tmp &= ~TSI148_LCSR_INTEN_IRQEN[level - 1]; - iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN); - - tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO); - tmp &= ~TSI148_LCSR_INTEO_IRQEO[level - 1]; - iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO); - - if (sync != 0) { - pdev = container_of(tsi148_bridge->parent, - struct pci_dev, dev); - - synchronize_irq(pdev->irq); - } - } else { - tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO); - tmp |= TSI148_LCSR_INTEO_IRQEO[level - 1]; - iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO); - - tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN); - tmp |= TSI148_LCSR_INTEN_IRQEN[level - 1]; - iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN); - } -} - -/* - * Generate a VME bus interrupt at the requested level & vector. Wait for - * interrupt to be acked. - */ -static int tsi148_irq_generate(struct vme_bridge *tsi148_bridge, int level, - int statid) -{ - u32 tmp; - struct tsi148_driver *bridge; - - bridge = tsi148_bridge->driver_priv; - - mutex_lock(&bridge->vme_int); - - /* Read VICR register */ - tmp = ioread32be(bridge->base + TSI148_LCSR_VICR); - - /* Set Status/ID */ - tmp = (tmp & ~TSI148_LCSR_VICR_STID_M) | - (statid & TSI148_LCSR_VICR_STID_M); - iowrite32be(tmp, bridge->base + TSI148_LCSR_VICR); - - /* Assert VMEbus IRQ */ - tmp = tmp | TSI148_LCSR_VICR_IRQL[level]; - iowrite32be(tmp, bridge->base + TSI148_LCSR_VICR); - - /* XXX Consider implementing a timeout? */ - wait_event_interruptible(bridge->iack_queue, - tsi148_iack_received(bridge)); - - mutex_unlock(&bridge->vme_int); - - return 0; -} - -/* - * Find the first error in this address range - */ -static struct vme_bus_error *tsi148_find_error(struct vme_bridge *tsi148_bridge, - u32 aspace, unsigned long long address, size_t count) -{ - struct list_head *err_pos; - struct vme_bus_error *vme_err, *valid = NULL; - unsigned long long bound; - - bound = address + count; - - /* - * XXX We are currently not looking at the address space when parsing - * for errors. This is because parsing the Address Modifier Codes - * is going to be quite resource intensive to do properly. We - * should be OK just looking at the addresses and this is certainly - * much better than what we had before. - */ - err_pos = NULL; - /* Iterate through errors */ - list_for_each(err_pos, &tsi148_bridge->vme_errors) { - vme_err = list_entry(err_pos, struct vme_bus_error, list); - if ((vme_err->address >= address) && - (vme_err->address < bound)) { - - valid = vme_err; - break; - } - } - - return valid; -} - -/* - * Clear errors in the provided address range. - */ -static void tsi148_clear_errors(struct vme_bridge *tsi148_bridge, - u32 aspace, unsigned long long address, size_t count) -{ - struct list_head *err_pos, *temp; - struct vme_bus_error *vme_err; - unsigned long long bound; - - bound = address + count; - - /* - * XXX We are currently not looking at the address space when parsing - * for errors. This is because parsing the Address Modifier Codes - * is going to be quite resource intensive to do properly. We - * should be OK just looking at the addresses and this is certainly - * much better than what we had before. - */ - err_pos = NULL; - /* Iterate through errors */ - list_for_each_safe(err_pos, temp, &tsi148_bridge->vme_errors) { - vme_err = list_entry(err_pos, struct vme_bus_error, list); - - if ((vme_err->address >= address) && - (vme_err->address < bound)) { - - list_del(err_pos); - kfree(vme_err); - } - } -} - -/* - * Initialize a slave window with the requested attributes. - */ -static int tsi148_slave_set(struct vme_slave_resource *image, int enabled, - unsigned long long vme_base, unsigned long long size, - dma_addr_t pci_base, u32 aspace, u32 cycle) -{ - unsigned int i, addr = 0, granularity = 0; - unsigned int temp_ctl = 0; - unsigned int vme_base_low, vme_base_high; - unsigned int vme_bound_low, vme_bound_high; - unsigned int pci_offset_low, pci_offset_high; - unsigned long long vme_bound, pci_offset; - struct vme_bridge *tsi148_bridge; - struct tsi148_driver *bridge; - - tsi148_bridge = image->parent; - bridge = tsi148_bridge->driver_priv; - - i = image->number; - - switch (aspace) { - case VME_A16: - granularity = 0x10; - addr |= TSI148_LCSR_ITAT_AS_A16; - break; - case VME_A24: - granularity = 0x1000; - addr |= TSI148_LCSR_ITAT_AS_A24; - break; - case VME_A32: - granularity = 0x10000; - addr |= TSI148_LCSR_ITAT_AS_A32; - break; - case VME_A64: - granularity = 0x10000; - addr |= TSI148_LCSR_ITAT_AS_A64; - break; - case VME_CRCSR: - case VME_USER1: - case VME_USER2: - case VME_USER3: - case VME_USER4: - default: - dev_err(tsi148_bridge->parent, "Invalid address space\n"); - return -EINVAL; - break; - } - - /* Convert 64-bit variables to 2x 32-bit variables */ - reg_split(vme_base, &vme_base_high, &vme_base_low); - - /* - * Bound address is a valid address for the window, adjust - * accordingly - */ - vme_bound = vme_base + size - granularity; - reg_split(vme_bound, &vme_bound_high, &vme_bound_low); - pci_offset = (unsigned long long)pci_base - vme_base; - reg_split(pci_offset, &pci_offset_high, &pci_offset_low); - - if (vme_base_low & (granularity - 1)) { - dev_err(tsi148_bridge->parent, "Invalid VME base alignment\n"); - return -EINVAL; - } - if (vme_bound_low & (granularity - 1)) { - dev_err(tsi148_bridge->parent, "Invalid VME bound alignment\n"); - return -EINVAL; - } - if (pci_offset_low & (granularity - 1)) { - dev_err(tsi148_bridge->parent, "Invalid PCI Offset " - "alignment\n"); - return -EINVAL; - } - - /* Disable while we are mucking around */ - temp_ctl = ioread32be(bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITAT); - temp_ctl &= ~TSI148_LCSR_ITAT_EN; - iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITAT); - - /* Setup mapping */ - iowrite32be(vme_base_high, bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITSAU); - iowrite32be(vme_base_low, bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITSAL); - iowrite32be(vme_bound_high, bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITEAU); - iowrite32be(vme_bound_low, bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITEAL); - iowrite32be(pci_offset_high, bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITOFU); - iowrite32be(pci_offset_low, bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITOFL); - - /* Setup 2eSST speeds */ - temp_ctl &= ~TSI148_LCSR_ITAT_2eSSTM_M; - switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) { - case VME_2eSST160: - temp_ctl |= TSI148_LCSR_ITAT_2eSSTM_160; - break; - case VME_2eSST267: - temp_ctl |= TSI148_LCSR_ITAT_2eSSTM_267; - break; - case VME_2eSST320: - temp_ctl |= TSI148_LCSR_ITAT_2eSSTM_320; - break; - } - - /* Setup cycle types */ - temp_ctl &= ~(0x1F << 7); - if (cycle & VME_BLT) - temp_ctl |= TSI148_LCSR_ITAT_BLT; - if (cycle & VME_MBLT) - temp_ctl |= TSI148_LCSR_ITAT_MBLT; - if (cycle & VME_2eVME) - temp_ctl |= TSI148_LCSR_ITAT_2eVME; - if (cycle & VME_2eSST) - temp_ctl |= TSI148_LCSR_ITAT_2eSST; - if (cycle & VME_2eSSTB) - temp_ctl |= TSI148_LCSR_ITAT_2eSSTB; - - /* Setup address space */ - temp_ctl &= ~TSI148_LCSR_ITAT_AS_M; - temp_ctl |= addr; - - temp_ctl &= ~0xF; - if (cycle & VME_SUPER) - temp_ctl |= TSI148_LCSR_ITAT_SUPR ; - if (cycle & VME_USER) - temp_ctl |= TSI148_LCSR_ITAT_NPRIV; - if (cycle & VME_PROG) - temp_ctl |= TSI148_LCSR_ITAT_PGM; - if (cycle & VME_DATA) - temp_ctl |= TSI148_LCSR_ITAT_DATA; - - /* Write ctl reg without enable */ - iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITAT); - - if (enabled) - temp_ctl |= TSI148_LCSR_ITAT_EN; - - iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITAT); - - return 0; -} - -/* - * Get slave window configuration. - */ -static int tsi148_slave_get(struct vme_slave_resource *image, int *enabled, - unsigned long long *vme_base, unsigned long long *size, - dma_addr_t *pci_base, u32 *aspace, u32 *cycle) -{ - unsigned int i, granularity = 0, ctl = 0; - unsigned int vme_base_low, vme_base_high; - unsigned int vme_bound_low, vme_bound_high; - unsigned int pci_offset_low, pci_offset_high; - unsigned long long vme_bound, pci_offset; - struct tsi148_driver *bridge; - - bridge = image->parent->driver_priv; - - i = image->number; - - /* Read registers */ - ctl = ioread32be(bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITAT); - - vme_base_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITSAU); - vme_base_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITSAL); - vme_bound_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITEAU); - vme_bound_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITEAL); - pci_offset_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITOFU); - pci_offset_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITOFL); - - /* Convert 64-bit variables to 2x 32-bit variables */ - reg_join(vme_base_high, vme_base_low, vme_base); - reg_join(vme_bound_high, vme_bound_low, &vme_bound); - reg_join(pci_offset_high, pci_offset_low, &pci_offset); - - *pci_base = (dma_addr_t)vme_base + pci_offset; - - *enabled = 0; - *aspace = 0; - *cycle = 0; - - if (ctl & TSI148_LCSR_ITAT_EN) - *enabled = 1; - - if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A16) { - granularity = 0x10; - *aspace |= VME_A16; - } - if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A24) { - granularity = 0x1000; - *aspace |= VME_A24; - } - if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A32) { - granularity = 0x10000; - *aspace |= VME_A32; - } - if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A64) { - granularity = 0x10000; - *aspace |= VME_A64; - } - - /* Need granularity before we set the size */ - *size = (unsigned long long)((vme_bound - *vme_base) + granularity); - - - if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_160) - *cycle |= VME_2eSST160; - if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_267) - *cycle |= VME_2eSST267; - if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_320) - *cycle |= VME_2eSST320; - - if (ctl & TSI148_LCSR_ITAT_BLT) - *cycle |= VME_BLT; - if (ctl & TSI148_LCSR_ITAT_MBLT) - *cycle |= VME_MBLT; - if (ctl & TSI148_LCSR_ITAT_2eVME) - *cycle |= VME_2eVME; - if (ctl & TSI148_LCSR_ITAT_2eSST) - *cycle |= VME_2eSST; - if (ctl & TSI148_LCSR_ITAT_2eSSTB) - *cycle |= VME_2eSSTB; - - if (ctl & TSI148_LCSR_ITAT_SUPR) - *cycle |= VME_SUPER; - if (ctl & TSI148_LCSR_ITAT_NPRIV) - *cycle |= VME_USER; - if (ctl & TSI148_LCSR_ITAT_PGM) - *cycle |= VME_PROG; - if (ctl & TSI148_LCSR_ITAT_DATA) - *cycle |= VME_DATA; - - return 0; -} - -/* - * Allocate and map PCI Resource - */ -static int tsi148_alloc_resource(struct vme_master_resource *image, - unsigned long long size) -{ - unsigned long long existing_size; - int retval = 0; - struct pci_dev *pdev; - struct vme_bridge *tsi148_bridge; - - tsi148_bridge = image->parent; - - pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev); - - existing_size = (unsigned long long)(image->bus_resource.end - - image->bus_resource.start); - - /* If the existing size is OK, return */ - if ((size != 0) && (existing_size == (size - 1))) - return 0; - - if (existing_size != 0) { - iounmap(image->kern_base); - image->kern_base = NULL; - kfree(image->bus_resource.name); - release_resource(&image->bus_resource); - memset(&image->bus_resource, 0, sizeof(struct resource)); - } - - /* Exit here if size is zero */ - if (size == 0) - return 0; - - if (image->bus_resource.name == NULL) { - image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_ATOMIC); - if (image->bus_resource.name == NULL) { - dev_err(tsi148_bridge->parent, "Unable to allocate " - "memory for resource name\n"); - retval = -ENOMEM; - goto err_name; - } - } - - sprintf((char *)image->bus_resource.name, "%s.%d", tsi148_bridge->name, - image->number); - - image->bus_resource.start = 0; - image->bus_resource.end = (unsigned long)size; - image->bus_resource.flags = IORESOURCE_MEM; - - retval = pci_bus_alloc_resource(pdev->bus, - &image->bus_resource, size, size, PCIBIOS_MIN_MEM, - 0, NULL, NULL); - if (retval) { - dev_err(tsi148_bridge->parent, "Failed to allocate mem " - "resource for window %d size 0x%lx start 0x%lx\n", - image->number, (unsigned long)size, - (unsigned long)image->bus_resource.start); - goto err_resource; - } - - image->kern_base = ioremap_nocache( - image->bus_resource.start, size); - if (image->kern_base == NULL) { - dev_err(tsi148_bridge->parent, "Failed to remap resource\n"); - retval = -ENOMEM; - goto err_remap; - } - - return 0; - -err_remap: - release_resource(&image->bus_resource); -err_resource: - kfree(image->bus_resource.name); - memset(&image->bus_resource, 0, sizeof(struct resource)); -err_name: - return retval; -} - -/* - * Free and unmap PCI Resource - */ -static void tsi148_free_resource(struct vme_master_resource *image) -{ - iounmap(image->kern_base); - image->kern_base = NULL; - release_resource(&image->bus_resource); - kfree(image->bus_resource.name); - memset(&image->bus_resource, 0, sizeof(struct resource)); -} - -/* - * Set the attributes of an outbound window. - */ -static int tsi148_master_set(struct vme_master_resource *image, int enabled, - unsigned long long vme_base, unsigned long long size, u32 aspace, - u32 cycle, u32 dwidth) -{ - int retval = 0; - unsigned int i; - unsigned int temp_ctl = 0; - unsigned int pci_base_low, pci_base_high; - unsigned int pci_bound_low, pci_bound_high; - unsigned int vme_offset_low, vme_offset_high; - unsigned long long pci_bound, vme_offset, pci_base; - struct vme_bridge *tsi148_bridge; - struct tsi148_driver *bridge; - - tsi148_bridge = image->parent; - - bridge = tsi148_bridge->driver_priv; - - /* Verify input data */ - if (vme_base & 0xFFFF) { - dev_err(tsi148_bridge->parent, "Invalid VME Window " - "alignment\n"); - retval = -EINVAL; - goto err_window; - } - - if ((size == 0) && (enabled != 0)) { - dev_err(tsi148_bridge->parent, "Size must be non-zero for " - "enabled windows\n"); - retval = -EINVAL; - goto err_window; - } - - spin_lock(&image->lock); - - /* Let's allocate the resource here rather than further up the stack as - * it avoids pushing loads of bus dependent stuff up the stack. If size - * is zero, any existing resource will be freed. - */ - retval = tsi148_alloc_resource(image, size); - if (retval) { - spin_unlock(&image->lock); - dev_err(tsi148_bridge->parent, "Unable to allocate memory for " - "resource\n"); - goto err_res; - } - - if (size == 0) { - pci_base = 0; - pci_bound = 0; - vme_offset = 0; - } else { - pci_base = (unsigned long long)image->bus_resource.start; - - /* - * Bound address is a valid address for the window, adjust - * according to window granularity. - */ - pci_bound = pci_base + (size - 0x10000); - vme_offset = vme_base - pci_base; - } - - /* Convert 64-bit variables to 2x 32-bit variables */ - reg_split(pci_base, &pci_base_high, &pci_base_low); - reg_split(pci_bound, &pci_bound_high, &pci_bound_low); - reg_split(vme_offset, &vme_offset_high, &vme_offset_low); - - if (pci_base_low & 0xFFFF) { - spin_unlock(&image->lock); - dev_err(tsi148_bridge->parent, "Invalid PCI base alignment\n"); - retval = -EINVAL; - goto err_gran; - } - if (pci_bound_low & 0xFFFF) { - spin_unlock(&image->lock); - dev_err(tsi148_bridge->parent, "Invalid PCI bound alignment\n"); - retval = -EINVAL; - goto err_gran; - } - if (vme_offset_low & 0xFFFF) { - spin_unlock(&image->lock); - dev_err(tsi148_bridge->parent, "Invalid VME Offset " - "alignment\n"); - retval = -EINVAL; - goto err_gran; - } - - i = image->number; - - /* Disable while we are mucking around */ - temp_ctl = ioread32be(bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTAT); - temp_ctl &= ~TSI148_LCSR_OTAT_EN; - iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTAT); - - /* Setup 2eSST speeds */ - temp_ctl &= ~TSI148_LCSR_OTAT_2eSSTM_M; - switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) { - case VME_2eSST160: - temp_ctl |= TSI148_LCSR_OTAT_2eSSTM_160; - break; - case VME_2eSST267: - temp_ctl |= TSI148_LCSR_OTAT_2eSSTM_267; - break; - case VME_2eSST320: - temp_ctl |= TSI148_LCSR_OTAT_2eSSTM_320; - break; - } - - /* Setup cycle types */ - if (cycle & VME_BLT) { - temp_ctl &= ~TSI148_LCSR_OTAT_TM_M; - temp_ctl |= TSI148_LCSR_OTAT_TM_BLT; - } - if (cycle & VME_MBLT) { - temp_ctl &= ~TSI148_LCSR_OTAT_TM_M; - temp_ctl |= TSI148_LCSR_OTAT_TM_MBLT; - } - if (cycle & VME_2eVME) { - temp_ctl &= ~TSI148_LCSR_OTAT_TM_M; - temp_ctl |= TSI148_LCSR_OTAT_TM_2eVME; - } - if (cycle & VME_2eSST) { - temp_ctl &= ~TSI148_LCSR_OTAT_TM_M; - temp_ctl |= TSI148_LCSR_OTAT_TM_2eSST; - } - if (cycle & VME_2eSSTB) { - dev_warn(tsi148_bridge->parent, "Currently not setting " - "Broadcast Select Registers\n"); - temp_ctl &= ~TSI148_LCSR_OTAT_TM_M; - temp_ctl |= TSI148_LCSR_OTAT_TM_2eSSTB; - } - - /* Setup data width */ - temp_ctl &= ~TSI148_LCSR_OTAT_DBW_M; - switch (dwidth) { - case VME_D16: - temp_ctl |= TSI148_LCSR_OTAT_DBW_16; - break; - case VME_D32: - temp_ctl |= TSI148_LCSR_OTAT_DBW_32; - break; - default: - spin_unlock(&image->lock); - dev_err(tsi148_bridge->parent, "Invalid data width\n"); - retval = -EINVAL; - goto err_dwidth; - } - - /* Setup address space */ - temp_ctl &= ~TSI148_LCSR_OTAT_AMODE_M; - switch (aspace) { - case VME_A16: - temp_ctl |= TSI148_LCSR_OTAT_AMODE_A16; - break; - case VME_A24: - temp_ctl |= TSI148_LCSR_OTAT_AMODE_A24; - break; - case VME_A32: - temp_ctl |= TSI148_LCSR_OTAT_AMODE_A32; - break; - case VME_A64: - temp_ctl |= TSI148_LCSR_OTAT_AMODE_A64; - break; - case VME_CRCSR: - temp_ctl |= TSI148_LCSR_OTAT_AMODE_CRCSR; - break; - case VME_USER1: - temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER1; - break; - case VME_USER2: - temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER2; - break; - case VME_USER3: - temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER3; - break; - case VME_USER4: - temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER4; - break; - default: - spin_unlock(&image->lock); - dev_err(tsi148_bridge->parent, "Invalid address space\n"); - retval = -EINVAL; - goto err_aspace; - break; - } - - temp_ctl &= ~(3<<4); - if (cycle & VME_SUPER) - temp_ctl |= TSI148_LCSR_OTAT_SUP; - if (cycle & VME_PROG) - temp_ctl |= TSI148_LCSR_OTAT_PGM; - - /* Setup mapping */ - iowrite32be(pci_base_high, bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTSAU); - iowrite32be(pci_base_low, bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTSAL); - iowrite32be(pci_bound_high, bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTEAU); - iowrite32be(pci_bound_low, bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTEAL); - iowrite32be(vme_offset_high, bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTOFU); - iowrite32be(vme_offset_low, bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTOFL); - - /* Write ctl reg without enable */ - iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTAT); - - if (enabled) - temp_ctl |= TSI148_LCSR_OTAT_EN; - - iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTAT); - - spin_unlock(&image->lock); - return 0; - -err_aspace: -err_dwidth: -err_gran: - tsi148_free_resource(image); -err_res: -err_window: - return retval; - -} - -/* - * Set the attributes of an outbound window. - * - * XXX Not parsing prefetch information. - */ -static int __tsi148_master_get(struct vme_master_resource *image, int *enabled, - unsigned long long *vme_base, unsigned long long *size, u32 *aspace, - u32 *cycle, u32 *dwidth) -{ - unsigned int i, ctl; - unsigned int pci_base_low, pci_base_high; - unsigned int pci_bound_low, pci_bound_high; - unsigned int vme_offset_low, vme_offset_high; - - unsigned long long pci_base, pci_bound, vme_offset; - struct tsi148_driver *bridge; - - bridge = image->parent->driver_priv; - - i = image->number; - - ctl = ioread32be(bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTAT); - - pci_base_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTSAU); - pci_base_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTSAL); - pci_bound_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTEAU); - pci_bound_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTEAL); - vme_offset_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTOFU); - vme_offset_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTOFL); - - /* Convert 64-bit variables to 2x 32-bit variables */ - reg_join(pci_base_high, pci_base_low, &pci_base); - reg_join(pci_bound_high, pci_bound_low, &pci_bound); - reg_join(vme_offset_high, vme_offset_low, &vme_offset); - - *vme_base = pci_base + vme_offset; - *size = (unsigned long long)(pci_bound - pci_base) + 0x10000; - - *enabled = 0; - *aspace = 0; - *cycle = 0; - *dwidth = 0; - - if (ctl & TSI148_LCSR_OTAT_EN) - *enabled = 1; - - /* Setup address space */ - if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A16) - *aspace |= VME_A16; - if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A24) - *aspace |= VME_A24; - if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A32) - *aspace |= VME_A32; - if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A64) - *aspace |= VME_A64; - if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_CRCSR) - *aspace |= VME_CRCSR; - if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER1) - *aspace |= VME_USER1; - if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER2) - *aspace |= VME_USER2; - if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER3) - *aspace |= VME_USER3; - if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER4) - *aspace |= VME_USER4; - - /* Setup 2eSST speeds */ - if ((ctl & TSI148_LCSR_OTAT_2eSSTM_M) == TSI148_LCSR_OTAT_2eSSTM_160) - *cycle |= VME_2eSST160; - if ((ctl & TSI148_LCSR_OTAT_2eSSTM_M) == TSI148_LCSR_OTAT_2eSSTM_267) - *cycle |= VME_2eSST267; - if ((ctl & TSI148_LCSR_OTAT_2eSSTM_M) == TSI148_LCSR_OTAT_2eSSTM_320) - *cycle |= VME_2eSST320; - - /* Setup cycle types */ - if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_SCT) - *cycle |= VME_SCT; - if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_BLT) - *cycle |= VME_BLT; - if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_MBLT) - *cycle |= VME_MBLT; - if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_2eVME) - *cycle |= VME_2eVME; - if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_2eSST) - *cycle |= VME_2eSST; - if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_2eSSTB) - *cycle |= VME_2eSSTB; - - if (ctl & TSI148_LCSR_OTAT_SUP) - *cycle |= VME_SUPER; - else - *cycle |= VME_USER; - - if (ctl & TSI148_LCSR_OTAT_PGM) - *cycle |= VME_PROG; - else - *cycle |= VME_DATA; - - /* Setup data width */ - if ((ctl & TSI148_LCSR_OTAT_DBW_M) == TSI148_LCSR_OTAT_DBW_16) - *dwidth = VME_D16; - if ((ctl & TSI148_LCSR_OTAT_DBW_M) == TSI148_LCSR_OTAT_DBW_32) - *dwidth = VME_D32; - - return 0; -} - - -static int tsi148_master_get(struct vme_master_resource *image, int *enabled, - unsigned long long *vme_base, unsigned long long *size, u32 *aspace, - u32 *cycle, u32 *dwidth) -{ - int retval; - - spin_lock(&image->lock); - - retval = __tsi148_master_get(image, enabled, vme_base, size, aspace, - cycle, dwidth); - - spin_unlock(&image->lock); - - return retval; -} - -static ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf, - size_t count, loff_t offset) -{ - int retval, enabled; - unsigned long long vme_base, size; - u32 aspace, cycle, dwidth; - struct vme_bus_error *vme_err = NULL; - struct vme_bridge *tsi148_bridge; - - tsi148_bridge = image->parent; - - spin_lock(&image->lock); - - memcpy_fromio(buf, image->kern_base + offset, (unsigned int)count); - retval = count; - - if (!err_chk) - goto skip_chk; - - __tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle, - &dwidth); - - vme_err = tsi148_find_error(tsi148_bridge, aspace, vme_base + offset, - count); - if (vme_err != NULL) { - dev_err(image->parent->parent, "First VME read error detected " - "an at address 0x%llx\n", vme_err->address); - retval = vme_err->address - (vme_base + offset); - /* Clear down save errors in this address range */ - tsi148_clear_errors(tsi148_bridge, aspace, vme_base + offset, - count); - } - -skip_chk: - spin_unlock(&image->lock); - - return retval; -} - - -static ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf, - size_t count, loff_t offset) -{ - int retval = 0, enabled; - unsigned long long vme_base, size; - u32 aspace, cycle, dwidth; - - struct vme_bus_error *vme_err = NULL; - struct vme_bridge *tsi148_bridge; - struct tsi148_driver *bridge; - - tsi148_bridge = image->parent; - - bridge = tsi148_bridge->driver_priv; - - spin_lock(&image->lock); - - memcpy_toio(image->kern_base + offset, buf, (unsigned int)count); - retval = count; - - /* - * Writes are posted. We need to do a read on the VME bus to flush out - * all of the writes before we check for errors. We can't guarantee - * that reading the data we have just written is safe. It is believed - * that there isn't any read, write re-ordering, so we can read any - * location in VME space, so lets read the Device ID from the tsi148's - * own registers as mapped into CR/CSR space. - * - * We check for saved errors in the written address range/space. - */ - - if (!err_chk) - goto skip_chk; - - /* - * Get window info first, to maximise the time that the buffers may - * fluch on their own - */ - __tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle, - &dwidth); - - ioread16(bridge->flush_image->kern_base + 0x7F000); - - vme_err = tsi148_find_error(tsi148_bridge, aspace, vme_base + offset, - count); - if (vme_err != NULL) { - dev_warn(tsi148_bridge->parent, "First VME write error detected" - " an at address 0x%llx\n", vme_err->address); - retval = vme_err->address - (vme_base + offset); - /* Clear down save errors in this address range */ - tsi148_clear_errors(tsi148_bridge, aspace, vme_base + offset, - count); - } - -skip_chk: - spin_unlock(&image->lock); - - return retval; -} - -/* - * Perform an RMW cycle on the VME bus. - * - * Requires a previously configured master window, returns final value. - */ -static unsigned int tsi148_master_rmw(struct vme_master_resource *image, - unsigned int mask, unsigned int compare, unsigned int swap, - loff_t offset) -{ - unsigned long long pci_addr; - unsigned int pci_addr_high, pci_addr_low; - u32 tmp, result; - int i; - struct tsi148_driver *bridge; - - bridge = image->parent->driver_priv; - - /* Find the PCI address that maps to the desired VME address */ - i = image->number; - - /* Locking as we can only do one of these at a time */ - mutex_lock(&bridge->vme_rmw); - - /* Lock image */ - spin_lock(&image->lock); - - pci_addr_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTSAU); - pci_addr_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTSAL); - - reg_join(pci_addr_high, pci_addr_low, &pci_addr); - reg_split(pci_addr + offset, &pci_addr_high, &pci_addr_low); - - /* Configure registers */ - iowrite32be(mask, bridge->base + TSI148_LCSR_RMWEN); - iowrite32be(compare, bridge->base + TSI148_LCSR_RMWC); - iowrite32be(swap, bridge->base + TSI148_LCSR_RMWS); - iowrite32be(pci_addr_high, bridge->base + TSI148_LCSR_RMWAU); - iowrite32be(pci_addr_low, bridge->base + TSI148_LCSR_RMWAL); - - /* Enable RMW */ - tmp = ioread32be(bridge->base + TSI148_LCSR_VMCTRL); - tmp |= TSI148_LCSR_VMCTRL_RMWEN; - iowrite32be(tmp, bridge->base + TSI148_LCSR_VMCTRL); - - /* Kick process off with a read to the required address. */ - result = ioread32be(image->kern_base + offset); - - /* Disable RMW */ - tmp = ioread32be(bridge->base + TSI148_LCSR_VMCTRL); - tmp &= ~TSI148_LCSR_VMCTRL_RMWEN; - iowrite32be(tmp, bridge->base + TSI148_LCSR_VMCTRL); - - spin_unlock(&image->lock); - - mutex_unlock(&bridge->vme_rmw); - - return result; -} - -static int tsi148_dma_set_vme_src_attributes(struct device *dev, __be32 *attr, - u32 aspace, u32 cycle, u32 dwidth) -{ - u32 val; - - val = be32_to_cpu(*attr); - - /* Setup 2eSST speeds */ - switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) { - case VME_2eSST160: - val |= TSI148_LCSR_DSAT_2eSSTM_160; - break; - case VME_2eSST267: - val |= TSI148_LCSR_DSAT_2eSSTM_267; - break; - case VME_2eSST320: - val |= TSI148_LCSR_DSAT_2eSSTM_320; - break; - } - - /* Setup cycle types */ - if (cycle & VME_SCT) - val |= TSI148_LCSR_DSAT_TM_SCT; - - if (cycle & VME_BLT) - val |= TSI148_LCSR_DSAT_TM_BLT; - - if (cycle & VME_MBLT) - val |= TSI148_LCSR_DSAT_TM_MBLT; - - if (cycle & VME_2eVME) - val |= TSI148_LCSR_DSAT_TM_2eVME; - - if (cycle & VME_2eSST) - val |= TSI148_LCSR_DSAT_TM_2eSST; - - if (cycle & VME_2eSSTB) { - dev_err(dev, "Currently not setting Broadcast Select " - "Registers\n"); - val |= TSI148_LCSR_DSAT_TM_2eSSTB; - } - - /* Setup data width */ - switch (dwidth) { - case VME_D16: - val |= TSI148_LCSR_DSAT_DBW_16; - break; - case VME_D32: - val |= TSI148_LCSR_DSAT_DBW_32; - break; - default: - dev_err(dev, "Invalid data width\n"); - return -EINVAL; - } - - /* Setup address space */ - switch (aspace) { - case VME_A16: - val |= TSI148_LCSR_DSAT_AMODE_A16; - break; - case VME_A24: - val |= TSI148_LCSR_DSAT_AMODE_A24; - break; - case VME_A32: - val |= TSI148_LCSR_DSAT_AMODE_A32; - break; - case VME_A64: - val |= TSI148_LCSR_DSAT_AMODE_A64; - break; - case VME_CRCSR: - val |= TSI148_LCSR_DSAT_AMODE_CRCSR; - break; - case VME_USER1: - val |= TSI148_LCSR_DSAT_AMODE_USER1; - break; - case VME_USER2: - val |= TSI148_LCSR_DSAT_AMODE_USER2; - break; - case VME_USER3: - val |= TSI148_LCSR_DSAT_AMODE_USER3; - break; - case VME_USER4: - val |= TSI148_LCSR_DSAT_AMODE_USER4; - break; - default: - dev_err(dev, "Invalid address space\n"); - return -EINVAL; - break; - } - - if (cycle & VME_SUPER) - val |= TSI148_LCSR_DSAT_SUP; - if (cycle & VME_PROG) - val |= TSI148_LCSR_DSAT_PGM; - - *attr = cpu_to_be32(val); - - return 0; -} - -static int tsi148_dma_set_vme_dest_attributes(struct device *dev, __be32 *attr, - u32 aspace, u32 cycle, u32 dwidth) -{ - u32 val; - - val = be32_to_cpu(*attr); - - /* Setup 2eSST speeds */ - switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) { - case VME_2eSST160: - val |= TSI148_LCSR_DDAT_2eSSTM_160; - break; - case VME_2eSST267: - val |= TSI148_LCSR_DDAT_2eSSTM_267; - break; - case VME_2eSST320: - val |= TSI148_LCSR_DDAT_2eSSTM_320; - break; - } - - /* Setup cycle types */ - if (cycle & VME_SCT) - val |= TSI148_LCSR_DDAT_TM_SCT; - - if (cycle & VME_BLT) - val |= TSI148_LCSR_DDAT_TM_BLT; - - if (cycle & VME_MBLT) - val |= TSI148_LCSR_DDAT_TM_MBLT; - - if (cycle & VME_2eVME) - val |= TSI148_LCSR_DDAT_TM_2eVME; - - if (cycle & VME_2eSST) - val |= TSI148_LCSR_DDAT_TM_2eSST; - - if (cycle & VME_2eSSTB) { - dev_err(dev, "Currently not setting Broadcast Select " - "Registers\n"); - val |= TSI148_LCSR_DDAT_TM_2eSSTB; - } - - /* Setup data width */ - switch (dwidth) { - case VME_D16: - val |= TSI148_LCSR_DDAT_DBW_16; - break; - case VME_D32: - val |= TSI148_LCSR_DDAT_DBW_32; - break; - default: - dev_err(dev, "Invalid data width\n"); - return -EINVAL; - } - - /* Setup address space */ - switch (aspace) { - case VME_A16: - val |= TSI148_LCSR_DDAT_AMODE_A16; - break; - case VME_A24: - val |= TSI148_LCSR_DDAT_AMODE_A24; - break; - case VME_A32: - val |= TSI148_LCSR_DDAT_AMODE_A32; - break; - case VME_A64: - val |= TSI148_LCSR_DDAT_AMODE_A64; - break; - case VME_CRCSR: - val |= TSI148_LCSR_DDAT_AMODE_CRCSR; - break; - case VME_USER1: - val |= TSI148_LCSR_DDAT_AMODE_USER1; - break; - case VME_USER2: - val |= TSI148_LCSR_DDAT_AMODE_USER2; - break; - case VME_USER3: - val |= TSI148_LCSR_DDAT_AMODE_USER3; - break; - case VME_USER4: - val |= TSI148_LCSR_DDAT_AMODE_USER4; - break; - default: - dev_err(dev, "Invalid address space\n"); - return -EINVAL; - break; - } - - if (cycle & VME_SUPER) - val |= TSI148_LCSR_DDAT_SUP; - if (cycle & VME_PROG) - val |= TSI148_LCSR_DDAT_PGM; - - *attr = cpu_to_be32(val); - - return 0; -} - -/* - * Add a link list descriptor to the list - * - * Note: DMA engine expects the DMA descriptor to be big endian. - */ -static int tsi148_dma_list_add(struct vme_dma_list *list, - struct vme_dma_attr *src, struct vme_dma_attr *dest, size_t count) -{ - struct tsi148_dma_entry *entry, *prev; - u32 address_high, address_low, val; - struct vme_dma_pattern *pattern_attr; - struct vme_dma_pci *pci_attr; - struct vme_dma_vme *vme_attr; - int retval = 0; - struct vme_bridge *tsi148_bridge; - - tsi148_bridge = list->parent->parent; - - /* Descriptor must be aligned on 64-bit boundaries */ - entry = kmalloc(sizeof(struct tsi148_dma_entry), GFP_KERNEL); - if (entry == NULL) { - dev_err(tsi148_bridge->parent, "Failed to allocate memory for " - "dma resource structure\n"); - retval = -ENOMEM; - goto err_mem; - } - - /* Test descriptor alignment */ - if ((unsigned long)&entry->descriptor & 0x7) { - dev_err(tsi148_bridge->parent, "Descriptor not aligned to 8 " - "byte boundary as required: %p\n", - &entry->descriptor); - retval = -EINVAL; - goto err_align; - } - - /* Given we are going to fill out the structure, we probably don't - * need to zero it, but better safe than sorry for now. - */ - memset(&entry->descriptor, 0, sizeof(struct tsi148_dma_descriptor)); - - /* Fill out source part */ - switch (src->type) { - case VME_DMA_PATTERN: - pattern_attr = src->private; - - entry->descriptor.dsal = cpu_to_be32(pattern_attr->pattern); - - val = TSI148_LCSR_DSAT_TYP_PAT; - - /* Default behaviour is 32 bit pattern */ - if (pattern_attr->type & VME_DMA_PATTERN_BYTE) - val |= TSI148_LCSR_DSAT_PSZ; - - /* It seems that the default behaviour is to increment */ - if ((pattern_attr->type & VME_DMA_PATTERN_INCREMENT) == 0) - val |= TSI148_LCSR_DSAT_NIN; - entry->descriptor.dsat = cpu_to_be32(val); - break; - case VME_DMA_PCI: - pci_attr = src->private; - - reg_split((unsigned long long)pci_attr->address, &address_high, - &address_low); - entry->descriptor.dsau = cpu_to_be32(address_high); - entry->descriptor.dsal = cpu_to_be32(address_low); - entry->descriptor.dsat = cpu_to_be32(TSI148_LCSR_DSAT_TYP_PCI); - break; - case VME_DMA_VME: - vme_attr = src->private; - - reg_split((unsigned long long)vme_attr->address, &address_high, - &address_low); - entry->descriptor.dsau = cpu_to_be32(address_high); - entry->descriptor.dsal = cpu_to_be32(address_low); - entry->descriptor.dsat = cpu_to_be32(TSI148_LCSR_DSAT_TYP_VME); - - retval = tsi148_dma_set_vme_src_attributes( - tsi148_bridge->parent, &entry->descriptor.dsat, - vme_attr->aspace, vme_attr->cycle, vme_attr->dwidth); - if (retval < 0) - goto err_source; - break; - default: - dev_err(tsi148_bridge->parent, "Invalid source type\n"); - retval = -EINVAL; - goto err_source; - break; - } - - /* Assume last link - this will be over-written by adding another */ - entry->descriptor.dnlau = cpu_to_be32(0); - entry->descriptor.dnlal = cpu_to_be32(TSI148_LCSR_DNLAL_LLA); - - /* Fill out destination part */ - switch (dest->type) { - case VME_DMA_PCI: - pci_attr = dest->private; - - reg_split((unsigned long long)pci_attr->address, &address_high, - &address_low); - entry->descriptor.ddau = cpu_to_be32(address_high); - entry->descriptor.ddal = cpu_to_be32(address_low); - entry->descriptor.ddat = cpu_to_be32(TSI148_LCSR_DDAT_TYP_PCI); - break; - case VME_DMA_VME: - vme_attr = dest->private; - - reg_split((unsigned long long)vme_attr->address, &address_high, - &address_low); - entry->descriptor.ddau = cpu_to_be32(address_high); - entry->descriptor.ddal = cpu_to_be32(address_low); - entry->descriptor.ddat = cpu_to_be32(TSI148_LCSR_DDAT_TYP_VME); - - retval = tsi148_dma_set_vme_dest_attributes( - tsi148_bridge->parent, &entry->descriptor.ddat, - vme_attr->aspace, vme_attr->cycle, vme_attr->dwidth); - if (retval < 0) - goto err_dest; - break; - default: - dev_err(tsi148_bridge->parent, "Invalid destination type\n"); - retval = -EINVAL; - goto err_dest; - break; - } - - /* Fill out count */ - entry->descriptor.dcnt = cpu_to_be32((u32)count); - - /* Add to list */ - list_add_tail(&entry->list, &list->entries); - - /* Fill out previous descriptors "Next Address" */ - if (entry->list.prev != &list->entries) { - prev = list_entry(entry->list.prev, struct tsi148_dma_entry, - list); - /* We need the bus address for the pointer */ - entry->dma_handle = dma_map_single(tsi148_bridge->parent, - &entry->descriptor, - sizeof(struct tsi148_dma_descriptor), DMA_TO_DEVICE); - - reg_split((unsigned long long)entry->dma_handle, &address_high, - &address_low); - entry->descriptor.dnlau = cpu_to_be32(address_high); - entry->descriptor.dnlal = cpu_to_be32(address_low); - - } - - return 0; - -err_dest: -err_source: -err_align: - kfree(entry); -err_mem: - return retval; -} - -/* - * Check to see if the provided DMA channel is busy. - */ -static int tsi148_dma_busy(struct vme_bridge *tsi148_bridge, int channel) -{ - u32 tmp; - struct tsi148_driver *bridge; - - bridge = tsi148_bridge->driver_priv; - - tmp = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] + - TSI148_LCSR_OFFSET_DSTA); - - if (tmp & TSI148_LCSR_DSTA_BSY) - return 0; - else - return 1; - -} - -/* - * Execute a previously generated link list - * - * XXX Need to provide control register configuration. - */ -static int tsi148_dma_list_exec(struct vme_dma_list *list) -{ - struct vme_dma_resource *ctrlr; - int channel, retval = 0; - struct tsi148_dma_entry *entry; - u32 bus_addr_high, bus_addr_low; - u32 val, dctlreg = 0; - struct vme_bridge *tsi148_bridge; - struct tsi148_driver *bridge; - - ctrlr = list->parent; - - tsi148_bridge = ctrlr->parent; - - bridge = tsi148_bridge->driver_priv; - - mutex_lock(&ctrlr->mtx); - - channel = ctrlr->number; - - if (!list_empty(&ctrlr->running)) { - /* - * XXX We have an active DMA transfer and currently haven't - * sorted out the mechanism for "pending" DMA transfers. - * Return busy. - */ - /* Need to add to pending here */ - mutex_unlock(&ctrlr->mtx); - return -EBUSY; - } else { - list_add(&list->list, &ctrlr->running); - } - - /* Get first bus address and write into registers */ - entry = list_first_entry(&list->entries, struct tsi148_dma_entry, - list); - - entry->dma_handle = dma_map_single(tsi148_bridge->parent, - &entry->descriptor, - sizeof(struct tsi148_dma_descriptor), DMA_TO_DEVICE); - - mutex_unlock(&ctrlr->mtx); - - reg_split(entry->dma_handle, &bus_addr_high, &bus_addr_low); - - iowrite32be(bus_addr_high, bridge->base + - TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAU); - iowrite32be(bus_addr_low, bridge->base + - TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAL); - - dctlreg = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] + - TSI148_LCSR_OFFSET_DCTL); - - /* Start the operation */ - iowrite32be(dctlreg | TSI148_LCSR_DCTL_DGO, bridge->base + - TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL); - - wait_event_interruptible(bridge->dma_queue[channel], - tsi148_dma_busy(ctrlr->parent, channel)); - - /* - * Read status register, this register is valid until we kick off a - * new transfer. - */ - val = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] + - TSI148_LCSR_OFFSET_DSTA); - - if (val & TSI148_LCSR_DSTA_VBE) { - dev_err(tsi148_bridge->parent, "DMA Error. DSTA=%08X\n", val); - retval = -EIO; - } - - /* Remove list from running list */ - mutex_lock(&ctrlr->mtx); - list_del(&list->list); - mutex_unlock(&ctrlr->mtx); - - return retval; -} - -/* - * Clean up a previously generated link list - * - * We have a separate function, don't assume that the chain can't be reused. - */ -static int tsi148_dma_list_empty(struct vme_dma_list *list) -{ - struct list_head *pos, *temp; - struct tsi148_dma_entry *entry; - - struct vme_bridge *tsi148_bridge = list->parent->parent; - - /* detach and free each entry */ - list_for_each_safe(pos, temp, &list->entries) { - list_del(pos); - entry = list_entry(pos, struct tsi148_dma_entry, list); - - dma_unmap_single(tsi148_bridge->parent, entry->dma_handle, - sizeof(struct tsi148_dma_descriptor), DMA_TO_DEVICE); - kfree(entry); - } - - return 0; -} - -/* - * All 4 location monitors reside at the same base - this is therefore a - * system wide configuration. - * - * This does not enable the LM monitor - that should be done when the first - * callback is attached and disabled when the last callback is removed. - */ -static int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, - u32 aspace, u32 cycle) -{ - u32 lm_base_high, lm_base_low, lm_ctl = 0; - int i; - struct vme_bridge *tsi148_bridge; - struct tsi148_driver *bridge; - - tsi148_bridge = lm->parent; - - bridge = tsi148_bridge->driver_priv; - - mutex_lock(&lm->mtx); - - /* If we already have a callback attached, we can't move it! */ - for (i = 0; i < lm->monitors; i++) { - if (bridge->lm_callback[i] != NULL) { - mutex_unlock(&lm->mtx); - dev_err(tsi148_bridge->parent, "Location monitor " - "callback attached, can't reset\n"); - return -EBUSY; - } - } - - switch (aspace) { - case VME_A16: - lm_ctl |= TSI148_LCSR_LMAT_AS_A16; - break; - case VME_A24: - lm_ctl |= TSI148_LCSR_LMAT_AS_A24; - break; - case VME_A32: - lm_ctl |= TSI148_LCSR_LMAT_AS_A32; - break; - case VME_A64: - lm_ctl |= TSI148_LCSR_LMAT_AS_A64; - break; - default: - mutex_unlock(&lm->mtx); - dev_err(tsi148_bridge->parent, "Invalid address space\n"); - return -EINVAL; - break; - } - - if (cycle & VME_SUPER) - lm_ctl |= TSI148_LCSR_LMAT_SUPR ; - if (cycle & VME_USER) - lm_ctl |= TSI148_LCSR_LMAT_NPRIV; - if (cycle & VME_PROG) - lm_ctl |= TSI148_LCSR_LMAT_PGM; - if (cycle & VME_DATA) - lm_ctl |= TSI148_LCSR_LMAT_DATA; - - reg_split(lm_base, &lm_base_high, &lm_base_low); - - iowrite32be(lm_base_high, bridge->base + TSI148_LCSR_LMBAU); - iowrite32be(lm_base_low, bridge->base + TSI148_LCSR_LMBAL); - iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT); - - mutex_unlock(&lm->mtx); - - return 0; -} - -/* Get configuration of the callback monitor and return whether it is enabled - * or disabled. - */ -static int tsi148_lm_get(struct vme_lm_resource *lm, - unsigned long long *lm_base, u32 *aspace, u32 *cycle) -{ - u32 lm_base_high, lm_base_low, lm_ctl, enabled = 0; - struct tsi148_driver *bridge; - - bridge = lm->parent->driver_priv; - - mutex_lock(&lm->mtx); - - lm_base_high = ioread32be(bridge->base + TSI148_LCSR_LMBAU); - lm_base_low = ioread32be(bridge->base + TSI148_LCSR_LMBAL); - lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT); - - reg_join(lm_base_high, lm_base_low, lm_base); - - if (lm_ctl & TSI148_LCSR_LMAT_EN) - enabled = 1; - - if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A16) - *aspace |= VME_A16; - - if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A24) - *aspace |= VME_A24; - - if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A32) - *aspace |= VME_A32; - - if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A64) - *aspace |= VME_A64; - - - if (lm_ctl & TSI148_LCSR_LMAT_SUPR) - *cycle |= VME_SUPER; - if (lm_ctl & TSI148_LCSR_LMAT_NPRIV) - *cycle |= VME_USER; - if (lm_ctl & TSI148_LCSR_LMAT_PGM) - *cycle |= VME_PROG; - if (lm_ctl & TSI148_LCSR_LMAT_DATA) - *cycle |= VME_DATA; - - mutex_unlock(&lm->mtx); - - return enabled; -} - -/* - * Attach a callback to a specific location monitor. - * - * Callback will be passed the monitor triggered. - */ -static int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor, - void (*callback)(int)) -{ - u32 lm_ctl, tmp; - struct vme_bridge *tsi148_bridge; - struct tsi148_driver *bridge; - - tsi148_bridge = lm->parent; - - bridge = tsi148_bridge->driver_priv; - - mutex_lock(&lm->mtx); - - /* Ensure that the location monitor is configured - need PGM or DATA */ - lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT); - if ((lm_ctl & (TSI148_LCSR_LMAT_PGM | TSI148_LCSR_LMAT_DATA)) == 0) { - mutex_unlock(&lm->mtx); - dev_err(tsi148_bridge->parent, "Location monitor not properly " - "configured\n"); - return -EINVAL; - } - - /* Check that a callback isn't already attached */ - if (bridge->lm_callback[monitor] != NULL) { - mutex_unlock(&lm->mtx); - dev_err(tsi148_bridge->parent, "Existing callback attached\n"); - return -EBUSY; - } - - /* Attach callback */ - bridge->lm_callback[monitor] = callback; - - /* Enable Location Monitor interrupt */ - tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN); - tmp |= TSI148_LCSR_INTEN_LMEN[monitor]; - iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN); - - tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO); - tmp |= TSI148_LCSR_INTEO_LMEO[monitor]; - iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO); - - /* Ensure that global Location Monitor Enable set */ - if ((lm_ctl & TSI148_LCSR_LMAT_EN) == 0) { - lm_ctl |= TSI148_LCSR_LMAT_EN; - iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT); - } - - mutex_unlock(&lm->mtx); - - return 0; -} - -/* - * Detach a callback function forn a specific location monitor. - */ -static int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor) -{ - u32 lm_en, tmp; - struct tsi148_driver *bridge; - - bridge = lm->parent->driver_priv; - - mutex_lock(&lm->mtx); - - /* Disable Location Monitor and ensure previous interrupts are clear */ - lm_en = ioread32be(bridge->base + TSI148_LCSR_INTEN); - lm_en &= ~TSI148_LCSR_INTEN_LMEN[monitor]; - iowrite32be(lm_en, bridge->base + TSI148_LCSR_INTEN); - - tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO); - tmp &= ~TSI148_LCSR_INTEO_LMEO[monitor]; - iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO); - - iowrite32be(TSI148_LCSR_INTC_LMC[monitor], - bridge->base + TSI148_LCSR_INTC); - - /* Detach callback */ - bridge->lm_callback[monitor] = NULL; - - /* If all location monitors disabled, disable global Location Monitor */ - if ((lm_en & (TSI148_LCSR_INTS_LM0S | TSI148_LCSR_INTS_LM1S | - TSI148_LCSR_INTS_LM2S | TSI148_LCSR_INTS_LM3S)) == 0) { - tmp = ioread32be(bridge->base + TSI148_LCSR_LMAT); - tmp &= ~TSI148_LCSR_LMAT_EN; - iowrite32be(tmp, bridge->base + TSI148_LCSR_LMAT); - } - - mutex_unlock(&lm->mtx); - - return 0; -} - -/* - * Determine Geographical Addressing - */ -static int tsi148_slot_get(struct vme_bridge *tsi148_bridge) -{ - u32 slot = 0; - struct tsi148_driver *bridge; - - bridge = tsi148_bridge->driver_priv; - - if (!geoid) { - slot = ioread32be(bridge->base + TSI148_LCSR_VSTAT); - slot = slot & TSI148_LCSR_VSTAT_GA_M; - } else - slot = geoid; - - return (int)slot; -} - -void *tsi148_alloc_consistent(struct device *parent, size_t size, - dma_addr_t *dma) -{ - struct pci_dev *pdev; - - /* Find pci_dev container of dev */ - pdev = container_of(parent, struct pci_dev, dev); - - return pci_alloc_consistent(pdev, size, dma); -} - -void tsi148_free_consistent(struct device *parent, size_t size, void *vaddr, - dma_addr_t dma) -{ - struct pci_dev *pdev; - - /* Find pci_dev container of dev */ - pdev = container_of(parent, struct pci_dev, dev); - - pci_free_consistent(pdev, size, vaddr, dma); -} - -static int __init tsi148_init(void) -{ - return pci_register_driver(&tsi148_driver); -} - -/* - * Configure CR/CSR space - * - * Access to the CR/CSR can be configured at power-up. The location of the - * CR/CSR registers in the CR/CSR address space is determined by the boards - * Auto-ID or Geographic address. This function ensures that the window is - * enabled at an offset consistent with the boards geopgraphic address. - * - * Each board has a 512kB window, with the highest 4kB being used for the - * boards registers, this means there is a fix length 508kB window which must - * be mapped onto PCI memory. - */ -static int tsi148_crcsr_init(struct vme_bridge *tsi148_bridge, - struct pci_dev *pdev) -{ - u32 cbar, crat, vstat; - u32 crcsr_bus_high, crcsr_bus_low; - int retval; - struct tsi148_driver *bridge; - - bridge = tsi148_bridge->driver_priv; - - /* Allocate mem for CR/CSR image */ - bridge->crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE, - &bridge->crcsr_bus); - if (bridge->crcsr_kernel == NULL) { - dev_err(tsi148_bridge->parent, "Failed to allocate memory for " - "CR/CSR image\n"); - return -ENOMEM; - } - - memset(bridge->crcsr_kernel, 0, VME_CRCSR_BUF_SIZE); - - reg_split(bridge->crcsr_bus, &crcsr_bus_high, &crcsr_bus_low); - - iowrite32be(crcsr_bus_high, bridge->base + TSI148_LCSR_CROU); - iowrite32be(crcsr_bus_low, bridge->base + TSI148_LCSR_CROL); - - /* Ensure that the CR/CSR is configured at the correct offset */ - cbar = ioread32be(bridge->base + TSI148_CBAR); - cbar = (cbar & TSI148_CRCSR_CBAR_M)>>3; - - vstat = tsi148_slot_get(tsi148_bridge); - - if (cbar != vstat) { - cbar = vstat; - dev_info(tsi148_bridge->parent, "Setting CR/CSR offset\n"); - iowrite32be(cbar<<3, bridge->base + TSI148_CBAR); - } - dev_info(tsi148_bridge->parent, "CR/CSR Offset: %d\n", cbar); - - crat = ioread32be(bridge->base + TSI148_LCSR_CRAT); - if (crat & TSI148_LCSR_CRAT_EN) { - dev_info(tsi148_bridge->parent, "Enabling CR/CSR space\n"); - iowrite32be(crat | TSI148_LCSR_CRAT_EN, - bridge->base + TSI148_LCSR_CRAT); - } else - dev_info(tsi148_bridge->parent, "CR/CSR already enabled\n"); - - /* If we want flushed, error-checked writes, set up a window - * over the CR/CSR registers. We read from here to safely flush - * through VME writes. - */ - if (err_chk) { - retval = tsi148_master_set(bridge->flush_image, 1, - (vstat * 0x80000), 0x80000, VME_CRCSR, VME_SCT, - VME_D16); - if (retval) - dev_err(tsi148_bridge->parent, "Configuring flush image" - " failed\n"); - } - - return 0; - -} - -static void tsi148_crcsr_exit(struct vme_bridge *tsi148_bridge, - struct pci_dev *pdev) -{ - u32 crat; - struct tsi148_driver *bridge; - - bridge = tsi148_bridge->driver_priv; - - /* Turn off CR/CSR space */ - crat = ioread32be(bridge->base + TSI148_LCSR_CRAT); - iowrite32be(crat & ~TSI148_LCSR_CRAT_EN, - bridge->base + TSI148_LCSR_CRAT); - - /* Free image */ - iowrite32be(0, bridge->base + TSI148_LCSR_CROU); - iowrite32be(0, bridge->base + TSI148_LCSR_CROL); - - pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, bridge->crcsr_kernel, - bridge->crcsr_bus); -} - -static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) -{ - int retval, i, master_num; - u32 data; - struct list_head *pos = NULL; - struct vme_bridge *tsi148_bridge; - struct tsi148_driver *tsi148_device; - struct vme_master_resource *master_image; - struct vme_slave_resource *slave_image; - struct vme_dma_resource *dma_ctrlr; - struct vme_lm_resource *lm; - - /* If we want to support more than one of each bridge, we need to - * dynamically generate this so we get one per device - */ - tsi148_bridge = kzalloc(sizeof(struct vme_bridge), GFP_KERNEL); - if (tsi148_bridge == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for device " - "structure\n"); - retval = -ENOMEM; - goto err_struct; - } - - tsi148_device = kzalloc(sizeof(struct tsi148_driver), GFP_KERNEL); - if (tsi148_device == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for device " - "structure\n"); - retval = -ENOMEM; - goto err_driver; - } - - tsi148_bridge->driver_priv = tsi148_device; - - /* Enable the device */ - retval = pci_enable_device(pdev); - if (retval) { - dev_err(&pdev->dev, "Unable to enable device\n"); - goto err_enable; - } - - /* Map Registers */ - retval = pci_request_regions(pdev, driver_name); - if (retval) { - dev_err(&pdev->dev, "Unable to reserve resources\n"); - goto err_resource; - } - - /* map registers in BAR 0 */ - tsi148_device->base = ioremap_nocache(pci_resource_start(pdev, 0), - 4096); - if (!tsi148_device->base) { - dev_err(&pdev->dev, "Unable to remap CRG region\n"); - retval = -EIO; - goto err_remap; - } - - /* Check to see if the mapping worked out */ - data = ioread32(tsi148_device->base + TSI148_PCFS_ID) & 0x0000FFFF; - if (data != PCI_VENDOR_ID_TUNDRA) { - dev_err(&pdev->dev, "CRG region check failed\n"); - retval = -EIO; - goto err_test; - } - - /* Initialize wait queues & mutual exclusion flags */ - init_waitqueue_head(&tsi148_device->dma_queue[0]); - init_waitqueue_head(&tsi148_device->dma_queue[1]); - init_waitqueue_head(&tsi148_device->iack_queue); - mutex_init(&tsi148_device->vme_int); - mutex_init(&tsi148_device->vme_rmw); - - tsi148_bridge->parent = &pdev->dev; - strcpy(tsi148_bridge->name, driver_name); - - /* Setup IRQ */ - retval = tsi148_irq_init(tsi148_bridge); - if (retval != 0) { - dev_err(&pdev->dev, "Chip Initialization failed.\n"); - goto err_irq; - } - - /* If we are going to flush writes, we need to read from the VME bus. - * We need to do this safely, thus we read the devices own CR/CSR - * register. To do this we must set up a window in CR/CSR space and - * hence have one less master window resource available. - */ - master_num = TSI148_MAX_MASTER; - if (err_chk) { - master_num--; - - tsi148_device->flush_image = - kmalloc(sizeof(struct vme_master_resource), GFP_KERNEL); - if (tsi148_device->flush_image == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for " - "flush resource structure\n"); - retval = -ENOMEM; - goto err_master; - } - tsi148_device->flush_image->parent = tsi148_bridge; - spin_lock_init(&tsi148_device->flush_image->lock); - tsi148_device->flush_image->locked = 1; - tsi148_device->flush_image->number = master_num; - tsi148_device->flush_image->address_attr = VME_A16 | VME_A24 | - VME_A32 | VME_A64; - tsi148_device->flush_image->cycle_attr = VME_SCT | VME_BLT | - VME_MBLT | VME_2eVME | VME_2eSST | VME_2eSSTB | - VME_2eSST160 | VME_2eSST267 | VME_2eSST320 | VME_SUPER | - VME_USER | VME_PROG | VME_DATA; - tsi148_device->flush_image->width_attr = VME_D16 | VME_D32; - memset(&tsi148_device->flush_image->bus_resource, 0, - sizeof(struct resource)); - tsi148_device->flush_image->kern_base = NULL; - } - - /* Add master windows to list */ - INIT_LIST_HEAD(&tsi148_bridge->master_resources); - for (i = 0; i < master_num; i++) { - master_image = kmalloc(sizeof(struct vme_master_resource), - GFP_KERNEL); - if (master_image == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for " - "master resource structure\n"); - retval = -ENOMEM; - goto err_master; - } - master_image->parent = tsi148_bridge; - spin_lock_init(&master_image->lock); - master_image->locked = 0; - master_image->number = i; - master_image->address_attr = VME_A16 | VME_A24 | VME_A32 | - VME_A64; - master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | - VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 | - VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER | - VME_PROG | VME_DATA; - master_image->width_attr = VME_D16 | VME_D32; - memset(&master_image->bus_resource, 0, - sizeof(struct resource)); - master_image->kern_base = NULL; - list_add_tail(&master_image->list, - &tsi148_bridge->master_resources); - } - - /* Add slave windows to list */ - INIT_LIST_HEAD(&tsi148_bridge->slave_resources); - for (i = 0; i < TSI148_MAX_SLAVE; i++) { - slave_image = kmalloc(sizeof(struct vme_slave_resource), - GFP_KERNEL); - if (slave_image == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for " - "slave resource structure\n"); - retval = -ENOMEM; - goto err_slave; - } - slave_image->parent = tsi148_bridge; - mutex_init(&slave_image->mtx); - slave_image->locked = 0; - slave_image->number = i; - slave_image->address_attr = VME_A16 | VME_A24 | VME_A32 | - VME_A64 | VME_CRCSR | VME_USER1 | VME_USER2 | - VME_USER3 | VME_USER4; - slave_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | - VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 | - VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER | - VME_PROG | VME_DATA; - list_add_tail(&slave_image->list, - &tsi148_bridge->slave_resources); - } - - /* Add dma engines to list */ - INIT_LIST_HEAD(&tsi148_bridge->dma_resources); - for (i = 0; i < TSI148_MAX_DMA; i++) { - dma_ctrlr = kmalloc(sizeof(struct vme_dma_resource), - GFP_KERNEL); - if (dma_ctrlr == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for " - "dma resource structure\n"); - retval = -ENOMEM; - goto err_dma; - } - dma_ctrlr->parent = tsi148_bridge; - mutex_init(&dma_ctrlr->mtx); - dma_ctrlr->locked = 0; - dma_ctrlr->number = i; - dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM | - VME_DMA_MEM_TO_VME | VME_DMA_VME_TO_VME | - VME_DMA_MEM_TO_MEM | VME_DMA_PATTERN_TO_VME | - VME_DMA_PATTERN_TO_MEM; - INIT_LIST_HEAD(&dma_ctrlr->pending); - INIT_LIST_HEAD(&dma_ctrlr->running); - list_add_tail(&dma_ctrlr->list, - &tsi148_bridge->dma_resources); - } - - /* Add location monitor to list */ - INIT_LIST_HEAD(&tsi148_bridge->lm_resources); - lm = kmalloc(sizeof(struct vme_lm_resource), GFP_KERNEL); - if (lm == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for " - "location monitor resource structure\n"); - retval = -ENOMEM; - goto err_lm; - } - lm->parent = tsi148_bridge; - mutex_init(&lm->mtx); - lm->locked = 0; - lm->number = 1; - lm->monitors = 4; - list_add_tail(&lm->list, &tsi148_bridge->lm_resources); - - tsi148_bridge->slave_get = tsi148_slave_get; - tsi148_bridge->slave_set = tsi148_slave_set; - tsi148_bridge->master_get = tsi148_master_get; - tsi148_bridge->master_set = tsi148_master_set; - tsi148_bridge->master_read = tsi148_master_read; - tsi148_bridge->master_write = tsi148_master_write; - tsi148_bridge->master_rmw = tsi148_master_rmw; - tsi148_bridge->dma_list_add = tsi148_dma_list_add; - tsi148_bridge->dma_list_exec = tsi148_dma_list_exec; - tsi148_bridge->dma_list_empty = tsi148_dma_list_empty; - tsi148_bridge->irq_set = tsi148_irq_set; - tsi148_bridge->irq_generate = tsi148_irq_generate; - tsi148_bridge->lm_set = tsi148_lm_set; - tsi148_bridge->lm_get = tsi148_lm_get; - tsi148_bridge->lm_attach = tsi148_lm_attach; - tsi148_bridge->lm_detach = tsi148_lm_detach; - tsi148_bridge->slot_get = tsi148_slot_get; - tsi148_bridge->alloc_consistent = tsi148_alloc_consistent; - tsi148_bridge->free_consistent = tsi148_free_consistent; - - data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT); - dev_info(&pdev->dev, "Board is%s the VME system controller\n", - (data & TSI148_LCSR_VSTAT_SCONS) ? "" : " not"); - if (!geoid) - dev_info(&pdev->dev, "VME geographical address is %d\n", - data & TSI148_LCSR_VSTAT_GA_M); - else - dev_info(&pdev->dev, "VME geographical address is set to %d\n", - geoid); - - dev_info(&pdev->dev, "VME Write and flush and error check is %s\n", - err_chk ? "enabled" : "disabled"); - - if (tsi148_crcsr_init(tsi148_bridge, pdev)) { - dev_err(&pdev->dev, "CR/CSR configuration failed.\n"); - goto err_crcsr; - } - - retval = vme_register_bridge(tsi148_bridge); - if (retval != 0) { - dev_err(&pdev->dev, "Chip Registration failed.\n"); - goto err_reg; - } - - pci_set_drvdata(pdev, tsi148_bridge); - - /* Clear VME bus "board fail", and "power-up reset" lines */ - data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT); - data &= ~TSI148_LCSR_VSTAT_BRDFL; - data |= TSI148_LCSR_VSTAT_CPURST; - iowrite32be(data, tsi148_device->base + TSI148_LCSR_VSTAT); - - return 0; - -err_reg: - tsi148_crcsr_exit(tsi148_bridge, pdev); -err_crcsr: -err_lm: - /* resources are stored in link list */ - list_for_each(pos, &tsi148_bridge->lm_resources) { - lm = list_entry(pos, struct vme_lm_resource, list); - list_del(pos); - kfree(lm); - } -err_dma: - /* resources are stored in link list */ - list_for_each(pos, &tsi148_bridge->dma_resources) { - dma_ctrlr = list_entry(pos, struct vme_dma_resource, list); - list_del(pos); - kfree(dma_ctrlr); - } -err_slave: - /* resources are stored in link list */ - list_for_each(pos, &tsi148_bridge->slave_resources) { - slave_image = list_entry(pos, struct vme_slave_resource, list); - list_del(pos); - kfree(slave_image); - } -err_master: - /* resources are stored in link list */ - list_for_each(pos, &tsi148_bridge->master_resources) { - master_image = list_entry(pos, struct vme_master_resource, - list); - list_del(pos); - kfree(master_image); - } - - tsi148_irq_exit(tsi148_bridge, pdev); -err_irq: -err_test: - iounmap(tsi148_device->base); -err_remap: - pci_release_regions(pdev); -err_resource: - pci_disable_device(pdev); -err_enable: - kfree(tsi148_device); -err_driver: - kfree(tsi148_bridge); -err_struct: - return retval; - -} - -static void tsi148_remove(struct pci_dev *pdev) -{ - struct list_head *pos = NULL; - struct list_head *tmplist; - struct vme_master_resource *master_image; - struct vme_slave_resource *slave_image; - struct vme_dma_resource *dma_ctrlr; - int i; - struct tsi148_driver *bridge; - struct vme_bridge *tsi148_bridge = pci_get_drvdata(pdev); - - bridge = tsi148_bridge->driver_priv; - - - dev_dbg(&pdev->dev, "Driver is being unloaded.\n"); - - /* - * Shutdown all inbound and outbound windows. - */ - for (i = 0; i < 8; i++) { - iowrite32be(0, bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITAT); - iowrite32be(0, bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTAT); - } - - /* - * Shutdown Location monitor. - */ - iowrite32be(0, bridge->base + TSI148_LCSR_LMAT); - - /* - * Shutdown CRG map. - */ - iowrite32be(0, bridge->base + TSI148_LCSR_CSRAT); - - /* - * Clear error status. - */ - iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_EDPAT); - iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_VEAT); - iowrite32be(0x07000700, bridge->base + TSI148_LCSR_PSTAT); - - /* - * Remove VIRQ interrupt (if any) - */ - if (ioread32be(bridge->base + TSI148_LCSR_VICR) & 0x800) - iowrite32be(0x8000, bridge->base + TSI148_LCSR_VICR); - - /* - * Map all Interrupts to PCI INTA - */ - iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM1); - iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM2); - - tsi148_irq_exit(tsi148_bridge, pdev); - - vme_unregister_bridge(tsi148_bridge); - - tsi148_crcsr_exit(tsi148_bridge, pdev); - - /* resources are stored in link list */ - list_for_each_safe(pos, tmplist, &tsi148_bridge->dma_resources) { - dma_ctrlr = list_entry(pos, struct vme_dma_resource, list); - list_del(pos); - kfree(dma_ctrlr); - } - - /* resources are stored in link list */ - list_for_each_safe(pos, tmplist, &tsi148_bridge->slave_resources) { - slave_image = list_entry(pos, struct vme_slave_resource, list); - list_del(pos); - kfree(slave_image); - } - - /* resources are stored in link list */ - list_for_each_safe(pos, tmplist, &tsi148_bridge->master_resources) { - master_image = list_entry(pos, struct vme_master_resource, - list); - list_del(pos); - kfree(master_image); - } - - iounmap(bridge->base); - - pci_release_regions(pdev); - - pci_disable_device(pdev); - - kfree(tsi148_bridge->driver_priv); - - kfree(tsi148_bridge); -} - -static void __exit tsi148_exit(void) -{ - pci_unregister_driver(&tsi148_driver); -} - -MODULE_PARM_DESC(err_chk, "Check for VME errors on reads and writes"); -module_param(err_chk, bool, 0); - -MODULE_PARM_DESC(geoid, "Override geographical addressing"); -module_param(geoid, int, 0); - -MODULE_DESCRIPTION("VME driver for the Tundra Tempe VME bridge"); -MODULE_LICENSE("GPL"); - -module_init(tsi148_init); -module_exit(tsi148_exit); diff --git a/drivers/staging/vme/bridges/vme_tsi148.h b/drivers/staging/vme/bridges/vme_tsi148.h deleted file mode 100644 index f5ed143..0000000 --- a/drivers/staging/vme/bridges/vme_tsi148.h +++ /dev/null @@ -1,1410 +0,0 @@ -/* - * tsi148.h - * - * Support for the Tundra TSI148 VME Bridge chip - * - * Author: Tom Armistead - * Updated and maintained by Ajit Prem - * Copyright 2004 Motorola Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef TSI148_H -#define TSI148_H - -#ifndef PCI_VENDOR_ID_TUNDRA -#define PCI_VENDOR_ID_TUNDRA 0x10e3 -#endif - -#ifndef PCI_DEVICE_ID_TUNDRA_TSI148 -#define PCI_DEVICE_ID_TUNDRA_TSI148 0x148 -#endif - -/* - * Define the number of each that the Tsi148 supports. - */ -#define TSI148_MAX_MASTER 8 /* Max Master Windows */ -#define TSI148_MAX_SLAVE 8 /* Max Slave Windows */ -#define TSI148_MAX_DMA 2 /* Max DMA Controllers */ -#define TSI148_MAX_MAILBOX 4 /* Max Mail Box registers */ -#define TSI148_MAX_SEMAPHORE 8 /* Max Semaphores */ - -/* Structure used to hold driver specific information */ -struct tsi148_driver { - void __iomem *base; /* Base Address of device registers */ - wait_queue_head_t dma_queue[2]; - wait_queue_head_t iack_queue; - void (*lm_callback[4])(int); /* Called in interrupt handler */ - void *crcsr_kernel; - dma_addr_t crcsr_bus; - struct vme_master_resource *flush_image; - struct mutex vme_rmw; /* Only one RMW cycle at a time */ - struct mutex vme_int; /* - * Only one VME interrupt can be - * generated at a time, provide locking - */ -}; - -/* - * Layout of a DMAC Linked-List Descriptor - * - * Note: This structure is accessed via the chip and therefore must be - * correctly laid out - It must also be aligned on 64-bit boundaries. - */ -struct tsi148_dma_descriptor { - __be32 dsau; /* Source Address */ - __be32 dsal; - __be32 ddau; /* Destination Address */ - __be32 ddal; - __be32 dsat; /* Source attributes */ - __be32 ddat; /* Destination attributes */ - __be32 dnlau; /* Next link address */ - __be32 dnlal; - __be32 dcnt; /* Byte count */ - __be32 ddbs; /* 2eSST Broadcast select */ -}; - -struct tsi148_dma_entry { - /* - * The descriptor needs to be aligned on a 64-bit boundary, we increase - * the chance of this by putting it first in the structure. - */ - struct tsi148_dma_descriptor descriptor; - struct list_head list; - dma_addr_t dma_handle; -}; - -/* - * TSI148 ASIC register structure overlays and bit field definitions. - * - * Note: Tsi148 Register Group (CRG) consists of the following - * combination of registers: - * PCFS - PCI Configuration Space Registers - * LCSR - Local Control and Status Registers - * GCSR - Global Control and Status Registers - * CR/CSR - Subset of Configuration ROM / - * Control and Status Registers - */ - - -/* - * Command/Status Registers (CRG + $004) - */ -#define TSI148_PCFS_ID 0x0 -#define TSI148_PCFS_CSR 0x4 -#define TSI148_PCFS_CLASS 0x8 -#define TSI148_PCFS_MISC0 0xC -#define TSI148_PCFS_MBARL 0x10 -#define TSI148_PCFS_MBARU 0x14 - -#define TSI148_PCFS_SUBID 0x28 - -#define TSI148_PCFS_CAPP 0x34 - -#define TSI148_PCFS_MISC1 0x3C - -#define TSI148_PCFS_XCAPP 0x40 -#define TSI148_PCFS_XSTAT 0x44 - -/* - * LCSR definitions - */ - -/* - * Outbound Translations - */ -#define TSI148_LCSR_OT0_OTSAU 0x100 -#define TSI148_LCSR_OT0_OTSAL 0x104 -#define TSI148_LCSR_OT0_OTEAU 0x108 -#define TSI148_LCSR_OT0_OTEAL 0x10C -#define TSI148_LCSR_OT0_OTOFU 0x110 -#define TSI148_LCSR_OT0_OTOFL 0x114 -#define TSI148_LCSR_OT0_OTBS 0x118 -#define TSI148_LCSR_OT0_OTAT 0x11C - -#define TSI148_LCSR_OT1_OTSAU 0x120 -#define TSI148_LCSR_OT1_OTSAL 0x124 -#define TSI148_LCSR_OT1_OTEAU 0x128 -#define TSI148_LCSR_OT1_OTEAL 0x12C -#define TSI148_LCSR_OT1_OTOFU 0x130 -#define TSI148_LCSR_OT1_OTOFL 0x134 -#define TSI148_LCSR_OT1_OTBS 0x138 -#define TSI148_LCSR_OT1_OTAT 0x13C - -#define TSI148_LCSR_OT2_OTSAU 0x140 -#define TSI148_LCSR_OT2_OTSAL 0x144 -#define TSI148_LCSR_OT2_OTEAU 0x148 -#define TSI148_LCSR_OT2_OTEAL 0x14C -#define TSI148_LCSR_OT2_OTOFU 0x150 -#define TSI148_LCSR_OT2_OTOFL 0x154 -#define TSI148_LCSR_OT2_OTBS 0x158 -#define TSI148_LCSR_OT2_OTAT 0x15C - -#define TSI148_LCSR_OT3_OTSAU 0x160 -#define TSI148_LCSR_OT3_OTSAL 0x164 -#define TSI148_LCSR_OT3_OTEAU 0x168 -#define TSI148_LCSR_OT3_OTEAL 0x16C -#define TSI148_LCSR_OT3_OTOFU 0x170 -#define TSI148_LCSR_OT3_OTOFL 0x174 -#define TSI148_LCSR_OT3_OTBS 0x178 -#define TSI148_LCSR_OT3_OTAT 0x17C - -#define TSI148_LCSR_OT4_OTSAU 0x180 -#define TSI148_LCSR_OT4_OTSAL 0x184 -#define TSI148_LCSR_OT4_OTEAU 0x188 -#define TSI148_LCSR_OT4_OTEAL 0x18C -#define TSI148_LCSR_OT4_OTOFU 0x190 -#define TSI148_LCSR_OT4_OTOFL 0x194 -#define TSI148_LCSR_OT4_OTBS 0x198 -#define TSI148_LCSR_OT4_OTAT 0x19C - -#define TSI148_LCSR_OT5_OTSAU 0x1A0 -#define TSI148_LCSR_OT5_OTSAL 0x1A4 -#define TSI148_LCSR_OT5_OTEAU 0x1A8 -#define TSI148_LCSR_OT5_OTEAL 0x1AC -#define TSI148_LCSR_OT5_OTOFU 0x1B0 -#define TSI148_LCSR_OT5_OTOFL 0x1B4 -#define TSI148_LCSR_OT5_OTBS 0x1B8 -#define TSI148_LCSR_OT5_OTAT 0x1BC - -#define TSI148_LCSR_OT6_OTSAU 0x1C0 -#define TSI148_LCSR_OT6_OTSAL 0x1C4 -#define TSI148_LCSR_OT6_OTEAU 0x1C8 -#define TSI148_LCSR_OT6_OTEAL 0x1CC -#define TSI148_LCSR_OT6_OTOFU 0x1D0 -#define TSI148_LCSR_OT6_OTOFL 0x1D4 -#define TSI148_LCSR_OT6_OTBS 0x1D8 -#define TSI148_LCSR_OT6_OTAT 0x1DC - -#define TSI148_LCSR_OT7_OTSAU 0x1E0 -#define TSI148_LCSR_OT7_OTSAL 0x1E4 -#define TSI148_LCSR_OT7_OTEAU 0x1E8 -#define TSI148_LCSR_OT7_OTEAL 0x1EC -#define TSI148_LCSR_OT7_OTOFU 0x1F0 -#define TSI148_LCSR_OT7_OTOFL 0x1F4 -#define TSI148_LCSR_OT7_OTBS 0x1F8 -#define TSI148_LCSR_OT7_OTAT 0x1FC - -#define TSI148_LCSR_OT0 0x100 -#define TSI148_LCSR_OT1 0x120 -#define TSI148_LCSR_OT2 0x140 -#define TSI148_LCSR_OT3 0x160 -#define TSI148_LCSR_OT4 0x180 -#define TSI148_LCSR_OT5 0x1A0 -#define TSI148_LCSR_OT6 0x1C0 -#define TSI148_LCSR_OT7 0x1E0 - -static const int TSI148_LCSR_OT[8] = { TSI148_LCSR_OT0, TSI148_LCSR_OT1, - TSI148_LCSR_OT2, TSI148_LCSR_OT3, - TSI148_LCSR_OT4, TSI148_LCSR_OT5, - TSI148_LCSR_OT6, TSI148_LCSR_OT7 }; - -#define TSI148_LCSR_OFFSET_OTSAU 0x0 -#define TSI148_LCSR_OFFSET_OTSAL 0x4 -#define TSI148_LCSR_OFFSET_OTEAU 0x8 -#define TSI148_LCSR_OFFSET_OTEAL 0xC -#define TSI148_LCSR_OFFSET_OTOFU 0x10 -#define TSI148_LCSR_OFFSET_OTOFL 0x14 -#define TSI148_LCSR_OFFSET_OTBS 0x18 -#define TSI148_LCSR_OFFSET_OTAT 0x1C - -/* - * VMEbus interrupt ack - * offset 200 - */ -#define TSI148_LCSR_VIACK1 0x204 -#define TSI148_LCSR_VIACK2 0x208 -#define TSI148_LCSR_VIACK3 0x20C -#define TSI148_LCSR_VIACK4 0x210 -#define TSI148_LCSR_VIACK5 0x214 -#define TSI148_LCSR_VIACK6 0x218 -#define TSI148_LCSR_VIACK7 0x21C - -static const int TSI148_LCSR_VIACK[8] = { 0, TSI148_LCSR_VIACK1, - TSI148_LCSR_VIACK2, TSI148_LCSR_VIACK3, - TSI148_LCSR_VIACK4, TSI148_LCSR_VIACK5, - TSI148_LCSR_VIACK6, TSI148_LCSR_VIACK7 }; - -/* - * RMW - * offset 220 - */ -#define TSI148_LCSR_RMWAU 0x220 -#define TSI148_LCSR_RMWAL 0x224 -#define TSI148_LCSR_RMWEN 0x228 -#define TSI148_LCSR_RMWC 0x22C -#define TSI148_LCSR_RMWS 0x230 - -/* - * VMEbus control - * offset 234 - */ -#define TSI148_LCSR_VMCTRL 0x234 -#define TSI148_LCSR_VCTRL 0x238 -#define TSI148_LCSR_VSTAT 0x23C - -/* - * PCI status - * offset 240 - */ -#define TSI148_LCSR_PSTAT 0x240 - -/* - * VME filter. - * offset 250 - */ -#define TSI148_LCSR_VMEFL 0x250 - - /* - * VME exception. - * offset 260 - */ -#define TSI148_LCSR_VEAU 0x260 -#define TSI148_LCSR_VEAL 0x264 -#define TSI148_LCSR_VEAT 0x268 - - /* - * PCI error - * offset 270 - */ -#define TSI148_LCSR_EDPAU 0x270 -#define TSI148_LCSR_EDPAL 0x274 -#define TSI148_LCSR_EDPXA 0x278 -#define TSI148_LCSR_EDPXS 0x27C -#define TSI148_LCSR_EDPAT 0x280 - - /* - * Inbound Translations - * offset 300 - */ -#define TSI148_LCSR_IT0_ITSAU 0x300 -#define TSI148_LCSR_IT0_ITSAL 0x304 -#define TSI148_LCSR_IT0_ITEAU 0x308 -#define TSI148_LCSR_IT0_ITEAL 0x30C -#define TSI148_LCSR_IT0_ITOFU 0x310 -#define TSI148_LCSR_IT0_ITOFL 0x314 -#define TSI148_LCSR_IT0_ITAT 0x318 - -#define TSI148_LCSR_IT1_ITSAU 0x320 -#define TSI148_LCSR_IT1_ITSAL 0x324 -#define TSI148_LCSR_IT1_ITEAU 0x328 -#define TSI148_LCSR_IT1_ITEAL 0x32C -#define TSI148_LCSR_IT1_ITOFU 0x330 -#define TSI148_LCSR_IT1_ITOFL 0x334 -#define TSI148_LCSR_IT1_ITAT 0x338 - -#define TSI148_LCSR_IT2_ITSAU 0x340 -#define TSI148_LCSR_IT2_ITSAL 0x344 -#define TSI148_LCSR_IT2_ITEAU 0x348 -#define TSI148_LCSR_IT2_ITEAL 0x34C -#define TSI148_LCSR_IT2_ITOFU 0x350 -#define TSI148_LCSR_IT2_ITOFL 0x354 -#define TSI148_LCSR_IT2_ITAT 0x358 - -#define TSI148_LCSR_IT3_ITSAU 0x360 -#define TSI148_LCSR_IT3_ITSAL 0x364 -#define TSI148_LCSR_IT3_ITEAU 0x368 -#define TSI148_LCSR_IT3_ITEAL 0x36C -#define TSI148_LCSR_IT3_ITOFU 0x370 -#define TSI148_LCSR_IT3_ITOFL 0x374 -#define TSI148_LCSR_IT3_ITAT 0x378 - -#define TSI148_LCSR_IT4_ITSAU 0x380 -#define TSI148_LCSR_IT4_ITSAL 0x384 -#define TSI148_LCSR_IT4_ITEAU 0x388 -#define TSI148_LCSR_IT4_ITEAL 0x38C -#define TSI148_LCSR_IT4_ITOFU 0x390 -#define TSI148_LCSR_IT4_ITOFL 0x394 -#define TSI148_LCSR_IT4_ITAT 0x398 - -#define TSI148_LCSR_IT5_ITSAU 0x3A0 -#define TSI148_LCSR_IT5_ITSAL 0x3A4 -#define TSI148_LCSR_IT5_ITEAU 0x3A8 -#define TSI148_LCSR_IT5_ITEAL 0x3AC -#define TSI148_LCSR_IT5_ITOFU 0x3B0 -#define TSI148_LCSR_IT5_ITOFL 0x3B4 -#define TSI148_LCSR_IT5_ITAT 0x3B8 - -#define TSI148_LCSR_IT6_ITSAU 0x3C0 -#define TSI148_LCSR_IT6_ITSAL 0x3C4 -#define TSI148_LCSR_IT6_ITEAU 0x3C8 -#define TSI148_LCSR_IT6_ITEAL 0x3CC -#define TSI148_LCSR_IT6_ITOFU 0x3D0 -#define TSI148_LCSR_IT6_ITOFL 0x3D4 -#define TSI148_LCSR_IT6_ITAT 0x3D8 - -#define TSI148_LCSR_IT7_ITSAU 0x3E0 -#define TSI148_LCSR_IT7_ITSAL 0x3E4 -#define TSI148_LCSR_IT7_ITEAU 0x3E8 -#define TSI148_LCSR_IT7_ITEAL 0x3EC -#define TSI148_LCSR_IT7_ITOFU 0x3F0 -#define TSI148_LCSR_IT7_ITOFL 0x3F4 -#define TSI148_LCSR_IT7_ITAT 0x3F8 - - -#define TSI148_LCSR_IT0 0x300 -#define TSI148_LCSR_IT1 0x320 -#define TSI148_LCSR_IT2 0x340 -#define TSI148_LCSR_IT3 0x360 -#define TSI148_LCSR_IT4 0x380 -#define TSI148_LCSR_IT5 0x3A0 -#define TSI148_LCSR_IT6 0x3C0 -#define TSI148_LCSR_IT7 0x3E0 - -static const int TSI148_LCSR_IT[8] = { TSI148_LCSR_IT0, TSI148_LCSR_IT1, - TSI148_LCSR_IT2, TSI148_LCSR_IT3, - TSI148_LCSR_IT4, TSI148_LCSR_IT5, - TSI148_LCSR_IT6, TSI148_LCSR_IT7 }; - -#define TSI148_LCSR_OFFSET_ITSAU 0x0 -#define TSI148_LCSR_OFFSET_ITSAL 0x4 -#define TSI148_LCSR_OFFSET_ITEAU 0x8 -#define TSI148_LCSR_OFFSET_ITEAL 0xC -#define TSI148_LCSR_OFFSET_ITOFU 0x10 -#define TSI148_LCSR_OFFSET_ITOFL 0x14 -#define TSI148_LCSR_OFFSET_ITAT 0x18 - - /* - * Inbound Translation GCSR - * offset 400 - */ -#define TSI148_LCSR_GBAU 0x400 -#define TSI148_LCSR_GBAL 0x404 -#define TSI148_LCSR_GCSRAT 0x408 - - /* - * Inbound Translation CRG - * offset 40C - */ -#define TSI148_LCSR_CBAU 0x40C -#define TSI148_LCSR_CBAL 0x410 -#define TSI148_LCSR_CSRAT 0x414 - - /* - * Inbound Translation CR/CSR - * CRG - * offset 418 - */ -#define TSI148_LCSR_CROU 0x418 -#define TSI148_LCSR_CROL 0x41C -#define TSI148_LCSR_CRAT 0x420 - - /* - * Inbound Translation Location Monitor - * offset 424 - */ -#define TSI148_LCSR_LMBAU 0x424 -#define TSI148_LCSR_LMBAL 0x428 -#define TSI148_LCSR_LMAT 0x42C - - /* - * VMEbus Interrupt Control. - * offset 430 - */ -#define TSI148_LCSR_BCU 0x430 -#define TSI148_LCSR_BCL 0x434 -#define TSI148_LCSR_BPGTR 0x438 -#define TSI148_LCSR_BPCTR 0x43C -#define TSI148_LCSR_VICR 0x440 - - /* - * Local Bus Interrupt Control. - * offset 448 - */ -#define TSI148_LCSR_INTEN 0x448 -#define TSI148_LCSR_INTEO 0x44C -#define TSI148_LCSR_INTS 0x450 -#define TSI148_LCSR_INTC 0x454 -#define TSI148_LCSR_INTM1 0x458 -#define TSI148_LCSR_INTM2 0x45C - - /* - * DMA Controllers - * offset 500 - */ -#define TSI148_LCSR_DCTL0 0x500 -#define TSI148_LCSR_DSTA0 0x504 -#define TSI148_LCSR_DCSAU0 0x508 -#define TSI148_LCSR_DCSAL0 0x50C -#define TSI148_LCSR_DCDAU0 0x510 -#define TSI148_LCSR_DCDAL0 0x514 -#define TSI148_LCSR_DCLAU0 0x518 -#define TSI148_LCSR_DCLAL0 0x51C -#define TSI148_LCSR_DSAU0 0x520 -#define TSI148_LCSR_DSAL0 0x524 -#define TSI148_LCSR_DDAU0 0x528 -#define TSI148_LCSR_DDAL0 0x52C -#define TSI148_LCSR_DSAT0 0x530 -#define TSI148_LCSR_DDAT0 0x534 -#define TSI148_LCSR_DNLAU0 0x538 -#define TSI148_LCSR_DNLAL0 0x53C -#define TSI148_LCSR_DCNT0 0x540 -#define TSI148_LCSR_DDBS0 0x544 - -#define TSI148_LCSR_DCTL1 0x580 -#define TSI148_LCSR_DSTA1 0x584 -#define TSI148_LCSR_DCSAU1 0x588 -#define TSI148_LCSR_DCSAL1 0x58C -#define TSI148_LCSR_DCDAU1 0x590 -#define TSI148_LCSR_DCDAL1 0x594 -#define TSI148_LCSR_DCLAU1 0x598 -#define TSI148_LCSR_DCLAL1 0x59C -#define TSI148_LCSR_DSAU1 0x5A0 -#define TSI148_LCSR_DSAL1 0x5A4 -#define TSI148_LCSR_DDAU1 0x5A8 -#define TSI148_LCSR_DDAL1 0x5AC -#define TSI148_LCSR_DSAT1 0x5B0 -#define TSI148_LCSR_DDAT1 0x5B4 -#define TSI148_LCSR_DNLAU1 0x5B8 -#define TSI148_LCSR_DNLAL1 0x5BC -#define TSI148_LCSR_DCNT1 0x5C0 -#define TSI148_LCSR_DDBS1 0x5C4 - -#define TSI148_LCSR_DMA0 0x500 -#define TSI148_LCSR_DMA1 0x580 - - -static const int TSI148_LCSR_DMA[TSI148_MAX_DMA] = { TSI148_LCSR_DMA0, - TSI148_LCSR_DMA1 }; - -#define TSI148_LCSR_OFFSET_DCTL 0x0 -#define TSI148_LCSR_OFFSET_DSTA 0x4 -#define TSI148_LCSR_OFFSET_DCSAU 0x8 -#define TSI148_LCSR_OFFSET_DCSAL 0xC -#define TSI148_LCSR_OFFSET_DCDAU 0x10 -#define TSI148_LCSR_OFFSET_DCDAL 0x14 -#define TSI148_LCSR_OFFSET_DCLAU 0x18 -#define TSI148_LCSR_OFFSET_DCLAL 0x1C -#define TSI148_LCSR_OFFSET_DSAU 0x20 -#define TSI148_LCSR_OFFSET_DSAL 0x24 -#define TSI148_LCSR_OFFSET_DDAU 0x28 -#define TSI148_LCSR_OFFSET_DDAL 0x2C -#define TSI148_LCSR_OFFSET_DSAT 0x30 -#define TSI148_LCSR_OFFSET_DDAT 0x34 -#define TSI148_LCSR_OFFSET_DNLAU 0x38 -#define TSI148_LCSR_OFFSET_DNLAL 0x3C -#define TSI148_LCSR_OFFSET_DCNT 0x40 -#define TSI148_LCSR_OFFSET_DDBS 0x44 - - /* - * GCSR Register Group - */ - - /* - * GCSR CRG - * offset 00 600 - DEVI/VENI - * offset 04 604 - CTRL/GA/REVID - * offset 08 608 - Semaphore3/2/1/0 - * offset 0C 60C - Seamphore7/6/5/4 - */ -#define TSI148_GCSR_ID 0x600 -#define TSI148_GCSR_CSR 0x604 -#define TSI148_GCSR_SEMA0 0x608 -#define TSI148_GCSR_SEMA1 0x60C - - /* - * Mail Box - * GCSR CRG - * offset 10 610 - Mailbox0 - */ -#define TSI148_GCSR_MBOX0 0x610 -#define TSI148_GCSR_MBOX1 0x614 -#define TSI148_GCSR_MBOX2 0x618 -#define TSI148_GCSR_MBOX3 0x61C - -static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, - TSI148_GCSR_MBOX1, - TSI148_GCSR_MBOX2, - TSI148_GCSR_MBOX3 }; - - /* - * CR/CSR - */ - - /* - * CR/CSR CRG - * offset 7FFF4 FF4 - CSRBCR - * offset 7FFF8 FF8 - CSRBSR - * offset 7FFFC FFC - CBAR - */ -#define TSI148_CSRBCR 0xFF4 -#define TSI148_CSRBSR 0xFF8 -#define TSI148_CBAR 0xFFC - - - - - /* - * TSI148 Register Bit Definitions - */ - - /* - * PFCS Register Set - */ -#define TSI148_PCFS_CMMD_SERR (1<<8) /* SERR_L out pin ssys err */ -#define TSI148_PCFS_CMMD_PERR (1<<6) /* PERR_L out pin parity */ -#define TSI148_PCFS_CMMD_MSTR (1<<2) /* PCI bus master */ -#define TSI148_PCFS_CMMD_MEMSP (1<<1) /* PCI mem space access */ -#define TSI148_PCFS_CMMD_IOSP (1<<0) /* PCI I/O space enable */ - -#define TSI148_PCFS_STAT_RCPVE (1<<15) /* Detected Parity Error */ -#define TSI148_PCFS_STAT_SIGSE (1<<14) /* Signalled System Error */ -#define TSI148_PCFS_STAT_RCVMA (1<<13) /* Received Master Abort */ -#define TSI148_PCFS_STAT_RCVTA (1<<12) /* Received Target Abort */ -#define TSI148_PCFS_STAT_SIGTA (1<<11) /* Signalled Target Abort */ -#define TSI148_PCFS_STAT_SELTIM (3<<9) /* DELSEL Timing */ -#define TSI148_PCFS_STAT_DPAR (1<<8) /* Data Parity Err Reported */ -#define TSI148_PCFS_STAT_FAST (1<<7) /* Fast back-to-back Cap */ -#define TSI148_PCFS_STAT_P66M (1<<5) /* 66 MHz Capable */ -#define TSI148_PCFS_STAT_CAPL (1<<4) /* Capab List - address $34 */ - -/* - * Revision ID/Class Code Registers (CRG +$008) - */ -#define TSI148_PCFS_CLAS_M (0xFF<<24) /* Class ID */ -#define TSI148_PCFS_SUBCLAS_M (0xFF<<16) /* Sub-Class ID */ -#define TSI148_PCFS_PROGIF_M (0xFF<<8) /* Sub-Class ID */ -#define TSI148_PCFS_REVID_M (0xFF<<0) /* Rev ID */ - -/* - * Cache Line Size/ Master Latency Timer/ Header Type Registers (CRG + $00C) - */ -#define TSI148_PCFS_HEAD_M (0xFF<<16) /* Master Lat Timer */ -#define TSI148_PCFS_MLAT_M (0xFF<<8) /* Master Lat Timer */ -#define TSI148_PCFS_CLSZ_M (0xFF<<0) /* Cache Line Size */ - -/* - * Memory Base Address Lower Reg (CRG + $010) - */ -#define TSI148_PCFS_MBARL_BASEL_M (0xFFFFF<<12) /* Base Addr Lower Mask */ -#define TSI148_PCFS_MBARL_PRE (1<<3) /* Prefetch */ -#define TSI148_PCFS_MBARL_MTYPE_M (3<<1) /* Memory Type Mask */ -#define TSI148_PCFS_MBARL_IOMEM (1<<0) /* I/O Space Indicator */ - -/* - * Message Signaled Interrupt Capabilities Register (CRG + $040) - */ -#define TSI148_PCFS_MSICAP_64BAC (1<<7) /* 64-bit Address Capable */ -#define TSI148_PCFS_MSICAP_MME_M (7<<4) /* Multiple Msg Enable Mask */ -#define TSI148_PCFS_MSICAP_MMC_M (7<<1) /* Multiple Msg Capable Mask */ -#define TSI148_PCFS_MSICAP_MSIEN (1<<0) /* Msg signaled INT Enable */ - -/* - * Message Address Lower Register (CRG +$044) - */ -#define TSI148_PCFS_MSIAL_M (0x3FFFFFFF<<2) /* Mask */ - -/* - * Message Data Register (CRG + 4C) - */ -#define TSI148_PCFS_MSIMD_M (0xFFFF<<0) /* Mask */ - -/* - * PCI-X Capabilities Register (CRG + $050) - */ -#define TSI148_PCFS_PCIXCAP_MOST_M (7<<4) /* Max outstanding Split Tran */ -#define TSI148_PCFS_PCIXCAP_MMRBC_M (3<<2) /* Max Mem Read byte cnt */ -#define TSI148_PCFS_PCIXCAP_ERO (1<<1) /* Enable Relaxed Ordering */ -#define TSI148_PCFS_PCIXCAP_DPERE (1<<0) /* Data Parity Recover Enable */ - -/* - * PCI-X Status Register (CRG +$054) - */ -#define TSI148_PCFS_PCIXSTAT_RSCEM (1<<29) /* Received Split Comp Error */ -#define TSI148_PCFS_PCIXSTAT_DMCRS_M (7<<26) /* max Cumulative Read Size */ -#define TSI148_PCFS_PCIXSTAT_DMOST_M (7<<23) /* max outstanding Split Trans - */ -#define TSI148_PCFS_PCIXSTAT_DMMRC_M (3<<21) /* max mem read byte count */ -#define TSI148_PCFS_PCIXSTAT_DC (1<<20) /* Device Complexity */ -#define TSI148_PCFS_PCIXSTAT_USC (1<<19) /* Unexpected Split comp */ -#define TSI148_PCFS_PCIXSTAT_SCD (1<<18) /* Split completion discard */ -#define TSI148_PCFS_PCIXSTAT_133C (1<<17) /* 133MHz capable */ -#define TSI148_PCFS_PCIXSTAT_64D (1<<16) /* 64 bit device */ -#define TSI148_PCFS_PCIXSTAT_BN_M (0xFF<<8) /* Bus number */ -#define TSI148_PCFS_PCIXSTAT_DN_M (0x1F<<3) /* Device number */ -#define TSI148_PCFS_PCIXSTAT_FN_M (7<<0) /* Function Number */ - -/* - * LCSR Registers - */ - -/* - * Outbound Translation Starting Address Lower - */ -#define TSI148_LCSR_OTSAL_M (0xFFFF<<16) /* Mask */ - -/* - * Outbound Translation Ending Address Lower - */ -#define TSI148_LCSR_OTEAL_M (0xFFFF<<16) /* Mask */ - -/* - * Outbound Translation Offset Lower - */ -#define TSI148_LCSR_OTOFFL_M (0xFFFF<<16) /* Mask */ - -/* - * Outbound Translation 2eSST Broadcast Select - */ -#define TSI148_LCSR_OTBS_M (0xFFFFF<<0) /* Mask */ - -/* - * Outbound Translation Attribute - */ -#define TSI148_LCSR_OTAT_EN (1<<31) /* Window Enable */ -#define TSI148_LCSR_OTAT_MRPFD (1<<18) /* Prefetch Disable */ - -#define TSI148_LCSR_OTAT_PFS_M (3<<16) /* Prefetch Size Mask */ -#define TSI148_LCSR_OTAT_PFS_2 (0<<16) /* 2 Cache Lines P Size */ -#define TSI148_LCSR_OTAT_PFS_4 (1<<16) /* 4 Cache Lines P Size */ -#define TSI148_LCSR_OTAT_PFS_8 (2<<16) /* 8 Cache Lines P Size */ -#define TSI148_LCSR_OTAT_PFS_16 (3<<16) /* 16 Cache Lines P Size */ - -#define TSI148_LCSR_OTAT_2eSSTM_M (7<<11) /* 2eSST Xfer Rate Mask */ -#define TSI148_LCSR_OTAT_2eSSTM_160 (0<<11) /* 160MB/s 2eSST Xfer Rate */ -#define TSI148_LCSR_OTAT_2eSSTM_267 (1<<11) /* 267MB/s 2eSST Xfer Rate */ -#define TSI148_LCSR_OTAT_2eSSTM_320 (2<<11) /* 320MB/s 2eSST Xfer Rate */ - -#define TSI148_LCSR_OTAT_TM_M (7<<8) /* Xfer Protocol Mask */ -#define TSI148_LCSR_OTAT_TM_SCT (0<<8) /* SCT Xfer Protocol */ -#define TSI148_LCSR_OTAT_TM_BLT (1<<8) /* BLT Xfer Protocol */ -#define TSI148_LCSR_OTAT_TM_MBLT (2<<8) /* MBLT Xfer Protocol */ -#define TSI148_LCSR_OTAT_TM_2eVME (3<<8) /* 2eVME Xfer Protocol */ -#define TSI148_LCSR_OTAT_TM_2eSST (4<<8) /* 2eSST Xfer Protocol */ -#define TSI148_LCSR_OTAT_TM_2eSSTB (5<<8) /* 2eSST Bcast Xfer Protocol */ - -#define TSI148_LCSR_OTAT_DBW_M (3<<6) /* Max Data Width */ -#define TSI148_LCSR_OTAT_DBW_16 (0<<6) /* 16-bit Data Width */ -#define TSI148_LCSR_OTAT_DBW_32 (1<<6) /* 32-bit Data Width */ - -#define TSI148_LCSR_OTAT_SUP (1<<5) /* Supervisory Access */ -#define TSI148_LCSR_OTAT_PGM (1<<4) /* Program Access */ - -#define TSI148_LCSR_OTAT_AMODE_M (0xf<<0) /* Address Mode Mask */ -#define TSI148_LCSR_OTAT_AMODE_A16 (0<<0) /* A16 Address Space */ -#define TSI148_LCSR_OTAT_AMODE_A24 (1<<0) /* A24 Address Space */ -#define TSI148_LCSR_OTAT_AMODE_A32 (2<<0) /* A32 Address Space */ -#define TSI148_LCSR_OTAT_AMODE_A64 (4<<0) /* A32 Address Space */ -#define TSI148_LCSR_OTAT_AMODE_CRCSR (5<<0) /* CR/CSR Address Space */ -#define TSI148_LCSR_OTAT_AMODE_USER1 (8<<0) /* User1 Address Space */ -#define TSI148_LCSR_OTAT_AMODE_USER2 (9<<0) /* User2 Address Space */ -#define TSI148_LCSR_OTAT_AMODE_USER3 (10<<0) /* User3 Address Space */ -#define TSI148_LCSR_OTAT_AMODE_USER4 (11<<0) /* User4 Address Space */ - -/* - * VME Master Control Register CRG+$234 - */ -#define TSI148_LCSR_VMCTRL_VSA (1<<27) /* VMEbus Stop Ack */ -#define TSI148_LCSR_VMCTRL_VS (1<<26) /* VMEbus Stop */ -#define TSI148_LCSR_VMCTRL_DHB (1<<25) /* Device Has Bus */ -#define TSI148_LCSR_VMCTRL_DWB (1<<24) /* Device Wants Bus */ - -#define TSI148_LCSR_VMCTRL_RMWEN (1<<20) /* RMW Enable */ - -#define TSI148_LCSR_VMCTRL_ATO_M (7<<16) /* Master Access Time-out Mask - */ -#define TSI148_LCSR_VMCTRL_ATO_32 (0<<16) /* 32 us */ -#define TSI148_LCSR_VMCTRL_ATO_128 (1<<16) /* 128 us */ -#define TSI148_LCSR_VMCTRL_ATO_512 (2<<16) /* 512 us */ -#define TSI148_LCSR_VMCTRL_ATO_2M (3<<16) /* 2 ms */ -#define TSI148_LCSR_VMCTRL_ATO_8M (4<<16) /* 8 ms */ -#define TSI148_LCSR_VMCTRL_ATO_32M (5<<16) /* 32 ms */ -#define TSI148_LCSR_VMCTRL_ATO_128M (6<<16) /* 128 ms */ -#define TSI148_LCSR_VMCTRL_ATO_DIS (7<<16) /* Disabled */ - -#define TSI148_LCSR_VMCTRL_VTOFF_M (7<<12) /* VMEbus Master Time off */ -#define TSI148_LCSR_VMCTRL_VTOFF_0 (0<<12) /* 0us */ -#define TSI148_LCSR_VMCTRL_VTOFF_1 (1<<12) /* 1us */ -#define TSI148_LCSR_VMCTRL_VTOFF_2 (2<<12) /* 2us */ -#define TSI148_LCSR_VMCTRL_VTOFF_4 (3<<12) /* 4us */ -#define TSI148_LCSR_VMCTRL_VTOFF_8 (4<<12) /* 8us */ -#define TSI148_LCSR_VMCTRL_VTOFF_16 (5<<12) /* 16us */ -#define TSI148_LCSR_VMCTRL_VTOFF_32 (6<<12) /* 32us */ -#define TSI148_LCSR_VMCTRL_VTOFF_64 (7<<12) /* 64us */ - -#define TSI148_LCSR_VMCTRL_VTON_M (7<<8) /* VMEbus Master Time On */ -#define TSI148_LCSR_VMCTRL_VTON_4 (0<<8) /* 8us */ -#define TSI148_LCSR_VMCTRL_VTON_8 (1<<8) /* 8us */ -#define TSI148_LCSR_VMCTRL_VTON_16 (2<<8) /* 16us */ -#define TSI148_LCSR_VMCTRL_VTON_32 (3<<8) /* 32us */ -#define TSI148_LCSR_VMCTRL_VTON_64 (4<<8) /* 64us */ -#define TSI148_LCSR_VMCTRL_VTON_128 (5<<8) /* 128us */ -#define TSI148_LCSR_VMCTRL_VTON_256 (6<<8) /* 256us */ -#define TSI148_LCSR_VMCTRL_VTON_512 (7<<8) /* 512us */ - -#define TSI148_LCSR_VMCTRL_VREL_M (3<<3) /* VMEbus Master Rel Mode Mask - */ -#define TSI148_LCSR_VMCTRL_VREL_T_D (0<<3) /* Time on or Done */ -#define TSI148_LCSR_VMCTRL_VREL_T_R_D (1<<3) /* Time on and REQ or Done */ -#define TSI148_LCSR_VMCTRL_VREL_T_B_D (2<<3) /* Time on and BCLR or Done */ -#define TSI148_LCSR_VMCTRL_VREL_T_D_R (3<<3) /* Time on or Done and REQ */ - -#define TSI148_LCSR_VMCTRL_VFAIR (1<<2) /* VMEbus Master Fair Mode */ -#define TSI148_LCSR_VMCTRL_VREQL_M (3<<0) /* VMEbus Master Req Level Mask - */ - -/* - * VMEbus Control Register CRG+$238 - */ -#define TSI148_LCSR_VCTRL_LRE (1<<31) /* Late Retry Enable */ - -#define TSI148_LCSR_VCTRL_DLT_M (0xF<<24) /* Deadlock Timer */ -#define TSI148_LCSR_VCTRL_DLT_OFF (0<<24) /* Deadlock Timer Off */ -#define TSI148_LCSR_VCTRL_DLT_16 (1<<24) /* 16 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_32 (2<<24) /* 32 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_64 (3<<24) /* 64 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_128 (4<<24) /* 128 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_256 (5<<24) /* 256 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_512 (6<<24) /* 512 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_1024 (7<<24) /* 1024 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_2048 (8<<24) /* 2048 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_4096 (9<<24) /* 4096 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_8192 (0xA<<24) /* 8192 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_16384 (0xB<<24) /* 16384 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_32768 (0xC<<24) /* 32768 VCLKS */ - -#define TSI148_LCSR_VCTRL_NERBB (1<<20) /* No Early Release of Bus Busy - */ - -#define TSI148_LCSR_VCTRL_SRESET (1<<17) /* System Reset */ -#define TSI148_LCSR_VCTRL_LRESET (1<<16) /* Local Reset */ - -#define TSI148_LCSR_VCTRL_SFAILAI (1<<15) /* SYSFAIL Auto Slot ID */ -#define TSI148_LCSR_VCTRL_BID_M (0x1F<<8) /* Broadcast ID Mask */ - -#define TSI148_LCSR_VCTRL_ATOEN (1<<7) /* Arbiter Time-out Enable */ -#define TSI148_LCSR_VCTRL_ROBIN (1<<6) /* VMEbus Round Robin */ - -#define TSI148_LCSR_VCTRL_GTO_M (7<<0) /* VMEbus Global Time-out Mask - */ -#define TSI148_LCSR_VCTRL_GTO_8 (0<<0) /* 8 us */ -#define TSI148_LCSR_VCTRL_GTO_16 (1<<0) /* 16 us */ -#define TSI148_LCSR_VCTRL_GTO_32 (2<<0) /* 32 us */ -#define TSI148_LCSR_VCTRL_GTO_64 (3<<0) /* 64 us */ -#define TSI148_LCSR_VCTRL_GTO_128 (4<<0) /* 128 us */ -#define TSI148_LCSR_VCTRL_GTO_256 (5<<0) /* 256 us */ -#define TSI148_LCSR_VCTRL_GTO_512 (6<<0) /* 512 us */ -#define TSI148_LCSR_VCTRL_GTO_DIS (7<<0) /* Disabled */ - -/* - * VMEbus Status Register CRG + $23C - */ -#define TSI148_LCSR_VSTAT_CPURST (1<<15) /* Clear power up reset */ -#define TSI148_LCSR_VSTAT_BRDFL (1<<14) /* Board fail */ -#define TSI148_LCSR_VSTAT_PURSTS (1<<12) /* Power up reset status */ -#define TSI148_LCSR_VSTAT_BDFAILS (1<<11) /* Board Fail Status */ -#define TSI148_LCSR_VSTAT_SYSFAILS (1<<10) /* System Fail Status */ -#define TSI148_LCSR_VSTAT_ACFAILS (1<<9) /* AC fail status */ -#define TSI148_LCSR_VSTAT_SCONS (1<<8) /* System Cont Status */ -#define TSI148_LCSR_VSTAT_GAP (1<<5) /* Geographic Addr Parity */ -#define TSI148_LCSR_VSTAT_GA_M (0x1F<<0) /* Geographic Addr Mask */ - -/* - * PCI Configuration Status Register CRG+$240 - */ -#define TSI148_LCSR_PSTAT_REQ64S (1<<6) /* Request 64 status set */ -#define TSI148_LCSR_PSTAT_M66ENS (1<<5) /* M66ENS 66Mhz enable */ -#define TSI148_LCSR_PSTAT_FRAMES (1<<4) /* Frame Status */ -#define TSI148_LCSR_PSTAT_IRDYS (1<<3) /* IRDY status */ -#define TSI148_LCSR_PSTAT_DEVSELS (1<<2) /* DEVL status */ -#define TSI148_LCSR_PSTAT_STOPS (1<<1) /* STOP status */ -#define TSI148_LCSR_PSTAT_TRDYS (1<<0) /* TRDY status */ - -/* - * VMEbus Exception Attributes Register CRG + $268 - */ -#define TSI148_LCSR_VEAT_VES (1<<31) /* Status */ -#define TSI148_LCSR_VEAT_VEOF (1<<30) /* Overflow */ -#define TSI148_LCSR_VEAT_VESCL (1<<29) /* Status Clear */ -#define TSI148_LCSR_VEAT_2EOT (1<<21) /* 2e Odd Termination */ -#define TSI148_LCSR_VEAT_2EST (1<<20) /* 2e Slave terminated */ -#define TSI148_LCSR_VEAT_BERR (1<<19) /* Bus Error */ -#define TSI148_LCSR_VEAT_LWORD (1<<18) /* LWORD_ signal state */ -#define TSI148_LCSR_VEAT_WRITE (1<<17) /* WRITE_ signal state */ -#define TSI148_LCSR_VEAT_IACK (1<<16) /* IACK_ signal state */ -#define TSI148_LCSR_VEAT_DS1 (1<<15) /* DS1_ signal state */ -#define TSI148_LCSR_VEAT_DS0 (1<<14) /* DS0_ signal state */ -#define TSI148_LCSR_VEAT_AM_M (0x3F<<8) /* Address Mode Mask */ -#define TSI148_LCSR_VEAT_XAM_M (0xFF<<0) /* Master AMode Mask */ - - -/* - * VMEbus PCI Error Diagnostics PCI/X Attributes Register CRG + $280 - */ -#define TSI148_LCSR_EDPAT_EDPCL (1<<29) - -/* - * Inbound Translation Starting Address Lower - */ -#define TSI148_LCSR_ITSAL6432_M (0xFFFF<<16) /* Mask */ -#define TSI148_LCSR_ITSAL24_M (0x00FFF<<12) /* Mask */ -#define TSI148_LCSR_ITSAL16_M (0x0000FFF<<4) /* Mask */ - -/* - * Inbound Translation Ending Address Lower - */ -#define TSI148_LCSR_ITEAL6432_M (0xFFFF<<16) /* Mask */ -#define TSI148_LCSR_ITEAL24_M (0x00FFF<<12) /* Mask */ -#define TSI148_LCSR_ITEAL16_M (0x0000FFF<<4) /* Mask */ - -/* - * Inbound Translation Offset Lower - */ -#define TSI148_LCSR_ITOFFL6432_M (0xFFFF<<16) /* Mask */ -#define TSI148_LCSR_ITOFFL24_M (0xFFFFF<<12) /* Mask */ -#define TSI148_LCSR_ITOFFL16_M (0xFFFFFFF<<4) /* Mask */ - -/* - * Inbound Translation Attribute - */ -#define TSI148_LCSR_ITAT_EN (1<<31) /* Window Enable */ -#define TSI148_LCSR_ITAT_TH (1<<18) /* Prefetch Threshold */ - -#define TSI148_LCSR_ITAT_VFS_M (3<<16) /* Virtual FIFO Size Mask */ -#define TSI148_LCSR_ITAT_VFS_64 (0<<16) /* 64 bytes Virtual FIFO Size */ -#define TSI148_LCSR_ITAT_VFS_128 (1<<16) /* 128 bytes Virtual FIFO Sz */ -#define TSI148_LCSR_ITAT_VFS_256 (2<<16) /* 256 bytes Virtual FIFO Sz */ -#define TSI148_LCSR_ITAT_VFS_512 (3<<16) /* 512 bytes Virtual FIFO Sz */ - -#define TSI148_LCSR_ITAT_2eSSTM_M (7<<12) /* 2eSST Xfer Rate Mask */ -#define TSI148_LCSR_ITAT_2eSSTM_160 (0<<12) /* 160MB/s 2eSST Xfer Rate */ -#define TSI148_LCSR_ITAT_2eSSTM_267 (1<<12) /* 267MB/s 2eSST Xfer Rate */ -#define TSI148_LCSR_ITAT_2eSSTM_320 (2<<12) /* 320MB/s 2eSST Xfer Rate */ - -#define TSI148_LCSR_ITAT_2eSSTB (1<<11) /* 2eSST Bcast Xfer Protocol */ -#define TSI148_LCSR_ITAT_2eSST (1<<10) /* 2eSST Xfer Protocol */ -#define TSI148_LCSR_ITAT_2eVME (1<<9) /* 2eVME Xfer Protocol */ -#define TSI148_LCSR_ITAT_MBLT (1<<8) /* MBLT Xfer Protocol */ -#define TSI148_LCSR_ITAT_BLT (1<<7) /* BLT Xfer Protocol */ - -#define TSI148_LCSR_ITAT_AS_M (7<<4) /* Address Space Mask */ -#define TSI148_LCSR_ITAT_AS_A16 (0<<4) /* A16 Address Space */ -#define TSI148_LCSR_ITAT_AS_A24 (1<<4) /* A24 Address Space */ -#define TSI148_LCSR_ITAT_AS_A32 (2<<4) /* A32 Address Space */ -#define TSI148_LCSR_ITAT_AS_A64 (4<<4) /* A64 Address Space */ - -#define TSI148_LCSR_ITAT_SUPR (1<<3) /* Supervisor Access */ -#define TSI148_LCSR_ITAT_NPRIV (1<<2) /* Non-Priv (User) Access */ -#define TSI148_LCSR_ITAT_PGM (1<<1) /* Program Access */ -#define TSI148_LCSR_ITAT_DATA (1<<0) /* Data Access */ - -/* - * GCSR Base Address Lower Address CRG +$404 - */ -#define TSI148_LCSR_GBAL_M (0x7FFFFFF<<5) /* Mask */ - -/* - * GCSR Attribute Register CRG + $408 - */ -#define TSI148_LCSR_GCSRAT_EN (1<<7) /* Enable access to GCSR */ - -#define TSI148_LCSR_GCSRAT_AS_M (7<<4) /* Address Space Mask */ -#define TSI148_LCSR_GCSRAT_AS_A16 (0<<4) /* Address Space 16 */ -#define TSI148_LCSR_GCSRAT_AS_A24 (1<<4) /* Address Space 24 */ -#define TSI148_LCSR_GCSRAT_AS_A32 (2<<4) /* Address Space 32 */ -#define TSI148_LCSR_GCSRAT_AS_A64 (4<<4) /* Address Space 64 */ - -#define TSI148_LCSR_GCSRAT_SUPR (1<<3) /* Sup set -GCSR decoder */ -#define TSI148_LCSR_GCSRAT_NPRIV (1<<2) /* Non-Privliged set - CGSR */ -#define TSI148_LCSR_GCSRAT_PGM (1<<1) /* Program set - GCSR decoder */ -#define TSI148_LCSR_GCSRAT_DATA (1<<0) /* DATA set GCSR decoder */ - -/* - * CRG Base Address Lower Address CRG + $410 - */ -#define TSI148_LCSR_CBAL_M (0xFFFFF<<12) - -/* - * CRG Attribute Register CRG + $414 - */ -#define TSI148_LCSR_CRGAT_EN (1<<7) /* Enable PRG Access */ - -#define TSI148_LCSR_CRGAT_AS_M (7<<4) /* Address Space */ -#define TSI148_LCSR_CRGAT_AS_A16 (0<<4) /* Address Space 16 */ -#define TSI148_LCSR_CRGAT_AS_A24 (1<<4) /* Address Space 24 */ -#define TSI148_LCSR_CRGAT_AS_A32 (2<<4) /* Address Space 32 */ -#define TSI148_LCSR_CRGAT_AS_A64 (4<<4) /* Address Space 64 */ - -#define TSI148_LCSR_CRGAT_SUPR (1<<3) /* Supervisor Access */ -#define TSI148_LCSR_CRGAT_NPRIV (1<<2) /* Non-Privliged(User) Access */ -#define TSI148_LCSR_CRGAT_PGM (1<<1) /* Program Access */ -#define TSI148_LCSR_CRGAT_DATA (1<<0) /* Data Access */ - -/* - * CR/CSR Offset Lower Register CRG + $41C - */ -#define TSI148_LCSR_CROL_M (0x1FFF<<19) /* Mask */ - -/* - * CR/CSR Attribute register CRG + $420 - */ -#define TSI148_LCSR_CRAT_EN (1<<7) /* Enable access to CR/CSR */ - -/* - * Location Monitor base address lower register CRG + $428 - */ -#define TSI148_LCSR_LMBAL_M (0x7FFFFFF<<5) /* Mask */ - -/* - * Location Monitor Attribute Register CRG + $42C - */ -#define TSI148_LCSR_LMAT_EN (1<<7) /* Enable Location Monitor */ - -#define TSI148_LCSR_LMAT_AS_M (7<<4) /* Address Space MASK */ -#define TSI148_LCSR_LMAT_AS_A16 (0<<4) /* A16 */ -#define TSI148_LCSR_LMAT_AS_A24 (1<<4) /* A24 */ -#define TSI148_LCSR_LMAT_AS_A32 (2<<4) /* A32 */ -#define TSI148_LCSR_LMAT_AS_A64 (4<<4) /* A64 */ - -#define TSI148_LCSR_LMAT_SUPR (1<<3) /* Supervisor Access */ -#define TSI148_LCSR_LMAT_NPRIV (1<<2) /* Non-Priv (User) Access */ -#define TSI148_LCSR_LMAT_PGM (1<<1) /* Program Access */ -#define TSI148_LCSR_LMAT_DATA (1<<0) /* Data Access */ - -/* - * Broadcast Pulse Generator Timer Register CRG + $438 - */ -#define TSI148_LCSR_BPGTR_BPGT_M (0xFFFF<<0) /* Mask */ - -/* - * Broadcast Programmable Clock Timer Register CRG + $43C - */ -#define TSI148_LCSR_BPCTR_BPCT_M (0xFFFFFF<<0) /* Mask */ - -/* - * VMEbus Interrupt Control Register CRG + $43C - */ -#define TSI148_LCSR_VICR_CNTS_M (3<<22) /* Cntr Source MASK */ -#define TSI148_LCSR_VICR_CNTS_DIS (1<<22) /* Cntr Disable */ -#define TSI148_LCSR_VICR_CNTS_IRQ1 (2<<22) /* IRQ1 to Cntr */ -#define TSI148_LCSR_VICR_CNTS_IRQ2 (3<<22) /* IRQ2 to Cntr */ - -#define TSI148_LCSR_VICR_EDGIS_M (3<<20) /* Edge interrupt MASK */ -#define TSI148_LCSR_VICR_EDGIS_DIS (1<<20) /* Edge interrupt Disable */ -#define TSI148_LCSR_VICR_EDGIS_IRQ1 (2<<20) /* IRQ1 to Edge */ -#define TSI148_LCSR_VICR_EDGIS_IRQ2 (3<<20) /* IRQ2 to Edge */ - -#define TSI148_LCSR_VICR_IRQIF_M (3<<18) /* IRQ1* Function MASK */ -#define TSI148_LCSR_VICR_IRQIF_NORM (1<<18) /* Normal */ -#define TSI148_LCSR_VICR_IRQIF_PULSE (2<<18) /* Pulse Generator */ -#define TSI148_LCSR_VICR_IRQIF_PROG (3<<18) /* Programmable Clock */ -#define TSI148_LCSR_VICR_IRQIF_1U (4<<18) /* 1us Clock */ - -#define TSI148_LCSR_VICR_IRQ2F_M (3<<16) /* IRQ2* Function MASK */ -#define TSI148_LCSR_VICR_IRQ2F_NORM (1<<16) /* Normal */ -#define TSI148_LCSR_VICR_IRQ2F_PULSE (2<<16) /* Pulse Generator */ -#define TSI148_LCSR_VICR_IRQ2F_PROG (3<<16) /* Programmable Clock */ -#define TSI148_LCSR_VICR_IRQ2F_1U (4<<16) /* 1us Clock */ - -#define TSI148_LCSR_VICR_BIP (1<<15) /* Broadcast Interrupt Pulse */ - -#define TSI148_LCSR_VICR_IRQC (1<<12) /* VMEbus IRQ Clear */ -#define TSI148_LCSR_VICR_IRQS (1<<11) /* VMEbus IRQ Status */ - -#define TSI148_LCSR_VICR_IRQL_M (7<<8) /* VMEbus SW IRQ Level Mask */ -#define TSI148_LCSR_VICR_IRQL_1 (1<<8) /* VMEbus SW IRQ Level 1 */ -#define TSI148_LCSR_VICR_IRQL_2 (2<<8) /* VMEbus SW IRQ Level 2 */ -#define TSI148_LCSR_VICR_IRQL_3 (3<<8) /* VMEbus SW IRQ Level 3 */ -#define TSI148_LCSR_VICR_IRQL_4 (4<<8) /* VMEbus SW IRQ Level 4 */ -#define TSI148_LCSR_VICR_IRQL_5 (5<<8) /* VMEbus SW IRQ Level 5 */ -#define TSI148_LCSR_VICR_IRQL_6 (6<<8) /* VMEbus SW IRQ Level 6 */ -#define TSI148_LCSR_VICR_IRQL_7 (7<<8) /* VMEbus SW IRQ Level 7 */ - -static const int TSI148_LCSR_VICR_IRQL[8] = { 0, TSI148_LCSR_VICR_IRQL_1, - TSI148_LCSR_VICR_IRQL_2, TSI148_LCSR_VICR_IRQL_3, - TSI148_LCSR_VICR_IRQL_4, TSI148_LCSR_VICR_IRQL_5, - TSI148_LCSR_VICR_IRQL_6, TSI148_LCSR_VICR_IRQL_7 }; - -#define TSI148_LCSR_VICR_STID_M (0xFF<<0) /* Status/ID Mask */ - -/* - * Interrupt Enable Register CRG + $440 - */ -#define TSI148_LCSR_INTEN_DMA1EN (1<<25) /* DMAC 1 */ -#define TSI148_LCSR_INTEN_DMA0EN (1<<24) /* DMAC 0 */ -#define TSI148_LCSR_INTEN_LM3EN (1<<23) /* Location Monitor 3 */ -#define TSI148_LCSR_INTEN_LM2EN (1<<22) /* Location Monitor 2 */ -#define TSI148_LCSR_INTEN_LM1EN (1<<21) /* Location Monitor 1 */ -#define TSI148_LCSR_INTEN_LM0EN (1<<20) /* Location Monitor 0 */ -#define TSI148_LCSR_INTEN_MB3EN (1<<19) /* Mail Box 3 */ -#define TSI148_LCSR_INTEN_MB2EN (1<<18) /* Mail Box 2 */ -#define TSI148_LCSR_INTEN_MB1EN (1<<17) /* Mail Box 1 */ -#define TSI148_LCSR_INTEN_MB0EN (1<<16) /* Mail Box 0 */ -#define TSI148_LCSR_INTEN_PERREN (1<<13) /* PCI/X Error */ -#define TSI148_LCSR_INTEN_VERREN (1<<12) /* VMEbus Error */ -#define TSI148_LCSR_INTEN_VIEEN (1<<11) /* VMEbus IRQ Edge */ -#define TSI148_LCSR_INTEN_IACKEN (1<<10) /* IACK */ -#define TSI148_LCSR_INTEN_SYSFLEN (1<<9) /* System Fail */ -#define TSI148_LCSR_INTEN_ACFLEN (1<<8) /* AC Fail */ -#define TSI148_LCSR_INTEN_IRQ7EN (1<<7) /* IRQ7 */ -#define TSI148_LCSR_INTEN_IRQ6EN (1<<6) /* IRQ6 */ -#define TSI148_LCSR_INTEN_IRQ5EN (1<<5) /* IRQ5 */ -#define TSI148_LCSR_INTEN_IRQ4EN (1<<4) /* IRQ4 */ -#define TSI148_LCSR_INTEN_IRQ3EN (1<<3) /* IRQ3 */ -#define TSI148_LCSR_INTEN_IRQ2EN (1<<2) /* IRQ2 */ -#define TSI148_LCSR_INTEN_IRQ1EN (1<<1) /* IRQ1 */ - -static const int TSI148_LCSR_INTEN_LMEN[4] = { TSI148_LCSR_INTEN_LM0EN, - TSI148_LCSR_INTEN_LM1EN, - TSI148_LCSR_INTEN_LM2EN, - TSI148_LCSR_INTEN_LM3EN }; - -static const int TSI148_LCSR_INTEN_IRQEN[7] = { TSI148_LCSR_INTEN_IRQ1EN, - TSI148_LCSR_INTEN_IRQ2EN, - TSI148_LCSR_INTEN_IRQ3EN, - TSI148_LCSR_INTEN_IRQ4EN, - TSI148_LCSR_INTEN_IRQ5EN, - TSI148_LCSR_INTEN_IRQ6EN, - TSI148_LCSR_INTEN_IRQ7EN }; - -/* - * Interrupt Enable Out Register CRG + $444 - */ -#define TSI148_LCSR_INTEO_DMA1EO (1<<25) /* DMAC 1 */ -#define TSI148_LCSR_INTEO_DMA0EO (1<<24) /* DMAC 0 */ -#define TSI148_LCSR_INTEO_LM3EO (1<<23) /* Loc Monitor 3 */ -#define TSI148_LCSR_INTEO_LM2EO (1<<22) /* Loc Monitor 2 */ -#define TSI148_LCSR_INTEO_LM1EO (1<<21) /* Loc Monitor 1 */ -#define TSI148_LCSR_INTEO_LM0EO (1<<20) /* Location Monitor 0 */ -#define TSI148_LCSR_INTEO_MB3EO (1<<19) /* Mail Box 3 */ -#define TSI148_LCSR_INTEO_MB2EO (1<<18) /* Mail Box 2 */ -#define TSI148_LCSR_INTEO_MB1EO (1<<17) /* Mail Box 1 */ -#define TSI148_LCSR_INTEO_MB0EO (1<<16) /* Mail Box 0 */ -#define TSI148_LCSR_INTEO_PERREO (1<<13) /* PCI/X Error */ -#define TSI148_LCSR_INTEO_VERREO (1<<12) /* VMEbus Error */ -#define TSI148_LCSR_INTEO_VIEEO (1<<11) /* VMEbus IRQ Edge */ -#define TSI148_LCSR_INTEO_IACKEO (1<<10) /* IACK */ -#define TSI148_LCSR_INTEO_SYSFLEO (1<<9) /* System Fail */ -#define TSI148_LCSR_INTEO_ACFLEO (1<<8) /* AC Fail */ -#define TSI148_LCSR_INTEO_IRQ7EO (1<<7) /* IRQ7 */ -#define TSI148_LCSR_INTEO_IRQ6EO (1<<6) /* IRQ6 */ -#define TSI148_LCSR_INTEO_IRQ5EO (1<<5) /* IRQ5 */ -#define TSI148_LCSR_INTEO_IRQ4EO (1<<4) /* IRQ4 */ -#define TSI148_LCSR_INTEO_IRQ3EO (1<<3) /* IRQ3 */ -#define TSI148_LCSR_INTEO_IRQ2EO (1<<2) /* IRQ2 */ -#define TSI148_LCSR_INTEO_IRQ1EO (1<<1) /* IRQ1 */ - -static const int TSI148_LCSR_INTEO_LMEO[4] = { TSI148_LCSR_INTEO_LM0EO, - TSI148_LCSR_INTEO_LM1EO, - TSI148_LCSR_INTEO_LM2EO, - TSI148_LCSR_INTEO_LM3EO }; - -static const int TSI148_LCSR_INTEO_IRQEO[7] = { TSI148_LCSR_INTEO_IRQ1EO, - TSI148_LCSR_INTEO_IRQ2EO, - TSI148_LCSR_INTEO_IRQ3EO, - TSI148_LCSR_INTEO_IRQ4EO, - TSI148_LCSR_INTEO_IRQ5EO, - TSI148_LCSR_INTEO_IRQ6EO, - TSI148_LCSR_INTEO_IRQ7EO }; - -/* - * Interrupt Status Register CRG + $448 - */ -#define TSI148_LCSR_INTS_DMA1S (1<<25) /* DMA 1 */ -#define TSI148_LCSR_INTS_DMA0S (1<<24) /* DMA 0 */ -#define TSI148_LCSR_INTS_LM3S (1<<23) /* Location Monitor 3 */ -#define TSI148_LCSR_INTS_LM2S (1<<22) /* Location Monitor 2 */ -#define TSI148_LCSR_INTS_LM1S (1<<21) /* Location Monitor 1 */ -#define TSI148_LCSR_INTS_LM0S (1<<20) /* Location Monitor 0 */ -#define TSI148_LCSR_INTS_MB3S (1<<19) /* Mail Box 3 */ -#define TSI148_LCSR_INTS_MB2S (1<<18) /* Mail Box 2 */ -#define TSI148_LCSR_INTS_MB1S (1<<17) /* Mail Box 1 */ -#define TSI148_LCSR_INTS_MB0S (1<<16) /* Mail Box 0 */ -#define TSI148_LCSR_INTS_PERRS (1<<13) /* PCI/X Error */ -#define TSI148_LCSR_INTS_VERRS (1<<12) /* VMEbus Error */ -#define TSI148_LCSR_INTS_VIES (1<<11) /* VMEbus IRQ Edge */ -#define TSI148_LCSR_INTS_IACKS (1<<10) /* IACK */ -#define TSI148_LCSR_INTS_SYSFLS (1<<9) /* System Fail */ -#define TSI148_LCSR_INTS_ACFLS (1<<8) /* AC Fail */ -#define TSI148_LCSR_INTS_IRQ7S (1<<7) /* IRQ7 */ -#define TSI148_LCSR_INTS_IRQ6S (1<<6) /* IRQ6 */ -#define TSI148_LCSR_INTS_IRQ5S (1<<5) /* IRQ5 */ -#define TSI148_LCSR_INTS_IRQ4S (1<<4) /* IRQ4 */ -#define TSI148_LCSR_INTS_IRQ3S (1<<3) /* IRQ3 */ -#define TSI148_LCSR_INTS_IRQ2S (1<<2) /* IRQ2 */ -#define TSI148_LCSR_INTS_IRQ1S (1<<1) /* IRQ1 */ - -static const int TSI148_LCSR_INTS_LMS[4] = { TSI148_LCSR_INTS_LM0S, - TSI148_LCSR_INTS_LM1S, - TSI148_LCSR_INTS_LM2S, - TSI148_LCSR_INTS_LM3S }; - -static const int TSI148_LCSR_INTS_MBS[4] = { TSI148_LCSR_INTS_MB0S, - TSI148_LCSR_INTS_MB1S, - TSI148_LCSR_INTS_MB2S, - TSI148_LCSR_INTS_MB3S }; - -/* - * Interrupt Clear Register CRG + $44C - */ -#define TSI148_LCSR_INTC_DMA1C (1<<25) /* DMA 1 */ -#define TSI148_LCSR_INTC_DMA0C (1<<24) /* DMA 0 */ -#define TSI148_LCSR_INTC_LM3C (1<<23) /* Location Monitor 3 */ -#define TSI148_LCSR_INTC_LM2C (1<<22) /* Location Monitor 2 */ -#define TSI148_LCSR_INTC_LM1C (1<<21) /* Location Monitor 1 */ -#define TSI148_LCSR_INTC_LM0C (1<<20) /* Location Monitor 0 */ -#define TSI148_LCSR_INTC_MB3C (1<<19) /* Mail Box 3 */ -#define TSI148_LCSR_INTC_MB2C (1<<18) /* Mail Box 2 */ -#define TSI148_LCSR_INTC_MB1C (1<<17) /* Mail Box 1 */ -#define TSI148_LCSR_INTC_MB0C (1<<16) /* Mail Box 0 */ -#define TSI148_LCSR_INTC_PERRC (1<<13) /* VMEbus Error */ -#define TSI148_LCSR_INTC_VERRC (1<<12) /* VMEbus Access Time-out */ -#define TSI148_LCSR_INTC_VIEC (1<<11) /* VMEbus IRQ Edge */ -#define TSI148_LCSR_INTC_IACKC (1<<10) /* IACK */ -#define TSI148_LCSR_INTC_SYSFLC (1<<9) /* System Fail */ -#define TSI148_LCSR_INTC_ACFLC (1<<8) /* AC Fail */ - -static const int TSI148_LCSR_INTC_LMC[4] = { TSI148_LCSR_INTC_LM0C, - TSI148_LCSR_INTC_LM1C, - TSI148_LCSR_INTC_LM2C, - TSI148_LCSR_INTC_LM3C }; - -static const int TSI148_LCSR_INTC_MBC[4] = { TSI148_LCSR_INTC_MB0C, - TSI148_LCSR_INTC_MB1C, - TSI148_LCSR_INTC_MB2C, - TSI148_LCSR_INTC_MB3C }; - -/* - * Interrupt Map Register 1 CRG + $458 - */ -#define TSI148_LCSR_INTM1_DMA1M_M (3<<18) /* DMA 1 */ -#define TSI148_LCSR_INTM1_DMA0M_M (3<<16) /* DMA 0 */ -#define TSI148_LCSR_INTM1_LM3M_M (3<<14) /* Location Monitor 3 */ -#define TSI148_LCSR_INTM1_LM2M_M (3<<12) /* Location Monitor 2 */ -#define TSI148_LCSR_INTM1_LM1M_M (3<<10) /* Location Monitor 1 */ -#define TSI148_LCSR_INTM1_LM0M_M (3<<8) /* Location Monitor 0 */ -#define TSI148_LCSR_INTM1_MB3M_M (3<<6) /* Mail Box 3 */ -#define TSI148_LCSR_INTM1_MB2M_M (3<<4) /* Mail Box 2 */ -#define TSI148_LCSR_INTM1_MB1M_M (3<<2) /* Mail Box 1 */ -#define TSI148_LCSR_INTM1_MB0M_M (3<<0) /* Mail Box 0 */ - -/* - * Interrupt Map Register 2 CRG + $45C - */ -#define TSI148_LCSR_INTM2_PERRM_M (3<<26) /* PCI Bus Error */ -#define TSI148_LCSR_INTM2_VERRM_M (3<<24) /* VMEbus Error */ -#define TSI148_LCSR_INTM2_VIEM_M (3<<22) /* VMEbus IRQ Edge */ -#define TSI148_LCSR_INTM2_IACKM_M (3<<20) /* IACK */ -#define TSI148_LCSR_INTM2_SYSFLM_M (3<<18) /* System Fail */ -#define TSI148_LCSR_INTM2_ACFLM_M (3<<16) /* AC Fail */ -#define TSI148_LCSR_INTM2_IRQ7M_M (3<<14) /* IRQ7 */ -#define TSI148_LCSR_INTM2_IRQ6M_M (3<<12) /* IRQ6 */ -#define TSI148_LCSR_INTM2_IRQ5M_M (3<<10) /* IRQ5 */ -#define TSI148_LCSR_INTM2_IRQ4M_M (3<<8) /* IRQ4 */ -#define TSI148_LCSR_INTM2_IRQ3M_M (3<<6) /* IRQ3 */ -#define TSI148_LCSR_INTM2_IRQ2M_M (3<<4) /* IRQ2 */ -#define TSI148_LCSR_INTM2_IRQ1M_M (3<<2) /* IRQ1 */ - -/* - * DMA Control (0-1) Registers CRG + $500 - */ -#define TSI148_LCSR_DCTL_ABT (1<<27) /* Abort */ -#define TSI148_LCSR_DCTL_PAU (1<<26) /* Pause */ -#define TSI148_LCSR_DCTL_DGO (1<<25) /* DMA Go */ - -#define TSI148_LCSR_DCTL_MOD (1<<23) /* Mode */ - -#define TSI148_LCSR_DCTL_VBKS_M (7<<12) /* VMEbus block Size MASK */ -#define TSI148_LCSR_DCTL_VBKS_32 (0<<12) /* VMEbus block Size 32 */ -#define TSI148_LCSR_DCTL_VBKS_64 (1<<12) /* VMEbus block Size 64 */ -#define TSI148_LCSR_DCTL_VBKS_128 (2<<12) /* VMEbus block Size 128 */ -#define TSI148_LCSR_DCTL_VBKS_256 (3<<12) /* VMEbus block Size 256 */ -#define TSI148_LCSR_DCTL_VBKS_512 (4<<12) /* VMEbus block Size 512 */ -#define TSI148_LCSR_DCTL_VBKS_1024 (5<<12) /* VMEbus block Size 1024 */ -#define TSI148_LCSR_DCTL_VBKS_2048 (6<<12) /* VMEbus block Size 2048 */ -#define TSI148_LCSR_DCTL_VBKS_4096 (7<<12) /* VMEbus block Size 4096 */ - -#define TSI148_LCSR_DCTL_VBOT_M (7<<8) /* VMEbus back-off MASK */ -#define TSI148_LCSR_DCTL_VBOT_0 (0<<8) /* VMEbus back-off 0us */ -#define TSI148_LCSR_DCTL_VBOT_1 (1<<8) /* VMEbus back-off 1us */ -#define TSI148_LCSR_DCTL_VBOT_2 (2<<8) /* VMEbus back-off 2us */ -#define TSI148_LCSR_DCTL_VBOT_4 (3<<8) /* VMEbus back-off 4us */ -#define TSI148_LCSR_DCTL_VBOT_8 (4<<8) /* VMEbus back-off 8us */ -#define TSI148_LCSR_DCTL_VBOT_16 (5<<8) /* VMEbus back-off 16us */ -#define TSI148_LCSR_DCTL_VBOT_32 (6<<8) /* VMEbus back-off 32us */ -#define TSI148_LCSR_DCTL_VBOT_64 (7<<8) /* VMEbus back-off 64us */ - -#define TSI148_LCSR_DCTL_PBKS_M (7<<4) /* PCI block size MASK */ -#define TSI148_LCSR_DCTL_PBKS_32 (0<<4) /* PCI block size 32 bytes */ -#define TSI148_LCSR_DCTL_PBKS_64 (1<<4) /* PCI block size 64 bytes */ -#define TSI148_LCSR_DCTL_PBKS_128 (2<<4) /* PCI block size 128 bytes */ -#define TSI148_LCSR_DCTL_PBKS_256 (3<<4) /* PCI block size 256 bytes */ -#define TSI148_LCSR_DCTL_PBKS_512 (4<<4) /* PCI block size 512 bytes */ -#define TSI148_LCSR_DCTL_PBKS_1024 (5<<4) /* PCI block size 1024 bytes */ -#define TSI148_LCSR_DCTL_PBKS_2048 (6<<4) /* PCI block size 2048 bytes */ -#define TSI148_LCSR_DCTL_PBKS_4096 (7<<4) /* PCI block size 4096 bytes */ - -#define TSI148_LCSR_DCTL_PBOT_M (7<<0) /* PCI back off MASK */ -#define TSI148_LCSR_DCTL_PBOT_0 (0<<0) /* PCI back off 0us */ -#define TSI148_LCSR_DCTL_PBOT_1 (1<<0) /* PCI back off 1us */ -#define TSI148_LCSR_DCTL_PBOT_2 (2<<0) /* PCI back off 2us */ -#define TSI148_LCSR_DCTL_PBOT_4 (3<<0) /* PCI back off 3us */ -#define TSI148_LCSR_DCTL_PBOT_8 (4<<0) /* PCI back off 4us */ -#define TSI148_LCSR_DCTL_PBOT_16 (5<<0) /* PCI back off 8us */ -#define TSI148_LCSR_DCTL_PBOT_32 (6<<0) /* PCI back off 16us */ -#define TSI148_LCSR_DCTL_PBOT_64 (7<<0) /* PCI back off 32us */ - -/* - * DMA Status Registers (0-1) CRG + $504 - */ -#define TSI148_LCSR_DSTA_SMA (1<<31) /* PCI Signalled Master Abt */ -#define TSI148_LCSR_DSTA_RTA (1<<30) /* PCI Received Target Abt */ -#define TSI148_LCSR_DSTA_MRC (1<<29) /* PCI Max Retry Count */ -#define TSI148_LCSR_DSTA_VBE (1<<28) /* VMEbus error */ -#define TSI148_LCSR_DSTA_ABT (1<<27) /* Abort */ -#define TSI148_LCSR_DSTA_PAU (1<<26) /* Pause */ -#define TSI148_LCSR_DSTA_DON (1<<25) /* Done */ -#define TSI148_LCSR_DSTA_BSY (1<<24) /* Busy */ - -/* - * DMA Current Link Address Lower (0-1) - */ -#define TSI148_LCSR_DCLAL_M (0x3FFFFFF<<6) /* Mask */ - -/* - * DMA Source Attribute (0-1) Reg - */ -#define TSI148_LCSR_DSAT_TYP_M (3<<28) /* Source Bus Type */ -#define TSI148_LCSR_DSAT_TYP_PCI (0<<28) /* PCI Bus */ -#define TSI148_LCSR_DSAT_TYP_VME (1<<28) /* VMEbus */ -#define TSI148_LCSR_DSAT_TYP_PAT (2<<28) /* Data Pattern */ - -#define TSI148_LCSR_DSAT_PSZ (1<<25) /* Pattern Size */ -#define TSI148_LCSR_DSAT_NIN (1<<24) /* No Increment */ - -#define TSI148_LCSR_DSAT_2eSSTM_M (3<<11) /* 2eSST Trans Rate Mask */ -#define TSI148_LCSR_DSAT_2eSSTM_160 (0<<11) /* 160 MB/s */ -#define TSI148_LCSR_DSAT_2eSSTM_267 (1<<11) /* 267 MB/s */ -#define TSI148_LCSR_DSAT_2eSSTM_320 (2<<11) /* 320 MB/s */ - -#define TSI148_LCSR_DSAT_TM_M (7<<8) /* Bus Transfer Protocol Mask */ -#define TSI148_LCSR_DSAT_TM_SCT (0<<8) /* SCT */ -#define TSI148_LCSR_DSAT_TM_BLT (1<<8) /* BLT */ -#define TSI148_LCSR_DSAT_TM_MBLT (2<<8) /* MBLT */ -#define TSI148_LCSR_DSAT_TM_2eVME (3<<8) /* 2eVME */ -#define TSI148_LCSR_DSAT_TM_2eSST (4<<8) /* 2eSST */ -#define TSI148_LCSR_DSAT_TM_2eSSTB (5<<8) /* 2eSST Broadcast */ - -#define TSI148_LCSR_DSAT_DBW_M (3<<6) /* Max Data Width MASK */ -#define TSI148_LCSR_DSAT_DBW_16 (0<<6) /* 16 Bits */ -#define TSI148_LCSR_DSAT_DBW_32 (1<<6) /* 32 Bits */ - -#define TSI148_LCSR_DSAT_SUP (1<<5) /* Supervisory Mode */ -#define TSI148_LCSR_DSAT_PGM (1<<4) /* Program Mode */ - -#define TSI148_LCSR_DSAT_AMODE_M (0xf<<0) /* Address Space Mask */ -#define TSI148_LCSR_DSAT_AMODE_A16 (0<<0) /* A16 */ -#define TSI148_LCSR_DSAT_AMODE_A24 (1<<0) /* A24 */ -#define TSI148_LCSR_DSAT_AMODE_A32 (2<<0) /* A32 */ -#define TSI148_LCSR_DSAT_AMODE_A64 (4<<0) /* A64 */ -#define TSI148_LCSR_DSAT_AMODE_CRCSR (5<<0) /* CR/CSR */ -#define TSI148_LCSR_DSAT_AMODE_USER1 (8<<0) /* User1 */ -#define TSI148_LCSR_DSAT_AMODE_USER2 (9<<0) /* User2 */ -#define TSI148_LCSR_DSAT_AMODE_USER3 (0xa<<0) /* User3 */ -#define TSI148_LCSR_DSAT_AMODE_USER4 (0xb<<0) /* User4 */ - -/* - * DMA Destination Attribute Registers (0-1) - */ -#define TSI148_LCSR_DDAT_TYP_PCI (0<<28) /* Destination PCI Bus */ -#define TSI148_LCSR_DDAT_TYP_VME (1<<28) /* Destination VMEbus */ - -#define TSI148_LCSR_DDAT_2eSSTM_M (3<<11) /* 2eSST Transfer Rate Mask */ -#define TSI148_LCSR_DDAT_2eSSTM_160 (0<<11) /* 160 MB/s */ -#define TSI148_LCSR_DDAT_2eSSTM_267 (1<<11) /* 267 MB/s */ -#define TSI148_LCSR_DDAT_2eSSTM_320 (2<<11) /* 320 MB/s */ - -#define TSI148_LCSR_DDAT_TM_M (7<<8) /* Bus Transfer Protocol Mask */ -#define TSI148_LCSR_DDAT_TM_SCT (0<<8) /* SCT */ -#define TSI148_LCSR_DDAT_TM_BLT (1<<8) /* BLT */ -#define TSI148_LCSR_DDAT_TM_MBLT (2<<8) /* MBLT */ -#define TSI148_LCSR_DDAT_TM_2eVME (3<<8) /* 2eVME */ -#define TSI148_LCSR_DDAT_TM_2eSST (4<<8) /* 2eSST */ -#define TSI148_LCSR_DDAT_TM_2eSSTB (5<<8) /* 2eSST Broadcast */ - -#define TSI148_LCSR_DDAT_DBW_M (3<<6) /* Max Data Width MASK */ -#define TSI148_LCSR_DDAT_DBW_16 (0<<6) /* 16 Bits */ -#define TSI148_LCSR_DDAT_DBW_32 (1<<6) /* 32 Bits */ - -#define TSI148_LCSR_DDAT_SUP (1<<5) /* Supervisory/User Access */ -#define TSI148_LCSR_DDAT_PGM (1<<4) /* Program/Data Access */ - -#define TSI148_LCSR_DDAT_AMODE_M (0xf<<0) /* Address Space Mask */ -#define TSI148_LCSR_DDAT_AMODE_A16 (0<<0) /* A16 */ -#define TSI148_LCSR_DDAT_AMODE_A24 (1<<0) /* A24 */ -#define TSI148_LCSR_DDAT_AMODE_A32 (2<<0) /* A32 */ -#define TSI148_LCSR_DDAT_AMODE_A64 (4<<0) /* A64 */ -#define TSI148_LCSR_DDAT_AMODE_CRCSR (5<<0) /* CRC/SR */ -#define TSI148_LCSR_DDAT_AMODE_USER1 (8<<0) /* User1 */ -#define TSI148_LCSR_DDAT_AMODE_USER2 (9<<0) /* User2 */ -#define TSI148_LCSR_DDAT_AMODE_USER3 (0xa<<0) /* User3 */ -#define TSI148_LCSR_DDAT_AMODE_USER4 (0xb<<0) /* User4 */ - -/* - * DMA Next Link Address Lower - */ -#define TSI148_LCSR_DNLAL_DNLAL_M (0x3FFFFFF<<6) /* Address Mask */ -#define TSI148_LCSR_DNLAL_LLA (1<<0) /* Last Link Address Indicator */ - -/* - * DMA 2eSST Broadcast Select - */ -#define TSI148_LCSR_DBS_M (0x1FFFFF<<0) /* Mask */ - -/* - * GCSR Register Group - */ - -/* - * GCSR Control and Status Register CRG + $604 - */ -#define TSI148_GCSR_GCTRL_LRST (1<<15) /* Local Reset */ -#define TSI148_GCSR_GCTRL_SFAILEN (1<<14) /* System Fail enable */ -#define TSI148_GCSR_GCTRL_BDFAILS (1<<13) /* Board Fail Status */ -#define TSI148_GCSR_GCTRL_SCON (1<<12) /* System Copntroller */ -#define TSI148_GCSR_GCTRL_MEN (1<<11) /* Module Enable (READY) */ - -#define TSI148_GCSR_GCTRL_LMI3S (1<<7) /* Loc Monitor 3 Int Status */ -#define TSI148_GCSR_GCTRL_LMI2S (1<<6) /* Loc Monitor 2 Int Status */ -#define TSI148_GCSR_GCTRL_LMI1S (1<<5) /* Loc Monitor 1 Int Status */ -#define TSI148_GCSR_GCTRL_LMI0S (1<<4) /* Loc Monitor 0 Int Status */ -#define TSI148_GCSR_GCTRL_MBI3S (1<<3) /* Mail box 3 Int Status */ -#define TSI148_GCSR_GCTRL_MBI2S (1<<2) /* Mail box 2 Int Status */ -#define TSI148_GCSR_GCTRL_MBI1S (1<<1) /* Mail box 1 Int Status */ -#define TSI148_GCSR_GCTRL_MBI0S (1<<0) /* Mail box 0 Int Status */ - -#define TSI148_GCSR_GAP (1<<5) /* Geographic Addr Parity */ -#define TSI148_GCSR_GA_M (0x1F<<0) /* Geographic Address Mask */ - -/* - * CR/CSR Register Group - */ - -/* - * CR/CSR Bit Clear Register CRG + $FF4 - */ -#define TSI148_CRCSR_CSRBCR_LRSTC (1<<7) /* Local Reset Clear */ -#define TSI148_CRCSR_CSRBCR_SFAILC (1<<6) /* System Fail Enable Clear */ -#define TSI148_CRCSR_CSRBCR_BDFAILS (1<<5) /* Board Fail Status */ -#define TSI148_CRCSR_CSRBCR_MENC (1<<4) /* Module Enable Clear */ -#define TSI148_CRCSR_CSRBCR_BERRSC (1<<3) /* Bus Error Status Clear */ - -/* - * CR/CSR Bit Set Register CRG+$FF8 - */ -#define TSI148_CRCSR_CSRBSR_LISTS (1<<7) /* Local Reset Clear */ -#define TSI148_CRCSR_CSRBSR_SFAILS (1<<6) /* System Fail Enable Clear */ -#define TSI148_CRCSR_CSRBSR_BDFAILS (1<<5) /* Board Fail Status */ -#define TSI148_CRCSR_CSRBSR_MENS (1<<4) /* Module Enable Clear */ -#define TSI148_CRCSR_CSRBSR_BERRS (1<<3) /* Bus Error Status Clear */ - -/* - * CR/CSR Base Address Register CRG + FFC - */ -#define TSI148_CRCSR_CBAR_M (0x1F<<3) /* Mask */ - -#endif /* TSI148_H */ diff --git a/drivers/staging/vme/devices/Kconfig b/drivers/staging/vme/devices/Kconfig index 55ec30c..d0cab17 100644 --- a/drivers/staging/vme/devices/Kconfig +++ b/drivers/staging/vme/devices/Kconfig @@ -2,6 +2,7 @@ comment "VME Device Drivers" config VME_USER tristate "VME user space access driver" + depends on STAGING help If you say Y here you want to be able to access a limited number of VME windows in a manner at least semi-compatible with the interface @@ -9,7 +10,7 @@ config VME_USER config VME_PIO2 tristate "GE PIO2 VME" - depends on GPIOLIB + depends on STAGING && GPIOLIB help Say Y here to include support for the GE PIO2. The PIO2 is a 6U VME slave card, implementing 32 solid-state relay switched IO lines, in diff --git a/drivers/staging/vme/devices/vme_pio2_cntr.c b/drivers/staging/vme/devices/vme_pio2_cntr.c index 08e0d59..6335471 100644 --- a/drivers/staging/vme/devices/vme_pio2_cntr.c +++ b/drivers/staging/vme/devices/vme_pio2_cntr.c @@ -17,8 +17,8 @@ #include #include #include +#include -#include "../vme.h" #include "vme_pio2.h" static int pio2_cntr_irq_set(struct pio2_card *card, int id) diff --git a/drivers/staging/vme/devices/vme_pio2_core.c b/drivers/staging/vme/devices/vme_pio2_core.c index d476b2e..78228d4 100644 --- a/drivers/staging/vme/devices/vme_pio2_core.c +++ b/drivers/staging/vme/devices/vme_pio2_core.c @@ -19,8 +19,8 @@ #include #include #include +#include -#include "../vme.h" #include "vme_pio2.h" diff --git a/drivers/staging/vme/devices/vme_pio2_gpio.c b/drivers/staging/vme/devices/vme_pio2_gpio.c index 9c459c1..ad76a47 100644 --- a/drivers/staging/vme/devices/vme_pio2_gpio.c +++ b/drivers/staging/vme/devices/vme_pio2_gpio.c @@ -20,8 +20,8 @@ #include #include #include +#include -#include "../vme.h" #include "vme_pio2.h" static const char driver_name[] = "pio2_gpio"; diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index 10269d5..e24a6f9 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -36,8 +36,8 @@ #include #include +#include -#include "../vme.h" #include "vme_user.h" static DEFINE_MUTEX(vme_user_mutex); diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c deleted file mode 100644 index fd51c2d..0000000 --- a/drivers/staging/vme/vme.c +++ /dev/null @@ -1,1517 +0,0 @@ -/* - * VME Bridge Framework - * - * Author: Martyn Welch - * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. - * - * Based on work by Tom Armistead and Ajit Prem - * Copyright 2004 Motorola 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "vme.h" -#include "vme_bridge.h" - -/* Bitmask and list of registered buses both protected by common mutex */ -static unsigned int vme_bus_numbers; -static LIST_HEAD(vme_bus_list); -static DEFINE_MUTEX(vme_buses_lock); - -static void __exit vme_exit(void); -static int __init vme_init(void); - -static struct vme_dev *dev_to_vme_dev(struct device *dev) -{ - return container_of(dev, struct vme_dev, dev); -} - -/* - * Find the bridge that the resource is associated with. - */ -static struct vme_bridge *find_bridge(struct vme_resource *resource) -{ - /* Get list to search */ - switch (resource->type) { - case VME_MASTER: - return list_entry(resource->entry, struct vme_master_resource, - list)->parent; - break; - case VME_SLAVE: - return list_entry(resource->entry, struct vme_slave_resource, - list)->parent; - break; - case VME_DMA: - return list_entry(resource->entry, struct vme_dma_resource, - list)->parent; - break; - case VME_LM: - return list_entry(resource->entry, struct vme_lm_resource, - list)->parent; - break; - default: - printk(KERN_ERR "Unknown resource type\n"); - return NULL; - break; - } -} - -/* - * Allocate a contiguous block of memory for use by the driver. This is used to - * create the buffers for the slave windows. - */ -void *vme_alloc_consistent(struct vme_resource *resource, size_t size, - dma_addr_t *dma) -{ - struct vme_bridge *bridge; - - if (resource == NULL) { - printk(KERN_ERR "No resource\n"); - return NULL; - } - - bridge = find_bridge(resource); - if (bridge == NULL) { - printk(KERN_ERR "Can't find bridge\n"); - return NULL; - } - - if (bridge->parent == NULL) { - printk(KERN_ERR "Dev entry NULL for bridge %s\n", bridge->name); - return NULL; - } - - if (bridge->alloc_consistent == NULL) { - printk(KERN_ERR "alloc_consistent not supported by bridge %s\n", - bridge->name); - return NULL; - } - - return bridge->alloc_consistent(bridge->parent, size, dma); -} -EXPORT_SYMBOL(vme_alloc_consistent); - -/* - * Free previously allocated contiguous block of memory. - */ -void vme_free_consistent(struct vme_resource *resource, size_t size, - void *vaddr, dma_addr_t dma) -{ - struct vme_bridge *bridge; - - if (resource == NULL) { - printk(KERN_ERR "No resource\n"); - return; - } - - bridge = find_bridge(resource); - if (bridge == NULL) { - printk(KERN_ERR "Can't find bridge\n"); - return; - } - - if (bridge->parent == NULL) { - printk(KERN_ERR "Dev entry NULL for bridge %s\n", bridge->name); - return; - } - - if (bridge->free_consistent == NULL) { - printk(KERN_ERR "free_consistent not supported by bridge %s\n", - bridge->name); - return; - } - - bridge->free_consistent(bridge->parent, size, vaddr, dma); -} -EXPORT_SYMBOL(vme_free_consistent); - -size_t vme_get_size(struct vme_resource *resource) -{ - int enabled, retval; - unsigned long long base, size; - dma_addr_t buf_base; - u32 aspace, cycle, dwidth; - - switch (resource->type) { - case VME_MASTER: - retval = vme_master_get(resource, &enabled, &base, &size, - &aspace, &cycle, &dwidth); - - return size; - break; - case VME_SLAVE: - retval = vme_slave_get(resource, &enabled, &base, &size, - &buf_base, &aspace, &cycle); - - return size; - break; - case VME_DMA: - return 0; - break; - default: - printk(KERN_ERR "Unknown resource type\n"); - return 0; - break; - } -} -EXPORT_SYMBOL(vme_get_size); - -static int vme_check_window(u32 aspace, unsigned long long vme_base, - unsigned long long size) -{ - int retval = 0; - - switch (aspace) { - case VME_A16: - if (((vme_base + size) > VME_A16_MAX) || - (vme_base > VME_A16_MAX)) - retval = -EFAULT; - break; - case VME_A24: - if (((vme_base + size) > VME_A24_MAX) || - (vme_base > VME_A24_MAX)) - retval = -EFAULT; - break; - case VME_A32: - if (((vme_base + size) > VME_A32_MAX) || - (vme_base > VME_A32_MAX)) - retval = -EFAULT; - break; - case VME_A64: - /* - * Any value held in an unsigned long long can be used as the - * base - */ - break; - case VME_CRCSR: - if (((vme_base + size) > VME_CRCSR_MAX) || - (vme_base > VME_CRCSR_MAX)) - retval = -EFAULT; - break; - case VME_USER1: - case VME_USER2: - case VME_USER3: - case VME_USER4: - /* User Defined */ - break; - default: - printk(KERN_ERR "Invalid address space\n"); - retval = -EINVAL; - break; - } - - return retval; -} - -/* - * Request a slave image with specific attributes, return some unique - * identifier. - */ -struct vme_resource *vme_slave_request(struct vme_dev *vdev, u32 address, - u32 cycle) -{ - struct vme_bridge *bridge; - struct list_head *slave_pos = NULL; - struct vme_slave_resource *allocated_image = NULL; - struct vme_slave_resource *slave_image = NULL; - struct vme_resource *resource = NULL; - - bridge = vdev->bridge; - if (bridge == NULL) { - printk(KERN_ERR "Can't find VME bus\n"); - goto err_bus; - } - - /* Loop through slave resources */ - list_for_each(slave_pos, &bridge->slave_resources) { - slave_image = list_entry(slave_pos, - struct vme_slave_resource, list); - - if (slave_image == NULL) { - printk(KERN_ERR "Registered NULL Slave resource\n"); - continue; - } - - /* Find an unlocked and compatible image */ - mutex_lock(&slave_image->mtx); - if (((slave_image->address_attr & address) == address) && - ((slave_image->cycle_attr & cycle) == cycle) && - (slave_image->locked == 0)) { - - slave_image->locked = 1; - mutex_unlock(&slave_image->mtx); - allocated_image = slave_image; - break; - } - mutex_unlock(&slave_image->mtx); - } - - /* No free image */ - if (allocated_image == NULL) - goto err_image; - - resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL); - if (resource == NULL) { - printk(KERN_WARNING "Unable to allocate resource structure\n"); - goto err_alloc; - } - resource->type = VME_SLAVE; - resource->entry = &allocated_image->list; - - return resource; - -err_alloc: - /* Unlock image */ - mutex_lock(&slave_image->mtx); - slave_image->locked = 0; - mutex_unlock(&slave_image->mtx); -err_image: -err_bus: - return NULL; -} -EXPORT_SYMBOL(vme_slave_request); - -int vme_slave_set(struct vme_resource *resource, int enabled, - unsigned long long vme_base, unsigned long long size, - dma_addr_t buf_base, u32 aspace, u32 cycle) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_slave_resource *image; - int retval; - - if (resource->type != VME_SLAVE) { - printk(KERN_ERR "Not a slave resource\n"); - return -EINVAL; - } - - image = list_entry(resource->entry, struct vme_slave_resource, list); - - if (bridge->slave_set == NULL) { - printk(KERN_ERR "Function not supported\n"); - return -ENOSYS; - } - - if (!(((image->address_attr & aspace) == aspace) && - ((image->cycle_attr & cycle) == cycle))) { - printk(KERN_ERR "Invalid attributes\n"); - return -EINVAL; - } - - retval = vme_check_window(aspace, vme_base, size); - if (retval) - return retval; - - return bridge->slave_set(image, enabled, vme_base, size, buf_base, - aspace, cycle); -} -EXPORT_SYMBOL(vme_slave_set); - -int vme_slave_get(struct vme_resource *resource, int *enabled, - unsigned long long *vme_base, unsigned long long *size, - dma_addr_t *buf_base, u32 *aspace, u32 *cycle) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_slave_resource *image; - - if (resource->type != VME_SLAVE) { - printk(KERN_ERR "Not a slave resource\n"); - return -EINVAL; - } - - image = list_entry(resource->entry, struct vme_slave_resource, list); - - if (bridge->slave_get == NULL) { - printk(KERN_ERR "vme_slave_get not supported\n"); - return -EINVAL; - } - - return bridge->slave_get(image, enabled, vme_base, size, buf_base, - aspace, cycle); -} -EXPORT_SYMBOL(vme_slave_get); - -void vme_slave_free(struct vme_resource *resource) -{ - struct vme_slave_resource *slave_image; - - if (resource->type != VME_SLAVE) { - printk(KERN_ERR "Not a slave resource\n"); - return; - } - - slave_image = list_entry(resource->entry, struct vme_slave_resource, - list); - if (slave_image == NULL) { - printk(KERN_ERR "Can't find slave resource\n"); - return; - } - - /* Unlock image */ - mutex_lock(&slave_image->mtx); - if (slave_image->locked == 0) - printk(KERN_ERR "Image is already free\n"); - - slave_image->locked = 0; - mutex_unlock(&slave_image->mtx); - - /* Free up resource memory */ - kfree(resource); -} -EXPORT_SYMBOL(vme_slave_free); - -/* - * Request a master image with specific attributes, return some unique - * identifier. - */ -struct vme_resource *vme_master_request(struct vme_dev *vdev, u32 address, - u32 cycle, u32 dwidth) -{ - struct vme_bridge *bridge; - struct list_head *master_pos = NULL; - struct vme_master_resource *allocated_image = NULL; - struct vme_master_resource *master_image = NULL; - struct vme_resource *resource = NULL; - - bridge = vdev->bridge; - if (bridge == NULL) { - printk(KERN_ERR "Can't find VME bus\n"); - goto err_bus; - } - - /* Loop through master resources */ - list_for_each(master_pos, &bridge->master_resources) { - master_image = list_entry(master_pos, - struct vme_master_resource, list); - - if (master_image == NULL) { - printk(KERN_WARNING "Registered NULL master resource\n"); - continue; - } - - /* Find an unlocked and compatible image */ - spin_lock(&master_image->lock); - if (((master_image->address_attr & address) == address) && - ((master_image->cycle_attr & cycle) == cycle) && - ((master_image->width_attr & dwidth) == dwidth) && - (master_image->locked == 0)) { - - master_image->locked = 1; - spin_unlock(&master_image->lock); - allocated_image = master_image; - break; - } - spin_unlock(&master_image->lock); - } - - /* Check to see if we found a resource */ - if (allocated_image == NULL) { - printk(KERN_ERR "Can't find a suitable resource\n"); - goto err_image; - } - - resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL); - if (resource == NULL) { - printk(KERN_ERR "Unable to allocate resource structure\n"); - goto err_alloc; - } - resource->type = VME_MASTER; - resource->entry = &allocated_image->list; - - return resource; - -err_alloc: - /* Unlock image */ - spin_lock(&master_image->lock); - master_image->locked = 0; - spin_unlock(&master_image->lock); -err_image: -err_bus: - return NULL; -} -EXPORT_SYMBOL(vme_master_request); - -int vme_master_set(struct vme_resource *resource, int enabled, - unsigned long long vme_base, unsigned long long size, u32 aspace, - u32 cycle, u32 dwidth) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_master_resource *image; - int retval; - - if (resource->type != VME_MASTER) { - printk(KERN_ERR "Not a master resource\n"); - return -EINVAL; - } - - image = list_entry(resource->entry, struct vme_master_resource, list); - - if (bridge->master_set == NULL) { - printk(KERN_WARNING "vme_master_set not supported\n"); - return -EINVAL; - } - - if (!(((image->address_attr & aspace) == aspace) && - ((image->cycle_attr & cycle) == cycle) && - ((image->width_attr & dwidth) == dwidth))) { - printk(KERN_WARNING "Invalid attributes\n"); - return -EINVAL; - } - - retval = vme_check_window(aspace, vme_base, size); - if (retval) - return retval; - - return bridge->master_set(image, enabled, vme_base, size, aspace, - cycle, dwidth); -} -EXPORT_SYMBOL(vme_master_set); - -int vme_master_get(struct vme_resource *resource, int *enabled, - unsigned long long *vme_base, unsigned long long *size, u32 *aspace, - u32 *cycle, u32 *dwidth) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_master_resource *image; - - if (resource->type != VME_MASTER) { - printk(KERN_ERR "Not a master resource\n"); - return -EINVAL; - } - - image = list_entry(resource->entry, struct vme_master_resource, list); - - if (bridge->master_get == NULL) { - printk(KERN_WARNING "vme_master_set not supported\n"); - return -EINVAL; - } - - return bridge->master_get(image, enabled, vme_base, size, aspace, - cycle, dwidth); -} -EXPORT_SYMBOL(vme_master_get); - -/* - * Read data out of VME space into a buffer. - */ -ssize_t vme_master_read(struct vme_resource *resource, void *buf, size_t count, - loff_t offset) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_master_resource *image; - size_t length; - - if (bridge->master_read == NULL) { - printk(KERN_WARNING "Reading from resource not supported\n"); - return -EINVAL; - } - - if (resource->type != VME_MASTER) { - printk(KERN_ERR "Not a master resource\n"); - return -EINVAL; - } - - image = list_entry(resource->entry, struct vme_master_resource, list); - - length = vme_get_size(resource); - - if (offset > length) { - printk(KERN_WARNING "Invalid Offset\n"); - return -EFAULT; - } - - if ((offset + count) > length) - count = length - offset; - - return bridge->master_read(image, buf, count, offset); - -} -EXPORT_SYMBOL(vme_master_read); - -/* - * Write data out to VME space from a buffer. - */ -ssize_t vme_master_write(struct vme_resource *resource, void *buf, - size_t count, loff_t offset) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_master_resource *image; - size_t length; - - if (bridge->master_write == NULL) { - printk(KERN_WARNING "Writing to resource not supported\n"); - return -EINVAL; - } - - if (resource->type != VME_MASTER) { - printk(KERN_ERR "Not a master resource\n"); - return -EINVAL; - } - - image = list_entry(resource->entry, struct vme_master_resource, list); - - length = vme_get_size(resource); - - if (offset > length) { - printk(KERN_WARNING "Invalid Offset\n"); - return -EFAULT; - } - - if ((offset + count) > length) - count = length - offset; - - return bridge->master_write(image, buf, count, offset); -} -EXPORT_SYMBOL(vme_master_write); - -/* - * Perform RMW cycle to provided location. - */ -unsigned int vme_master_rmw(struct vme_resource *resource, unsigned int mask, - unsigned int compare, unsigned int swap, loff_t offset) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_master_resource *image; - - if (bridge->master_rmw == NULL) { - printk(KERN_WARNING "Writing to resource not supported\n"); - return -EINVAL; - } - - if (resource->type != VME_MASTER) { - printk(KERN_ERR "Not a master resource\n"); - return -EINVAL; - } - - image = list_entry(resource->entry, struct vme_master_resource, list); - - return bridge->master_rmw(image, mask, compare, swap, offset); -} -EXPORT_SYMBOL(vme_master_rmw); - -void vme_master_free(struct vme_resource *resource) -{ - struct vme_master_resource *master_image; - - if (resource->type != VME_MASTER) { - printk(KERN_ERR "Not a master resource\n"); - return; - } - - master_image = list_entry(resource->entry, struct vme_master_resource, - list); - if (master_image == NULL) { - printk(KERN_ERR "Can't find master resource\n"); - return; - } - - /* Unlock image */ - spin_lock(&master_image->lock); - if (master_image->locked == 0) - printk(KERN_ERR "Image is already free\n"); - - master_image->locked = 0; - spin_unlock(&master_image->lock); - - /* Free up resource memory */ - kfree(resource); -} -EXPORT_SYMBOL(vme_master_free); - -/* - * Request a DMA controller with specific attributes, return some unique - * identifier. - */ -struct vme_resource *vme_dma_request(struct vme_dev *vdev, u32 route) -{ - struct vme_bridge *bridge; - struct list_head *dma_pos = NULL; - struct vme_dma_resource *allocated_ctrlr = NULL; - struct vme_dma_resource *dma_ctrlr = NULL; - struct vme_resource *resource = NULL; - - /* XXX Not checking resource attributes */ - printk(KERN_ERR "No VME resource Attribute tests done\n"); - - bridge = vdev->bridge; - if (bridge == NULL) { - printk(KERN_ERR "Can't find VME bus\n"); - goto err_bus; - } - - /* Loop through DMA resources */ - list_for_each(dma_pos, &bridge->dma_resources) { - dma_ctrlr = list_entry(dma_pos, - struct vme_dma_resource, list); - - if (dma_ctrlr == NULL) { - printk(KERN_ERR "Registered NULL DMA resource\n"); - continue; - } - - /* Find an unlocked and compatible controller */ - mutex_lock(&dma_ctrlr->mtx); - if (((dma_ctrlr->route_attr & route) == route) && - (dma_ctrlr->locked == 0)) { - - dma_ctrlr->locked = 1; - mutex_unlock(&dma_ctrlr->mtx); - allocated_ctrlr = dma_ctrlr; - break; - } - mutex_unlock(&dma_ctrlr->mtx); - } - - /* Check to see if we found a resource */ - if (allocated_ctrlr == NULL) - goto err_ctrlr; - - resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL); - if (resource == NULL) { - printk(KERN_WARNING "Unable to allocate resource structure\n"); - goto err_alloc; - } - resource->type = VME_DMA; - resource->entry = &allocated_ctrlr->list; - - return resource; - -err_alloc: - /* Unlock image */ - mutex_lock(&dma_ctrlr->mtx); - dma_ctrlr->locked = 0; - mutex_unlock(&dma_ctrlr->mtx); -err_ctrlr: -err_bus: - return NULL; -} -EXPORT_SYMBOL(vme_dma_request); - -/* - * Start new list - */ -struct vme_dma_list *vme_new_dma_list(struct vme_resource *resource) -{ - struct vme_dma_resource *ctrlr; - struct vme_dma_list *dma_list; - - if (resource->type != VME_DMA) { - printk(KERN_ERR "Not a DMA resource\n"); - return NULL; - } - - ctrlr = list_entry(resource->entry, struct vme_dma_resource, list); - - dma_list = kmalloc(sizeof(struct vme_dma_list), GFP_KERNEL); - if (dma_list == NULL) { - printk(KERN_ERR "Unable to allocate memory for new dma list\n"); - return NULL; - } - INIT_LIST_HEAD(&dma_list->entries); - dma_list->parent = ctrlr; - mutex_init(&dma_list->mtx); - - return dma_list; -} -EXPORT_SYMBOL(vme_new_dma_list); - -/* - * Create "Pattern" type attributes - */ -struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, u32 type) -{ - struct vme_dma_attr *attributes; - struct vme_dma_pattern *pattern_attr; - - attributes = kmalloc(sizeof(struct vme_dma_attr), GFP_KERNEL); - if (attributes == NULL) { - printk(KERN_ERR "Unable to allocate memory for attributes structure\n"); - goto err_attr; - } - - pattern_attr = kmalloc(sizeof(struct vme_dma_pattern), GFP_KERNEL); - if (pattern_attr == NULL) { - printk(KERN_ERR "Unable to allocate memory for pattern attributes\n"); - goto err_pat; - } - - attributes->type = VME_DMA_PATTERN; - attributes->private = (void *)pattern_attr; - - pattern_attr->pattern = pattern; - pattern_attr->type = type; - - return attributes; - -err_pat: - kfree(attributes); -err_attr: - return NULL; -} -EXPORT_SYMBOL(vme_dma_pattern_attribute); - -/* - * Create "PCI" type attributes - */ -struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t address) -{ - struct vme_dma_attr *attributes; - struct vme_dma_pci *pci_attr; - - /* XXX Run some sanity checks here */ - - attributes = kmalloc(sizeof(struct vme_dma_attr), GFP_KERNEL); - if (attributes == NULL) { - printk(KERN_ERR "Unable to allocate memory for attributes structure\n"); - goto err_attr; - } - - pci_attr = kmalloc(sizeof(struct vme_dma_pci), GFP_KERNEL); - if (pci_attr == NULL) { - printk(KERN_ERR "Unable to allocate memory for pci attributes\n"); - goto err_pci; - } - - - - attributes->type = VME_DMA_PCI; - attributes->private = (void *)pci_attr; - - pci_attr->address = address; - - return attributes; - -err_pci: - kfree(attributes); -err_attr: - return NULL; -} -EXPORT_SYMBOL(vme_dma_pci_attribute); - -/* - * Create "VME" type attributes - */ -struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long address, - u32 aspace, u32 cycle, u32 dwidth) -{ - struct vme_dma_attr *attributes; - struct vme_dma_vme *vme_attr; - - attributes = kmalloc( - sizeof(struct vme_dma_attr), GFP_KERNEL); - if (attributes == NULL) { - printk(KERN_ERR "Unable to allocate memory for attributes structure\n"); - goto err_attr; - } - - vme_attr = kmalloc(sizeof(struct vme_dma_vme), GFP_KERNEL); - if (vme_attr == NULL) { - printk(KERN_ERR "Unable to allocate memory for vme attributes\n"); - goto err_vme; - } - - attributes->type = VME_DMA_VME; - attributes->private = (void *)vme_attr; - - vme_attr->address = address; - vme_attr->aspace = aspace; - vme_attr->cycle = cycle; - vme_attr->dwidth = dwidth; - - return attributes; - -err_vme: - kfree(attributes); -err_attr: - return NULL; -} -EXPORT_SYMBOL(vme_dma_vme_attribute); - -/* - * Free attribute - */ -void vme_dma_free_attribute(struct vme_dma_attr *attributes) -{ - kfree(attributes->private); - kfree(attributes); -} -EXPORT_SYMBOL(vme_dma_free_attribute); - -int vme_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, - struct vme_dma_attr *dest, size_t count) -{ - struct vme_bridge *bridge = list->parent->parent; - int retval; - - if (bridge->dma_list_add == NULL) { - printk(KERN_WARNING "Link List DMA generation not supported\n"); - return -EINVAL; - } - - if (!mutex_trylock(&list->mtx)) { - printk(KERN_ERR "Link List already submitted\n"); - return -EINVAL; - } - - retval = bridge->dma_list_add(list, src, dest, count); - - mutex_unlock(&list->mtx); - - return retval; -} -EXPORT_SYMBOL(vme_dma_list_add); - -int vme_dma_list_exec(struct vme_dma_list *list) -{ - struct vme_bridge *bridge = list->parent->parent; - int retval; - - if (bridge->dma_list_exec == NULL) { - printk(KERN_ERR "Link List DMA execution not supported\n"); - return -EINVAL; - } - - mutex_lock(&list->mtx); - - retval = bridge->dma_list_exec(list); - - mutex_unlock(&list->mtx); - - return retval; -} -EXPORT_SYMBOL(vme_dma_list_exec); - -int vme_dma_list_free(struct vme_dma_list *list) -{ - struct vme_bridge *bridge = list->parent->parent; - int retval; - - if (bridge->dma_list_empty == NULL) { - printk(KERN_WARNING "Emptying of Link Lists not supported\n"); - return -EINVAL; - } - - if (!mutex_trylock(&list->mtx)) { - printk(KERN_ERR "Link List in use\n"); - return -EINVAL; - } - - /* - * Empty out all of the entries from the dma list. We need to go to the - * low level driver as dma entries are driver specific. - */ - retval = bridge->dma_list_empty(list); - if (retval) { - printk(KERN_ERR "Unable to empty link-list entries\n"); - mutex_unlock(&list->mtx); - return retval; - } - mutex_unlock(&list->mtx); - kfree(list); - - return retval; -} -EXPORT_SYMBOL(vme_dma_list_free); - -int vme_dma_free(struct vme_resource *resource) -{ - struct vme_dma_resource *ctrlr; - - if (resource->type != VME_DMA) { - printk(KERN_ERR "Not a DMA resource\n"); - return -EINVAL; - } - - ctrlr = list_entry(resource->entry, struct vme_dma_resource, list); - - if (!mutex_trylock(&ctrlr->mtx)) { - printk(KERN_ERR "Resource busy, can't free\n"); - return -EBUSY; - } - - if (!(list_empty(&ctrlr->pending) && list_empty(&ctrlr->running))) { - printk(KERN_WARNING "Resource still processing transfers\n"); - mutex_unlock(&ctrlr->mtx); - return -EBUSY; - } - - ctrlr->locked = 0; - - mutex_unlock(&ctrlr->mtx); - - return 0; -} -EXPORT_SYMBOL(vme_dma_free); - -void vme_irq_handler(struct vme_bridge *bridge, int level, int statid) -{ - void (*call)(int, int, void *); - void *priv_data; - - call = bridge->irq[level - 1].callback[statid].func; - priv_data = bridge->irq[level - 1].callback[statid].priv_data; - - if (call != NULL) - call(level, statid, priv_data); - else - printk(KERN_WARNING "Spurilous VME interrupt, level:%x, vector:%x\n", - level, statid); -} -EXPORT_SYMBOL(vme_irq_handler); - -int vme_irq_request(struct vme_dev *vdev, int level, int statid, - void (*callback)(int, int, void *), - void *priv_data) -{ - struct vme_bridge *bridge; - - bridge = vdev->bridge; - if (bridge == NULL) { - printk(KERN_ERR "Can't find VME bus\n"); - return -EINVAL; - } - - if ((level < 1) || (level > 7)) { - printk(KERN_ERR "Invalid interrupt level\n"); - return -EINVAL; - } - - if (bridge->irq_set == NULL) { - printk(KERN_ERR "Configuring interrupts not supported\n"); - return -EINVAL; - } - - mutex_lock(&bridge->irq_mtx); - - if (bridge->irq[level - 1].callback[statid].func) { - mutex_unlock(&bridge->irq_mtx); - printk(KERN_WARNING "VME Interrupt already taken\n"); - return -EBUSY; - } - - bridge->irq[level - 1].count++; - bridge->irq[level - 1].callback[statid].priv_data = priv_data; - bridge->irq[level - 1].callback[statid].func = callback; - - /* Enable IRQ level */ - bridge->irq_set(bridge, level, 1, 1); - - mutex_unlock(&bridge->irq_mtx); - - return 0; -} -EXPORT_SYMBOL(vme_irq_request); - -void vme_irq_free(struct vme_dev *vdev, int level, int statid) -{ - struct vme_bridge *bridge; - - bridge = vdev->bridge; - if (bridge == NULL) { - printk(KERN_ERR "Can't find VME bus\n"); - return; - } - - if ((level < 1) || (level > 7)) { - printk(KERN_ERR "Invalid interrupt level\n"); - return; - } - - if (bridge->irq_set == NULL) { - printk(KERN_ERR "Configuring interrupts not supported\n"); - return; - } - - mutex_lock(&bridge->irq_mtx); - - bridge->irq[level - 1].count--; - - /* Disable IRQ level if no more interrupts attached at this level*/ - if (bridge->irq[level - 1].count == 0) - bridge->irq_set(bridge, level, 0, 1); - - bridge->irq[level - 1].callback[statid].func = NULL; - bridge->irq[level - 1].callback[statid].priv_data = NULL; - - mutex_unlock(&bridge->irq_mtx); -} -EXPORT_SYMBOL(vme_irq_free); - -int vme_irq_generate(struct vme_dev *vdev, int level, int statid) -{ - struct vme_bridge *bridge; - - bridge = vdev->bridge; - if (bridge == NULL) { - printk(KERN_ERR "Can't find VME bus\n"); - return -EINVAL; - } - - if ((level < 1) || (level > 7)) { - printk(KERN_WARNING "Invalid interrupt level\n"); - return -EINVAL; - } - - if (bridge->irq_generate == NULL) { - printk(KERN_WARNING "Interrupt generation not supported\n"); - return -EINVAL; - } - - return bridge->irq_generate(bridge, level, statid); -} -EXPORT_SYMBOL(vme_irq_generate); - -/* - * Request the location monitor, return resource or NULL - */ -struct vme_resource *vme_lm_request(struct vme_dev *vdev) -{ - struct vme_bridge *bridge; - struct list_head *lm_pos = NULL; - struct vme_lm_resource *allocated_lm = NULL; - struct vme_lm_resource *lm = NULL; - struct vme_resource *resource = NULL; - - bridge = vdev->bridge; - if (bridge == NULL) { - printk(KERN_ERR "Can't find VME bus\n"); - goto err_bus; - } - - /* Loop through DMA resources */ - list_for_each(lm_pos, &bridge->lm_resources) { - lm = list_entry(lm_pos, - struct vme_lm_resource, list); - - if (lm == NULL) { - printk(KERN_ERR "Registered NULL Location Monitor resource\n"); - continue; - } - - /* Find an unlocked controller */ - mutex_lock(&lm->mtx); - if (lm->locked == 0) { - lm->locked = 1; - mutex_unlock(&lm->mtx); - allocated_lm = lm; - break; - } - mutex_unlock(&lm->mtx); - } - - /* Check to see if we found a resource */ - if (allocated_lm == NULL) - goto err_lm; - - resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL); - if (resource == NULL) { - printk(KERN_ERR "Unable to allocate resource structure\n"); - goto err_alloc; - } - resource->type = VME_LM; - resource->entry = &allocated_lm->list; - - return resource; - -err_alloc: - /* Unlock image */ - mutex_lock(&lm->mtx); - lm->locked = 0; - mutex_unlock(&lm->mtx); -err_lm: -err_bus: - return NULL; -} -EXPORT_SYMBOL(vme_lm_request); - -int vme_lm_count(struct vme_resource *resource) -{ - struct vme_lm_resource *lm; - - if (resource->type != VME_LM) { - printk(KERN_ERR "Not a Location Monitor resource\n"); - return -EINVAL; - } - - lm = list_entry(resource->entry, struct vme_lm_resource, list); - - return lm->monitors; -} -EXPORT_SYMBOL(vme_lm_count); - -int vme_lm_set(struct vme_resource *resource, unsigned long long lm_base, - u32 aspace, u32 cycle) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_lm_resource *lm; - - if (resource->type != VME_LM) { - printk(KERN_ERR "Not a Location Monitor resource\n"); - return -EINVAL; - } - - lm = list_entry(resource->entry, struct vme_lm_resource, list); - - if (bridge->lm_set == NULL) { - printk(KERN_ERR "vme_lm_set not supported\n"); - return -EINVAL; - } - - return bridge->lm_set(lm, lm_base, aspace, cycle); -} -EXPORT_SYMBOL(vme_lm_set); - -int vme_lm_get(struct vme_resource *resource, unsigned long long *lm_base, - u32 *aspace, u32 *cycle) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_lm_resource *lm; - - if (resource->type != VME_LM) { - printk(KERN_ERR "Not a Location Monitor resource\n"); - return -EINVAL; - } - - lm = list_entry(resource->entry, struct vme_lm_resource, list); - - if (bridge->lm_get == NULL) { - printk(KERN_ERR "vme_lm_get not supported\n"); - return -EINVAL; - } - - return bridge->lm_get(lm, lm_base, aspace, cycle); -} -EXPORT_SYMBOL(vme_lm_get); - -int vme_lm_attach(struct vme_resource *resource, int monitor, - void (*callback)(int)) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_lm_resource *lm; - - if (resource->type != VME_LM) { - printk(KERN_ERR "Not a Location Monitor resource\n"); - return -EINVAL; - } - - lm = list_entry(resource->entry, struct vme_lm_resource, list); - - if (bridge->lm_attach == NULL) { - printk(KERN_ERR "vme_lm_attach not supported\n"); - return -EINVAL; - } - - return bridge->lm_attach(lm, monitor, callback); -} -EXPORT_SYMBOL(vme_lm_attach); - -int vme_lm_detach(struct vme_resource *resource, int monitor) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_lm_resource *lm; - - if (resource->type != VME_LM) { - printk(KERN_ERR "Not a Location Monitor resource\n"); - return -EINVAL; - } - - lm = list_entry(resource->entry, struct vme_lm_resource, list); - - if (bridge->lm_detach == NULL) { - printk(KERN_ERR "vme_lm_detach not supported\n"); - return -EINVAL; - } - - return bridge->lm_detach(lm, monitor); -} -EXPORT_SYMBOL(vme_lm_detach); - -void vme_lm_free(struct vme_resource *resource) -{ - struct vme_lm_resource *lm; - - if (resource->type != VME_LM) { - printk(KERN_ERR "Not a Location Monitor resource\n"); - return; - } - - lm = list_entry(resource->entry, struct vme_lm_resource, list); - - mutex_lock(&lm->mtx); - - /* XXX - * Check to see that there aren't any callbacks still attached, if - * there are we should probably be detaching them! - */ - - lm->locked = 0; - - mutex_unlock(&lm->mtx); - - kfree(resource); -} -EXPORT_SYMBOL(vme_lm_free); - -int vme_slot_get(struct vme_dev *vdev) -{ - struct vme_bridge *bridge; - - bridge = vdev->bridge; - if (bridge == NULL) { - printk(KERN_ERR "Can't find VME bus\n"); - return -EINVAL; - } - - if (bridge->slot_get == NULL) { - printk(KERN_WARNING "vme_slot_get not supported\n"); - return -EINVAL; - } - - return bridge->slot_get(bridge); -} -EXPORT_SYMBOL(vme_slot_get); - - -/* - Bridge Registration --------------------------------------------------- */ - -static void vme_dev_release(struct device *dev) -{ - kfree(dev_to_vme_dev(dev)); -} - -int vme_register_bridge(struct vme_bridge *bridge) -{ - int i; - int ret = -1; - - mutex_lock(&vme_buses_lock); - for (i = 0; i < sizeof(vme_bus_numbers) * 8; i++) { - if ((vme_bus_numbers & (1 << i)) == 0) { - vme_bus_numbers |= (1 << i); - bridge->num = i; - INIT_LIST_HEAD(&bridge->devices); - list_add_tail(&bridge->bus_list, &vme_bus_list); - ret = 0; - break; - } - } - mutex_unlock(&vme_buses_lock); - - return ret; -} -EXPORT_SYMBOL(vme_register_bridge); - -void vme_unregister_bridge(struct vme_bridge *bridge) -{ - struct vme_dev *vdev; - struct vme_dev *tmp; - - mutex_lock(&vme_buses_lock); - vme_bus_numbers &= ~(1 << bridge->num); - list_for_each_entry_safe(vdev, tmp, &bridge->devices, bridge_list) { - list_del(&vdev->drv_list); - list_del(&vdev->bridge_list); - device_unregister(&vdev->dev); - } - list_del(&bridge->bus_list); - mutex_unlock(&vme_buses_lock); -} -EXPORT_SYMBOL(vme_unregister_bridge); - -/* - Driver Registration --------------------------------------------------- */ - -static int __vme_register_driver_bus(struct vme_driver *drv, - struct vme_bridge *bridge, unsigned int ndevs) -{ - int err; - unsigned int i; - struct vme_dev *vdev; - struct vme_dev *tmp; - - for (i = 0; i < ndevs; i++) { - vdev = kzalloc(sizeof(struct vme_dev), GFP_KERNEL); - if (!vdev) { - err = -ENOMEM; - goto err_devalloc; - } - vdev->num = i; - vdev->bridge = bridge; - vdev->dev.platform_data = drv; - vdev->dev.release = vme_dev_release; - vdev->dev.parent = bridge->parent; - vdev->dev.bus = &vme_bus_type; - dev_set_name(&vdev->dev, "%s.%u-%u", drv->name, bridge->num, - vdev->num); - - err = device_register(&vdev->dev); - if (err) - goto err_reg; - - if (vdev->dev.platform_data) { - list_add_tail(&vdev->drv_list, &drv->devices); - list_add_tail(&vdev->bridge_list, &bridge->devices); - } else - device_unregister(&vdev->dev); - } - return 0; - -err_reg: - kfree(vdev); -err_devalloc: - list_for_each_entry_safe(vdev, tmp, &drv->devices, drv_list) { - list_del(&vdev->drv_list); - list_del(&vdev->bridge_list); - device_unregister(&vdev->dev); - } - return err; -} - -static int __vme_register_driver(struct vme_driver *drv, unsigned int ndevs) -{ - struct vme_bridge *bridge; - int err = 0; - - mutex_lock(&vme_buses_lock); - list_for_each_entry(bridge, &vme_bus_list, bus_list) { - /* - * This cannot cause trouble as we already have vme_buses_lock - * and if the bridge is removed, it will have to go through - * vme_unregister_bridge() to do it (which calls remove() on - * the bridge which in turn tries to acquire vme_buses_lock and - * will have to wait). - */ - err = __vme_register_driver_bus(drv, bridge, ndevs); - if (err) - break; - } - mutex_unlock(&vme_buses_lock); - return err; -} - -int vme_register_driver(struct vme_driver *drv, unsigned int ndevs) -{ - int err; - - drv->driver.name = drv->name; - drv->driver.bus = &vme_bus_type; - INIT_LIST_HEAD(&drv->devices); - - err = driver_register(&drv->driver); - if (err) - return err; - - err = __vme_register_driver(drv, ndevs); - if (err) - driver_unregister(&drv->driver); - - return err; -} -EXPORT_SYMBOL(vme_register_driver); - -void vme_unregister_driver(struct vme_driver *drv) -{ - struct vme_dev *dev, *dev_tmp; - - mutex_lock(&vme_buses_lock); - list_for_each_entry_safe(dev, dev_tmp, &drv->devices, drv_list) { - list_del(&dev->drv_list); - list_del(&dev->bridge_list); - device_unregister(&dev->dev); - } - mutex_unlock(&vme_buses_lock); - - driver_unregister(&drv->driver); -} -EXPORT_SYMBOL(vme_unregister_driver); - -/* - Bus Registration ------------------------------------------------------ */ - -static int vme_bus_match(struct device *dev, struct device_driver *drv) -{ - struct vme_driver *vme_drv; - - vme_drv = container_of(drv, struct vme_driver, driver); - - if (dev->platform_data == vme_drv) { - struct vme_dev *vdev = dev_to_vme_dev(dev); - - if (vme_drv->match && vme_drv->match(vdev)) - return 1; - - dev->platform_data = NULL; - } - return 0; -} - -static int vme_bus_probe(struct device *dev) -{ - int retval = -ENODEV; - struct vme_driver *driver; - struct vme_dev *vdev = dev_to_vme_dev(dev); - - driver = dev->platform_data; - - if (driver->probe != NULL) - retval = driver->probe(vdev); - - return retval; -} - -static int vme_bus_remove(struct device *dev) -{ - int retval = -ENODEV; - struct vme_driver *driver; - struct vme_dev *vdev = dev_to_vme_dev(dev); - - driver = dev->platform_data; - - if (driver->remove != NULL) - retval = driver->remove(vdev); - - return retval; -} - -struct bus_type vme_bus_type = { - .name = "vme", - .match = vme_bus_match, - .probe = vme_bus_probe, - .remove = vme_bus_remove, -}; -EXPORT_SYMBOL(vme_bus_type); - -static int __init vme_init(void) -{ - return bus_register(&vme_bus_type); -} - -static void __exit vme_exit(void) -{ - bus_unregister(&vme_bus_type); -} - -MODULE_DESCRIPTION("VME bridge driver framework"); -MODULE_AUTHOR("Martyn Welch id.num >= USER_BUS_MAX) - return 0; - return 1; - } - -The '.probe' element should contain a pointer to the probe routine. The -probe routine is passed a 'struct vme_dev' pointer as an argument. The -'struct vme_dev' structure looks like the following: - - struct vme_dev { - int num; - struct vme_bridge *bridge; - struct device dev; - struct list_head drv_list; - struct list_head bridge_list; - }; - -Here, the 'num' field refers to the sequential device ID for this specific -driver. The bridge number (or bus number) can be accessed using -dev->bridge->num. - -A function is also provided to unregister the driver from the VME core and is -usually called from the device driver's exit routine: - - void vme_unregister_driver (struct vme_driver *driver); - - -Resource management -=================== - -Once a driver has registered with the VME core the provided match routine will -be called the number of times specified during the registration. If a match -succeeds, a non-zero value should be returned. A zero return value indicates -failure. For all successful matches, the probe routine of the corresponding -driver is called. The probe routine is passed a pointer to the devices -device structure. This pointer should be saved, it will be required for -requesting VME resources. - -The driver can request ownership of one or more master windows, slave windows -and/or dma channels. Rather than allowing the device driver to request a -specific window or DMA channel (which may be used by a different driver) this -driver allows a resource to be assigned based on the required attributes of the -driver in question: - - struct vme_resource * vme_master_request(struct vme_dev *dev, - u32 aspace, u32 cycle, u32 width); - - struct vme_resource * vme_slave_request(struct vme_dev *dev, u32 aspace, - u32 cycle); - - struct vme_resource *vme_dma_request(struct vme_dev *dev, u32 route); - -For slave windows these attributes are split into the VME address spaces that -need to be accessed in 'aspace' and VME bus cycle types required in 'cycle'. -Master windows add a further set of attributes in 'width' specifying the -required data transfer widths. These attributes are defined as bitmasks and as -such any combination of the attributes can be requested for a single window, -the core will assign a window that meets the requirements, returning a pointer -of type vme_resource that should be used to identify the allocated resource -when it is used. For DMA controllers, the request function requires the -potential direction of any transfers to be provided in the route attributes. -This is typically VME-to-MEM and/or MEM-to-VME, though some hardware can -support VME-to-VME and MEM-to-MEM transfers as well as test pattern generation. -If an unallocated window fitting the requirements can not be found a NULL -pointer will be returned. - -Functions are also provided to free window allocations once they are no longer -required. These functions should be passed the pointer to the resource provided -during resource allocation: - - void vme_master_free(struct vme_resource *res); - - void vme_slave_free(struct vme_resource *res); - - void vme_dma_free(struct vme_resource *res); - - -Master windows -============== - -Master windows provide access from the local processor[s] out onto the VME bus. -The number of windows available and the available access modes is dependent on -the underlying chipset. A window must be configured before it can be used. - - -Master window configuration ---------------------------- - -Once a master window has been assigned the following functions can be used to -configure it and retrieve the current settings: - - int vme_master_set (struct vme_resource *res, int enabled, - unsigned long long base, unsigned long long size, u32 aspace, - u32 cycle, u32 width); - - int vme_master_get (struct vme_resource *res, int *enabled, - unsigned long long *base, unsigned long long *size, u32 *aspace, - u32 *cycle, u32 *width); - -The address spaces, transfer widths and cycle types are the same as described -under resource management, however some of the options are mutually exclusive. -For example, only one address space may be specified. - -These functions return 0 on success or an error code should the call fail. - - -Master window access --------------------- - -The following functions can be used to read from and write to configured master -windows. These functions return the number of bytes copied: - - ssize_t vme_master_read(struct vme_resource *res, void *buf, - size_t count, loff_t offset); - - ssize_t vme_master_write(struct vme_resource *res, void *buf, - size_t count, loff_t offset); - -In addition to simple reads and writes, a function is provided to do a -read-modify-write transaction. This function returns the original value of the -VME bus location : - - unsigned int vme_master_rmw (struct vme_resource *res, - unsigned int mask, unsigned int compare, unsigned int swap, - loff_t offset); - -This functions by reading the offset, applying the mask. If the bits selected in -the mask match with the values of the corresponding bits in the compare field, -the value of swap is written the specified offset. - - -Slave windows -============= - -Slave windows provide devices on the VME bus access into mapped portions of the -local memory. The number of windows available and the access modes that can be -used is dependent on the underlying chipset. A window must be configured before -it can be used. - - -Slave window configuration --------------------------- - -Once a slave window has been assigned the following functions can be used to -configure it and retrieve the current settings: - - int vme_slave_set (struct vme_resource *res, int enabled, - unsigned long long base, unsigned long long size, - dma_addr_t mem, u32 aspace, u32 cycle); - - int vme_slave_get (struct vme_resource *res, int *enabled, - unsigned long long *base, unsigned long long *size, - dma_addr_t *mem, u32 *aspace, u32 *cycle); - -The address spaces, transfer widths and cycle types are the same as described -under resource management, however some of the options are mutually exclusive. -For example, only one address space may be specified. - -These functions return 0 on success or an error code should the call fail. - - -Slave window buffer allocation ------------------------------- - -Functions are provided to allow the user to allocate and free a contiguous -buffers which will be accessible by the VME bridge. These functions do not have -to be used, other methods can be used to allocate a buffer, though care must be -taken to ensure that they are contiguous and accessible by the VME bridge: - - void * vme_alloc_consistent(struct vme_resource *res, size_t size, - dma_addr_t *mem); - - void vme_free_consistent(struct vme_resource *res, size_t size, - void *virt, dma_addr_t mem); - - -Slave window access -------------------- - -Slave windows map local memory onto the VME bus, the standard methods for -accessing memory should be used. - - -DMA channels -============ - -The VME DMA transfer provides the ability to run link-list DMA transfers. The -API introduces the concept of DMA lists. Each DMA list is a link-list which can -be passed to a DMA controller. Multiple lists can be created, extended, -executed, reused and destroyed. - - -List Management ---------------- - -The following functions are provided to create and destroy DMA lists. Execution -of a list will not automatically destroy the list, thus enabling a list to be -reused for repetitive tasks: - - struct vme_dma_list *vme_new_dma_list(struct vme_resource *res); - - int vme_dma_list_free(struct vme_dma_list *list); - - -List Population ---------------- - -An item can be added to a list using the following function ( the source and -destination attributes need to be created before calling this function, this is -covered under "Transfer Attributes"): - - int vme_dma_list_add(struct vme_dma_list *list, - struct vme_dma_attr *src, struct vme_dma_attr *dest, - size_t count); - -NOTE: The detailed attributes of the transfers source and destination - are not checked until an entry is added to a DMA list, the request - for a DMA channel purely checks the directions in which the - controller is expected to transfer data. As a result it is - possible for this call to return an error, for example if the - source or destination is in an unsupported VME address space. - -Transfer Attributes -------------------- - -The attributes for the source and destination are handled separately from adding -an item to a list. This is due to the diverse attributes required for each type -of source and destination. There are functions to create attributes for PCI, VME -and pattern sources and destinations (where appropriate): - -Pattern source: - - struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, u32 type); - -PCI source or destination: - - struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t mem); - -VME source or destination: - - struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long base, - u32 aspace, u32 cycle, u32 width); - -The following function should be used to free an attribute: - - void vme_dma_free_attribute(struct vme_dma_attr *attr); - - -List Execution --------------- - -The following function queues a list for execution. The function will return -once the list has been executed: - - int vme_dma_list_exec(struct vme_dma_list *list); - - -Interrupts -========== - -The VME API provides functions to attach and detach callbacks to specific VME -level and status ID combinations and for the generation of VME interrupts with -specific VME level and status IDs. - - -Attaching Interrupt Handlers ----------------------------- - -The following functions can be used to attach and free a specific VME level and -status ID combination. Any given combination can only be assigned a single -callback function. A void pointer parameter is provided, the value of which is -passed to the callback function, the use of this pointer is user undefined: - - int vme_irq_request(struct vme_dev *dev, int level, int statid, - void (*callback)(int, int, void *), void *priv); - - void vme_irq_free(struct vme_dev *dev, int level, int statid); - -The callback parameters are as follows. Care must be taken in writing a callback -function, callback functions run in interrupt context: - - void callback(int level, int statid, void *priv); - - -Interrupt Generation --------------------- - -The following function can be used to generate a VME interrupt at a given VME -level and VME status ID: - - int vme_irq_generate(struct vme_dev *dev, int level, int statid); - - -Location monitors -================= - -The VME API provides the following functionality to configure the location -monitor. - - -Location Monitor Management ---------------------------- - -The following functions are provided to request the use of a block of location -monitors and to free them after they are no longer required: - - struct vme_resource * vme_lm_request(struct vme_dev *dev); - - void vme_lm_free(struct vme_resource * res); - -Each block may provide a number of location monitors, monitoring adjacent -locations. The following function can be used to determine how many locations -are provided: - - int vme_lm_count(struct vme_resource * res); - - -Location Monitor Configuration ------------------------------- - -Once a bank of location monitors has been allocated, the following functions -are provided to configure the location and mode of the location monitor: - - int vme_lm_set(struct vme_resource *res, unsigned long long base, - u32 aspace, u32 cycle); - - int vme_lm_get(struct vme_resource *res, unsigned long long *base, - u32 *aspace, u32 *cycle); - - -Location Monitor Use --------------------- - -The following functions allow a callback to be attached and detached from each -location monitor location. Each location monitor can monitor a number of -adjacent locations: - - int vme_lm_attach(struct vme_resource *res, int num, - void (*callback)(int)); - - int vme_lm_detach(struct vme_resource *res, int num); - -The callback function is declared as follows. - - void callback(int num); - - -Slot Detection -============== - -This function returns the slot ID of the provided bridge. - - int vme_slot_get(struct vme_dev *dev); diff --git a/drivers/staging/vme/vme_bridge.h b/drivers/staging/vme/vme_bridge.h deleted file mode 100644 index 934949a..0000000 --- a/drivers/staging/vme/vme_bridge.h +++ /dev/null @@ -1,174 +0,0 @@ -#ifndef _VME_BRIDGE_H_ -#define _VME_BRIDGE_H_ - -#define VME_CRCSR_BUF_SIZE (508*1024) -/* - * Resource structures - */ -struct vme_master_resource { - struct list_head list; - struct vme_bridge *parent; - /* - * We are likely to need to access the VME bus in interrupt context, so - * protect master routines with a spinlock rather than a mutex. - */ - spinlock_t lock; - int locked; - int number; - u32 address_attr; - u32 cycle_attr; - u32 width_attr; - struct resource bus_resource; - void __iomem *kern_base; -}; - -struct vme_slave_resource { - struct list_head list; - struct vme_bridge *parent; - struct mutex mtx; - int locked; - int number; - u32 address_attr; - u32 cycle_attr; -}; - -struct vme_dma_pattern { - u32 pattern; - u32 type; -}; - -struct vme_dma_pci { - dma_addr_t address; -}; - -struct vme_dma_vme { - unsigned long long address; - u32 aspace; - u32 cycle; - u32 dwidth; -}; - -struct vme_dma_list { - struct list_head list; - struct vme_dma_resource *parent; - struct list_head entries; - struct mutex mtx; -}; - -struct vme_dma_resource { - struct list_head list; - struct vme_bridge *parent; - struct mutex mtx; - int locked; - int number; - struct list_head pending; - struct list_head running; - u32 route_attr; -}; - -struct vme_lm_resource { - struct list_head list; - struct vme_bridge *parent; - struct mutex mtx; - int locked; - int number; - int monitors; -}; - -struct vme_bus_error { - struct list_head list; - unsigned long long address; - u32 attributes; -}; - -struct vme_callback { - void (*func)(int, int, void*); - void *priv_data; -}; - -struct vme_irq { - int count; - struct vme_callback callback[255]; -}; - -/* Allow 16 characters for name (including null character) */ -#define VMENAMSIZ 16 - -/* This structure stores all the information about one bridge - * The structure should be dynamically allocated by the driver and one instance - * of the structure should be present for each VME chip present in the system. - */ -struct vme_bridge { - char name[VMENAMSIZ]; - int num; - struct list_head master_resources; - struct list_head slave_resources; - struct list_head dma_resources; - struct list_head lm_resources; - - struct list_head vme_errors; /* List for errors generated on VME */ - struct list_head devices; /* List of devices on this bridge */ - - /* Bridge Info - XXX Move to private structure? */ - struct device *parent; /* Parent device (eg. pdev->dev for PCI) */ - void *driver_priv; /* Private pointer for the bridge driver */ - struct list_head bus_list; /* list of VME buses */ - - /* Interrupt callbacks */ - struct vme_irq irq[7]; - /* Locking for VME irq callback configuration */ - struct mutex irq_mtx; - - /* Slave Functions */ - int (*slave_get) (struct vme_slave_resource *, int *, - unsigned long long *, unsigned long long *, dma_addr_t *, - u32 *, u32 *); - int (*slave_set) (struct vme_slave_resource *, int, unsigned long long, - unsigned long long, dma_addr_t, u32, u32); - - /* Master Functions */ - int (*master_get) (struct vme_master_resource *, int *, - unsigned long long *, unsigned long long *, u32 *, u32 *, - u32 *); - int (*master_set) (struct vme_master_resource *, int, - unsigned long long, unsigned long long, u32, u32, u32); - ssize_t (*master_read) (struct vme_master_resource *, void *, size_t, - loff_t); - ssize_t (*master_write) (struct vme_master_resource *, void *, size_t, - loff_t); - unsigned int (*master_rmw) (struct vme_master_resource *, unsigned int, - unsigned int, unsigned int, loff_t); - - /* DMA Functions */ - int (*dma_list_add) (struct vme_dma_list *, struct vme_dma_attr *, - struct vme_dma_attr *, size_t); - int (*dma_list_exec) (struct vme_dma_list *); - int (*dma_list_empty) (struct vme_dma_list *); - - /* Interrupt Functions */ - void (*irq_set) (struct vme_bridge *, int, int, int); - int (*irq_generate) (struct vme_bridge *, int, int); - - /* Location monitor functions */ - int (*lm_set) (struct vme_lm_resource *, unsigned long long, u32, u32); - int (*lm_get) (struct vme_lm_resource *, unsigned long long *, u32 *, - u32 *); - int (*lm_attach) (struct vme_lm_resource *, int, void (*callback)(int)); - int (*lm_detach) (struct vme_lm_resource *, int); - - /* CR/CSR space functions */ - int (*slot_get) (struct vme_bridge *); - - /* Bridge parent interface */ - void *(*alloc_consistent)(struct device *dev, size_t size, - dma_addr_t *dma); - void (*free_consistent)(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma); -}; - -void vme_irq_handler(struct vme_bridge *, int, int); - -int vme_register_bridge(struct vme_bridge *); -void vme_unregister_bridge(struct vme_bridge *); - -#endif /* _VME_BRIDGE_H_ */ diff --git a/drivers/vme/Kconfig b/drivers/vme/Kconfig new file mode 100644 index 0000000..c5c2246 --- /dev/null +++ b/drivers/vme/Kconfig @@ -0,0 +1,19 @@ +# +# VME configuration. +# + +menuconfig VME_BUS + tristate "VME bridge support" + depends on PCI + ---help--- + If you say Y here you get support for the VME bridge Framework. + +if VME_BUS + +source "drivers/vme/bridges/Kconfig" + +source "drivers/vme/boards/Kconfig" + +source "drivers/staging/vme/devices/Kconfig" + +endif # VME diff --git a/drivers/vme/Makefile b/drivers/vme/Makefile new file mode 100644 index 0000000..d7bfcb9 --- /dev/null +++ b/drivers/vme/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for the VME bridge device drivers. +# +obj-$(CONFIG_VME_BUS) += vme.o + +obj-y += bridges/ +obj-y += boards/ diff --git a/drivers/vme/boards/Kconfig b/drivers/vme/boards/Kconfig new file mode 100644 index 0000000..7616313 --- /dev/null +++ b/drivers/vme/boards/Kconfig @@ -0,0 +1,9 @@ +comment "VME Board Drivers" + +config VMIVME_7805 + tristate "VMIVME-7805" + help + If you say Y here you get support for the VMIVME-7805 board. + This board has an additional control interface to the Universe II + chip. This driver has to be included if you want to access VME bus + with VMIVME-7805 board. diff --git a/drivers/vme/boards/Makefile b/drivers/vme/boards/Makefile new file mode 100644 index 0000000..4365834 --- /dev/null +++ b/drivers/vme/boards/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the VME board drivers. +# + +obj-$(CONFIG_VMIVME_7805) += vme_vmivme7805.o diff --git a/drivers/vme/boards/vme_vmivme7805.c b/drivers/vme/boards/vme_vmivme7805.c new file mode 100644 index 0000000..8e05bb4 --- /dev/null +++ b/drivers/vme/boards/vme_vmivme7805.c @@ -0,0 +1,123 @@ +/* + * Support for the VMIVME-7805 board access to the Universe II bridge. + * + * Author: Arthur Benilov + * Copyright 2010 Ion Beam Application, 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. + */ + +#include +#include +#include +#include +#include +#include + +#include "vme_vmivme7805.h" + +static int __init vmic_init(void); +static int vmic_probe(struct pci_dev *, const struct pci_device_id *); +static void vmic_remove(struct pci_dev *); +static void __exit vmic_exit(void); + +/** Base address to access FPGA register */ +static void *vmic_base; + +static const char driver_name[] = "vmivme_7805"; + +static DEFINE_PCI_DEVICE_TABLE(vmic_ids) = { + { PCI_DEVICE(PCI_VENDOR_ID_VMIC, PCI_DEVICE_ID_VTIMR) }, + { }, +}; + +static struct pci_driver vmic_driver = { + .name = driver_name, + .id_table = vmic_ids, + .probe = vmic_probe, + .remove = vmic_remove, +}; + +static int __init vmic_init(void) +{ + return pci_register_driver(&vmic_driver); +} + +static int vmic_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + int retval; + u32 data; + + /* Enable the device */ + retval = pci_enable_device(pdev); + if (retval) { + dev_err(&pdev->dev, "Unable to enable device\n"); + goto err; + } + + /* Map Registers */ + retval = pci_request_regions(pdev, driver_name); + if (retval) { + dev_err(&pdev->dev, "Unable to reserve resources\n"); + goto err_resource; + } + + /* Map registers in BAR 0 */ + vmic_base = ioremap_nocache(pci_resource_start(pdev, 0), 16); + if (!vmic_base) { + dev_err(&pdev->dev, "Unable to remap CRG region\n"); + retval = -EIO; + goto err_remap; + } + + /* Clear the FPGA VME IF contents */ + iowrite32(0, vmic_base + VME_CONTROL); + + /* Clear any initial BERR */ + data = ioread32(vmic_base + VME_CONTROL) & 0x00000FFF; + data |= BM_VME_CONTROL_BERRST; + iowrite32(data, vmic_base + VME_CONTROL); + + /* Enable the vme interface and byte swapping */ + data = ioread32(vmic_base + VME_CONTROL) & 0x00000FFF; + data = data | BM_VME_CONTROL_MASTER_ENDIAN | + BM_VME_CONTROL_SLAVE_ENDIAN | + BM_VME_CONTROL_ABLE | + BM_VME_CONTROL_BERRI | + BM_VME_CONTROL_BPENA | + BM_VME_CONTROL_VBENA; + iowrite32(data, vmic_base + VME_CONTROL); + + return 0; + +err_remap: + pci_release_regions(pdev); +err_resource: + pci_disable_device(pdev); +err: + return retval; +} + +static void vmic_remove(struct pci_dev *pdev) +{ + iounmap(vmic_base); + pci_release_regions(pdev); + pci_disable_device(pdev); + +} + +static void __exit vmic_exit(void) +{ + pci_unregister_driver(&vmic_driver); +} + +MODULE_DESCRIPTION("VMIVME-7805 board support driver"); +MODULE_AUTHOR("Arthur Benilov "); +MODULE_LICENSE("GPL"); + +module_init(vmic_init); +module_exit(vmic_exit); + diff --git a/drivers/vme/boards/vme_vmivme7805.h b/drivers/vme/boards/vme_vmivme7805.h new file mode 100644 index 0000000..44c2c44 --- /dev/null +++ b/drivers/vme/boards/vme_vmivme7805.h @@ -0,0 +1,37 @@ +/* + * vmivme_7805.h + * + * Support for the VMIVME-7805 board access to the Universe II bridge. + * + * Author: Arthur Benilov + * Copyright 2010 Ion Beam Application, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + + +#ifndef _VMIVME_7805_H +#define _VMIVME_7805_H + +#ifndef PCI_VENDOR_ID_VMIC +#define PCI_VENDOR_ID_VMIC 0x114A +#endif + +#ifndef PCI_DEVICE_ID_VTIMR +#define PCI_DEVICE_ID_VTIMR 0x0004 +#endif + +#define VME_CONTROL 0x0000 +#define BM_VME_CONTROL_MASTER_ENDIAN 0x0001 +#define BM_VME_CONTROL_SLAVE_ENDIAN 0x0002 +#define BM_VME_CONTROL_ABLE 0x0004 +#define BM_VME_CONTROL_BERRI 0x0040 +#define BM_VME_CONTROL_BERRST 0x0080 +#define BM_VME_CONTROL_BPENA 0x0400 +#define BM_VME_CONTROL_VBENA 0x0800 + +#endif /* _VMIVME_7805_H */ + diff --git a/drivers/vme/bridges/Kconfig b/drivers/vme/bridges/Kconfig new file mode 100644 index 0000000..9331064 --- /dev/null +++ b/drivers/vme/bridges/Kconfig @@ -0,0 +1,15 @@ +comment "VME Bridge Drivers" + +config VME_CA91CX42 + tristate "Universe II" + depends on VIRT_TO_BUS + help + If you say Y here you get support for the Tundra CA91C142 + (Universe II) VME bridge chip. + +config VME_TSI148 + tristate "Tempe" + depends on VIRT_TO_BUS + help + If you say Y here you get support for the Tundra TSI148 VME bridge + chip. diff --git a/drivers/vme/bridges/Makefile b/drivers/vme/bridges/Makefile new file mode 100644 index 0000000..59638af --- /dev/null +++ b/drivers/vme/bridges/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_VME_CA91CX42) += vme_ca91cx42.o +obj-$(CONFIG_VME_TSI148) += vme_tsi148.o diff --git a/drivers/vme/bridges/vme_ca91cx42.c b/drivers/vme/bridges/vme_ca91cx42.c new file mode 100644 index 0000000..a3c0f84 --- /dev/null +++ b/drivers/vme/bridges/vme_ca91cx42.c @@ -0,0 +1,1959 @@ +/* + * Support for the Tundra Universe I/II VME-PCI Bridge Chips + * + * Author: Martyn Welch + * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. + * + * Based on work by Tom Armistead and Ajit Prem + * Copyright 2004 Motorola Inc. + * + * Derived from ca91c042.c by Michael Wyrick + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../vme_bridge.h" +#include "vme_ca91cx42.h" + +static int __init ca91cx42_init(void); +static int ca91cx42_probe(struct pci_dev *, const struct pci_device_id *); +static void ca91cx42_remove(struct pci_dev *); +static void __exit ca91cx42_exit(void); + +/* Module parameters */ +static int geoid; + +static const char driver_name[] = "vme_ca91cx42"; + +static DEFINE_PCI_DEVICE_TABLE(ca91cx42_ids) = { + { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_CA91C142) }, + { }, +}; + +static struct pci_driver ca91cx42_driver = { + .name = driver_name, + .id_table = ca91cx42_ids, + .probe = ca91cx42_probe, + .remove = ca91cx42_remove, +}; + +static u32 ca91cx42_DMA_irqhandler(struct ca91cx42_driver *bridge) +{ + wake_up(&bridge->dma_queue); + + return CA91CX42_LINT_DMA; +} + +static u32 ca91cx42_LM_irqhandler(struct ca91cx42_driver *bridge, u32 stat) +{ + int i; + u32 serviced = 0; + + for (i = 0; i < 4; i++) { + if (stat & CA91CX42_LINT_LM[i]) { + /* We only enable interrupts if the callback is set */ + bridge->lm_callback[i](i); + serviced |= CA91CX42_LINT_LM[i]; + } + } + + return serviced; +} + +/* XXX This needs to be split into 4 queues */ +static u32 ca91cx42_MB_irqhandler(struct ca91cx42_driver *bridge, int mbox_mask) +{ + wake_up(&bridge->mbox_queue); + + return CA91CX42_LINT_MBOX; +} + +static u32 ca91cx42_IACK_irqhandler(struct ca91cx42_driver *bridge) +{ + wake_up(&bridge->iack_queue); + + return CA91CX42_LINT_SW_IACK; +} + +static u32 ca91cx42_VERR_irqhandler(struct vme_bridge *ca91cx42_bridge) +{ + int val; + struct ca91cx42_driver *bridge; + + bridge = ca91cx42_bridge->driver_priv; + + val = ioread32(bridge->base + DGCS); + + if (!(val & 0x00000800)) { + dev_err(ca91cx42_bridge->parent, "ca91cx42_VERR_irqhandler DMA " + "Read Error DGCS=%08X\n", val); + } + + return CA91CX42_LINT_VERR; +} + +static u32 ca91cx42_LERR_irqhandler(struct vme_bridge *ca91cx42_bridge) +{ + int val; + struct ca91cx42_driver *bridge; + + bridge = ca91cx42_bridge->driver_priv; + + val = ioread32(bridge->base + DGCS); + + if (!(val & 0x00000800)) + dev_err(ca91cx42_bridge->parent, "ca91cx42_LERR_irqhandler DMA " + "Read Error DGCS=%08X\n", val); + + return CA91CX42_LINT_LERR; +} + + +static u32 ca91cx42_VIRQ_irqhandler(struct vme_bridge *ca91cx42_bridge, + int stat) +{ + int vec, i, serviced = 0; + struct ca91cx42_driver *bridge; + + bridge = ca91cx42_bridge->driver_priv; + + + for (i = 7; i > 0; i--) { + if (stat & (1 << i)) { + vec = ioread32(bridge->base + + CA91CX42_V_STATID[i]) & 0xff; + + vme_irq_handler(ca91cx42_bridge, i, vec); + + serviced |= (1 << i); + } + } + + return serviced; +} + +static irqreturn_t ca91cx42_irqhandler(int irq, void *ptr) +{ + u32 stat, enable, serviced = 0; + struct vme_bridge *ca91cx42_bridge; + struct ca91cx42_driver *bridge; + + ca91cx42_bridge = ptr; + + bridge = ca91cx42_bridge->driver_priv; + + enable = ioread32(bridge->base + LINT_EN); + stat = ioread32(bridge->base + LINT_STAT); + + /* Only look at unmasked interrupts */ + stat &= enable; + + if (unlikely(!stat)) + return IRQ_NONE; + + if (stat & CA91CX42_LINT_DMA) + serviced |= ca91cx42_DMA_irqhandler(bridge); + if (stat & (CA91CX42_LINT_LM0 | CA91CX42_LINT_LM1 | CA91CX42_LINT_LM2 | + CA91CX42_LINT_LM3)) + serviced |= ca91cx42_LM_irqhandler(bridge, stat); + if (stat & CA91CX42_LINT_MBOX) + serviced |= ca91cx42_MB_irqhandler(bridge, stat); + if (stat & CA91CX42_LINT_SW_IACK) + serviced |= ca91cx42_IACK_irqhandler(bridge); + if (stat & CA91CX42_LINT_VERR) + serviced |= ca91cx42_VERR_irqhandler(ca91cx42_bridge); + if (stat & CA91CX42_LINT_LERR) + serviced |= ca91cx42_LERR_irqhandler(ca91cx42_bridge); + if (stat & (CA91CX42_LINT_VIRQ1 | CA91CX42_LINT_VIRQ2 | + CA91CX42_LINT_VIRQ3 | CA91CX42_LINT_VIRQ4 | + CA91CX42_LINT_VIRQ5 | CA91CX42_LINT_VIRQ6 | + CA91CX42_LINT_VIRQ7)) + serviced |= ca91cx42_VIRQ_irqhandler(ca91cx42_bridge, stat); + + /* Clear serviced interrupts */ + iowrite32(serviced, bridge->base + LINT_STAT); + + return IRQ_HANDLED; +} + +static int ca91cx42_irq_init(struct vme_bridge *ca91cx42_bridge) +{ + int result, tmp; + struct pci_dev *pdev; + struct ca91cx42_driver *bridge; + + bridge = ca91cx42_bridge->driver_priv; + + /* Need pdev */ + pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, dev); + + /* Initialise list for VME bus errors */ + INIT_LIST_HEAD(&ca91cx42_bridge->vme_errors); + + mutex_init(&ca91cx42_bridge->irq_mtx); + + /* Disable interrupts from PCI to VME */ + iowrite32(0, bridge->base + VINT_EN); + + /* Disable PCI interrupts */ + iowrite32(0, bridge->base + LINT_EN); + /* Clear Any Pending PCI Interrupts */ + iowrite32(0x00FFFFFF, bridge->base + LINT_STAT); + + result = request_irq(pdev->irq, ca91cx42_irqhandler, IRQF_SHARED, + driver_name, ca91cx42_bridge); + if (result) { + dev_err(&pdev->dev, "Can't get assigned pci irq vector %02X\n", + pdev->irq); + return result; + } + + /* Ensure all interrupts are mapped to PCI Interrupt 0 */ + iowrite32(0, bridge->base + LINT_MAP0); + iowrite32(0, bridge->base + LINT_MAP1); + iowrite32(0, bridge->base + LINT_MAP2); + + /* Enable DMA, mailbox & LM Interrupts */ + tmp = CA91CX42_LINT_MBOX3 | CA91CX42_LINT_MBOX2 | CA91CX42_LINT_MBOX1 | + CA91CX42_LINT_MBOX0 | CA91CX42_LINT_SW_IACK | + CA91CX42_LINT_VERR | CA91CX42_LINT_LERR | CA91CX42_LINT_DMA; + + iowrite32(tmp, bridge->base + LINT_EN); + + return 0; +} + +static void ca91cx42_irq_exit(struct ca91cx42_driver *bridge, + struct pci_dev *pdev) +{ + /* Disable interrupts from PCI to VME */ + iowrite32(0, bridge->base + VINT_EN); + + /* Disable PCI interrupts */ + iowrite32(0, bridge->base + LINT_EN); + /* Clear Any Pending PCI Interrupts */ + iowrite32(0x00FFFFFF, bridge->base + LINT_STAT); + + free_irq(pdev->irq, pdev); +} + +static int ca91cx42_iack_received(struct ca91cx42_driver *bridge, int level) +{ + u32 tmp; + + tmp = ioread32(bridge->base + LINT_STAT); + + if (tmp & (1 << level)) + return 0; + else + return 1; +} + +/* + * Set up an VME interrupt + */ +static void ca91cx42_irq_set(struct vme_bridge *ca91cx42_bridge, int level, + int state, int sync) + +{ + struct pci_dev *pdev; + u32 tmp; + struct ca91cx42_driver *bridge; + + bridge = ca91cx42_bridge->driver_priv; + + /* Enable IRQ level */ + tmp = ioread32(bridge->base + LINT_EN); + + if (state == 0) + tmp &= ~CA91CX42_LINT_VIRQ[level]; + else + tmp |= CA91CX42_LINT_VIRQ[level]; + + iowrite32(tmp, bridge->base + LINT_EN); + + if ((state == 0) && (sync != 0)) { + pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, + dev); + + synchronize_irq(pdev->irq); + } +} + +static int ca91cx42_irq_generate(struct vme_bridge *ca91cx42_bridge, int level, + int statid) +{ + u32 tmp; + struct ca91cx42_driver *bridge; + + bridge = ca91cx42_bridge->driver_priv; + + /* Universe can only generate even vectors */ + if (statid & 1) + return -EINVAL; + + mutex_lock(&bridge->vme_int); + + tmp = ioread32(bridge->base + VINT_EN); + + /* Set Status/ID */ + iowrite32(statid << 24, bridge->base + STATID); + + /* Assert VMEbus IRQ */ + tmp = tmp | (1 << (level + 24)); + iowrite32(tmp, bridge->base + VINT_EN); + + /* Wait for IACK */ + wait_event_interruptible(bridge->iack_queue, + ca91cx42_iack_received(bridge, level)); + + /* Return interrupt to low state */ + tmp = ioread32(bridge->base + VINT_EN); + tmp = tmp & ~(1 << (level + 24)); + iowrite32(tmp, bridge->base + VINT_EN); + + mutex_unlock(&bridge->vme_int); + + return 0; +} + +static int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled, + unsigned long long vme_base, unsigned long long size, + dma_addr_t pci_base, u32 aspace, u32 cycle) +{ + unsigned int i, addr = 0, granularity; + unsigned int temp_ctl = 0; + unsigned int vme_bound, pci_offset; + struct vme_bridge *ca91cx42_bridge; + struct ca91cx42_driver *bridge; + + ca91cx42_bridge = image->parent; + + bridge = ca91cx42_bridge->driver_priv; + + i = image->number; + + switch (aspace) { + case VME_A16: + addr |= CA91CX42_VSI_CTL_VAS_A16; + break; + case VME_A24: + addr |= CA91CX42_VSI_CTL_VAS_A24; + break; + case VME_A32: + addr |= CA91CX42_VSI_CTL_VAS_A32; + break; + case VME_USER1: + addr |= CA91CX42_VSI_CTL_VAS_USER1; + break; + case VME_USER2: + addr |= CA91CX42_VSI_CTL_VAS_USER2; + break; + case VME_A64: + case VME_CRCSR: + case VME_USER3: + case VME_USER4: + default: + dev_err(ca91cx42_bridge->parent, "Invalid address space\n"); + return -EINVAL; + break; + } + + /* + * Bound address is a valid address for the window, adjust + * accordingly + */ + vme_bound = vme_base + size; + pci_offset = pci_base - vme_base; + + if ((i == 0) || (i == 4)) + granularity = 0x1000; + else + granularity = 0x10000; + + if (vme_base & (granularity - 1)) { + dev_err(ca91cx42_bridge->parent, "Invalid VME base " + "alignment\n"); + return -EINVAL; + } + if (vme_bound & (granularity - 1)) { + dev_err(ca91cx42_bridge->parent, "Invalid VME bound " + "alignment\n"); + return -EINVAL; + } + if (pci_offset & (granularity - 1)) { + dev_err(ca91cx42_bridge->parent, "Invalid PCI Offset " + "alignment\n"); + return -EINVAL; + } + + /* Disable while we are mucking around */ + temp_ctl = ioread32(bridge->base + CA91CX42_VSI_CTL[i]); + temp_ctl &= ~CA91CX42_VSI_CTL_EN; + iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]); + + /* Setup mapping */ + iowrite32(vme_base, bridge->base + CA91CX42_VSI_BS[i]); + iowrite32(vme_bound, bridge->base + CA91CX42_VSI_BD[i]); + iowrite32(pci_offset, bridge->base + CA91CX42_VSI_TO[i]); + + /* Setup address space */ + temp_ctl &= ~CA91CX42_VSI_CTL_VAS_M; + temp_ctl |= addr; + + /* Setup cycle types */ + temp_ctl &= ~(CA91CX42_VSI_CTL_PGM_M | CA91CX42_VSI_CTL_SUPER_M); + if (cycle & VME_SUPER) + temp_ctl |= CA91CX42_VSI_CTL_SUPER_SUPR; + if (cycle & VME_USER) + temp_ctl |= CA91CX42_VSI_CTL_SUPER_NPRIV; + if (cycle & VME_PROG) + temp_ctl |= CA91CX42_VSI_CTL_PGM_PGM; + if (cycle & VME_DATA) + temp_ctl |= CA91CX42_VSI_CTL_PGM_DATA; + + /* Write ctl reg without enable */ + iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]); + + if (enabled) + temp_ctl |= CA91CX42_VSI_CTL_EN; + + iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]); + + return 0; +} + +static int ca91cx42_slave_get(struct vme_slave_resource *image, int *enabled, + unsigned long long *vme_base, unsigned long long *size, + dma_addr_t *pci_base, u32 *aspace, u32 *cycle) +{ + unsigned int i, granularity = 0, ctl = 0; + unsigned long long vme_bound, pci_offset; + struct ca91cx42_driver *bridge; + + bridge = image->parent->driver_priv; + + i = image->number; + + if ((i == 0) || (i == 4)) + granularity = 0x1000; + else + granularity = 0x10000; + + /* Read Registers */ + ctl = ioread32(bridge->base + CA91CX42_VSI_CTL[i]); + + *vme_base = ioread32(bridge->base + CA91CX42_VSI_BS[i]); + vme_bound = ioread32(bridge->base + CA91CX42_VSI_BD[i]); + pci_offset = ioread32(bridge->base + CA91CX42_VSI_TO[i]); + + *pci_base = (dma_addr_t)vme_base + pci_offset; + *size = (unsigned long long)((vme_bound - *vme_base) + granularity); + + *enabled = 0; + *aspace = 0; + *cycle = 0; + + if (ctl & CA91CX42_VSI_CTL_EN) + *enabled = 1; + + if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_A16) + *aspace = VME_A16; + if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_A24) + *aspace = VME_A24; + if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_A32) + *aspace = VME_A32; + if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_USER1) + *aspace = VME_USER1; + if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_USER2) + *aspace = VME_USER2; + + if (ctl & CA91CX42_VSI_CTL_SUPER_SUPR) + *cycle |= VME_SUPER; + if (ctl & CA91CX42_VSI_CTL_SUPER_NPRIV) + *cycle |= VME_USER; + if (ctl & CA91CX42_VSI_CTL_PGM_PGM) + *cycle |= VME_PROG; + if (ctl & CA91CX42_VSI_CTL_PGM_DATA) + *cycle |= VME_DATA; + + return 0; +} + +/* + * Allocate and map PCI Resource + */ +static int ca91cx42_alloc_resource(struct vme_master_resource *image, + unsigned long long size) +{ + unsigned long long existing_size; + int retval = 0; + struct pci_dev *pdev; + struct vme_bridge *ca91cx42_bridge; + + ca91cx42_bridge = image->parent; + + /* Find pci_dev container of dev */ + if (ca91cx42_bridge->parent == NULL) { + dev_err(ca91cx42_bridge->parent, "Dev entry NULL\n"); + return -EINVAL; + } + pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, dev); + + existing_size = (unsigned long long)(image->bus_resource.end - + image->bus_resource.start); + + /* If the existing size is OK, return */ + if (existing_size == (size - 1)) + return 0; + + if (existing_size != 0) { + iounmap(image->kern_base); + image->kern_base = NULL; + kfree(image->bus_resource.name); + release_resource(&image->bus_resource); + memset(&image->bus_resource, 0, sizeof(struct resource)); + } + + if (image->bus_resource.name == NULL) { + image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_ATOMIC); + if (image->bus_resource.name == NULL) { + dev_err(ca91cx42_bridge->parent, "Unable to allocate " + "memory for resource name\n"); + retval = -ENOMEM; + goto err_name; + } + } + + sprintf((char *)image->bus_resource.name, "%s.%d", + ca91cx42_bridge->name, image->number); + + image->bus_resource.start = 0; + image->bus_resource.end = (unsigned long)size; + image->bus_resource.flags = IORESOURCE_MEM; + + retval = pci_bus_alloc_resource(pdev->bus, + &image->bus_resource, size, size, PCIBIOS_MIN_MEM, + 0, NULL, NULL); + if (retval) { + dev_err(ca91cx42_bridge->parent, "Failed to allocate mem " + "resource for window %d size 0x%lx start 0x%lx\n", + image->number, (unsigned long)size, + (unsigned long)image->bus_resource.start); + goto err_resource; + } + + image->kern_base = ioremap_nocache( + image->bus_resource.start, size); + if (image->kern_base == NULL) { + dev_err(ca91cx42_bridge->parent, "Failed to remap resource\n"); + retval = -ENOMEM; + goto err_remap; + } + + return 0; + +err_remap: + release_resource(&image->bus_resource); +err_resource: + kfree(image->bus_resource.name); + memset(&image->bus_resource, 0, sizeof(struct resource)); +err_name: + return retval; +} + +/* + * Free and unmap PCI Resource + */ +static void ca91cx42_free_resource(struct vme_master_resource *image) +{ + iounmap(image->kern_base); + image->kern_base = NULL; + release_resource(&image->bus_resource); + kfree(image->bus_resource.name); + memset(&image->bus_resource, 0, sizeof(struct resource)); +} + + +static int ca91cx42_master_set(struct vme_master_resource *image, int enabled, + unsigned long long vme_base, unsigned long long size, u32 aspace, + u32 cycle, u32 dwidth) +{ + int retval = 0; + unsigned int i, granularity = 0; + unsigned int temp_ctl = 0; + unsigned long long pci_bound, vme_offset, pci_base; + struct vme_bridge *ca91cx42_bridge; + struct ca91cx42_driver *bridge; + + ca91cx42_bridge = image->parent; + + bridge = ca91cx42_bridge->driver_priv; + + i = image->number; + + if ((i == 0) || (i == 4)) + granularity = 0x1000; + else + granularity = 0x10000; + + /* Verify input data */ + if (vme_base & (granularity - 1)) { + dev_err(ca91cx42_bridge->parent, "Invalid VME Window " + "alignment\n"); + retval = -EINVAL; + goto err_window; + } + if (size & (granularity - 1)) { + dev_err(ca91cx42_bridge->parent, "Invalid VME Window " + "alignment\n"); + retval = -EINVAL; + goto err_window; + } + + spin_lock(&image->lock); + + /* + * Let's allocate the resource here rather than further up the stack as + * it avoids pushing loads of bus dependent stuff up the stack + */ + retval = ca91cx42_alloc_resource(image, size); + if (retval) { + spin_unlock(&image->lock); + dev_err(ca91cx42_bridge->parent, "Unable to allocate memory " + "for resource name\n"); + retval = -ENOMEM; + goto err_res; + } + + pci_base = (unsigned long long)image->bus_resource.start; + + /* + * Bound address is a valid address for the window, adjust + * according to window granularity. + */ + pci_bound = pci_base + size; + vme_offset = vme_base - pci_base; + + /* Disable while we are mucking around */ + temp_ctl = ioread32(bridge->base + CA91CX42_LSI_CTL[i]); + temp_ctl &= ~CA91CX42_LSI_CTL_EN; + iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]); + + /* Setup cycle types */ + temp_ctl &= ~CA91CX42_LSI_CTL_VCT_M; + if (cycle & VME_BLT) + temp_ctl |= CA91CX42_LSI_CTL_VCT_BLT; + if (cycle & VME_MBLT) + temp_ctl |= CA91CX42_LSI_CTL_VCT_MBLT; + + /* Setup data width */ + temp_ctl &= ~CA91CX42_LSI_CTL_VDW_M; + switch (dwidth) { + case VME_D8: + temp_ctl |= CA91CX42_LSI_CTL_VDW_D8; + break; + case VME_D16: + temp_ctl |= CA91CX42_LSI_CTL_VDW_D16; + break; + case VME_D32: + temp_ctl |= CA91CX42_LSI_CTL_VDW_D32; + break; + case VME_D64: + temp_ctl |= CA91CX42_LSI_CTL_VDW_D64; + break; + default: + spin_unlock(&image->lock); + dev_err(ca91cx42_bridge->parent, "Invalid data width\n"); + retval = -EINVAL; + goto err_dwidth; + break; + } + + /* Setup address space */ + temp_ctl &= ~CA91CX42_LSI_CTL_VAS_M; + switch (aspace) { + case VME_A16: + temp_ctl |= CA91CX42_LSI_CTL_VAS_A16; + break; + case VME_A24: + temp_ctl |= CA91CX42_LSI_CTL_VAS_A24; + break; + case VME_A32: + temp_ctl |= CA91CX42_LSI_CTL_VAS_A32; + break; + case VME_CRCSR: + temp_ctl |= CA91CX42_LSI_CTL_VAS_CRCSR; + break; + case VME_USER1: + temp_ctl |= CA91CX42_LSI_CTL_VAS_USER1; + break; + case VME_USER2: + temp_ctl |= CA91CX42_LSI_CTL_VAS_USER2; + break; + case VME_A64: + case VME_USER3: + case VME_USER4: + default: + spin_unlock(&image->lock); + dev_err(ca91cx42_bridge->parent, "Invalid address space\n"); + retval = -EINVAL; + goto err_aspace; + break; + } + + temp_ctl &= ~(CA91CX42_LSI_CTL_PGM_M | CA91CX42_LSI_CTL_SUPER_M); + if (cycle & VME_SUPER) + temp_ctl |= CA91CX42_LSI_CTL_SUPER_SUPR; + if (cycle & VME_PROG) + temp_ctl |= CA91CX42_LSI_CTL_PGM_PGM; + + /* Setup mapping */ + iowrite32(pci_base, bridge->base + CA91CX42_LSI_BS[i]); + iowrite32(pci_bound, bridge->base + CA91CX42_LSI_BD[i]); + iowrite32(vme_offset, bridge->base + CA91CX42_LSI_TO[i]); + + /* Write ctl reg without enable */ + iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]); + + if (enabled) + temp_ctl |= CA91CX42_LSI_CTL_EN; + + iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]); + + spin_unlock(&image->lock); + return 0; + +err_aspace: +err_dwidth: + ca91cx42_free_resource(image); +err_res: +err_window: + return retval; +} + +static int __ca91cx42_master_get(struct vme_master_resource *image, + int *enabled, unsigned long long *vme_base, unsigned long long *size, + u32 *aspace, u32 *cycle, u32 *dwidth) +{ + unsigned int i, ctl; + unsigned long long pci_base, pci_bound, vme_offset; + struct ca91cx42_driver *bridge; + + bridge = image->parent->driver_priv; + + i = image->number; + + ctl = ioread32(bridge->base + CA91CX42_LSI_CTL[i]); + + pci_base = ioread32(bridge->base + CA91CX42_LSI_BS[i]); + vme_offset = ioread32(bridge->base + CA91CX42_LSI_TO[i]); + pci_bound = ioread32(bridge->base + CA91CX42_LSI_BD[i]); + + *vme_base = pci_base + vme_offset; + *size = (unsigned long long)(pci_bound - pci_base); + + *enabled = 0; + *aspace = 0; + *cycle = 0; + *dwidth = 0; + + if (ctl & CA91CX42_LSI_CTL_EN) + *enabled = 1; + + /* Setup address space */ + switch (ctl & CA91CX42_LSI_CTL_VAS_M) { + case CA91CX42_LSI_CTL_VAS_A16: + *aspace = VME_A16; + break; + case CA91CX42_LSI_CTL_VAS_A24: + *aspace = VME_A24; + break; + case CA91CX42_LSI_CTL_VAS_A32: + *aspace = VME_A32; + break; + case CA91CX42_LSI_CTL_VAS_CRCSR: + *aspace = VME_CRCSR; + break; + case CA91CX42_LSI_CTL_VAS_USER1: + *aspace = VME_USER1; + break; + case CA91CX42_LSI_CTL_VAS_USER2: + *aspace = VME_USER2; + break; + } + + /* XXX Not sure howto check for MBLT */ + /* Setup cycle types */ + if (ctl & CA91CX42_LSI_CTL_VCT_BLT) + *cycle |= VME_BLT; + else + *cycle |= VME_SCT; + + if (ctl & CA91CX42_LSI_CTL_SUPER_SUPR) + *cycle |= VME_SUPER; + else + *cycle |= VME_USER; + + if (ctl & CA91CX42_LSI_CTL_PGM_PGM) + *cycle = VME_PROG; + else + *cycle = VME_DATA; + + /* Setup data width */ + switch (ctl & CA91CX42_LSI_CTL_VDW_M) { + case CA91CX42_LSI_CTL_VDW_D8: + *dwidth = VME_D8; + break; + case CA91CX42_LSI_CTL_VDW_D16: + *dwidth = VME_D16; + break; + case CA91CX42_LSI_CTL_VDW_D32: + *dwidth = VME_D32; + break; + case CA91CX42_LSI_CTL_VDW_D64: + *dwidth = VME_D64; + break; + } + + return 0; +} + +static int ca91cx42_master_get(struct vme_master_resource *image, int *enabled, + unsigned long long *vme_base, unsigned long long *size, u32 *aspace, + u32 *cycle, u32 *dwidth) +{ + int retval; + + spin_lock(&image->lock); + + retval = __ca91cx42_master_get(image, enabled, vme_base, size, aspace, + cycle, dwidth); + + spin_unlock(&image->lock); + + return retval; +} + +static ssize_t ca91cx42_master_read(struct vme_master_resource *image, + void *buf, size_t count, loff_t offset) +{ + ssize_t retval; + void *addr = image->kern_base + offset; + unsigned int done = 0; + unsigned int count32; + + if (count == 0) + return 0; + + spin_lock(&image->lock); + + /* The following code handles VME address alignment problem + * in order to assure the maximal data width cycle. + * We cannot use memcpy_xxx directly here because it + * may cut data transfer in 8-bits cycles, thus making + * D16 cycle impossible. + * From the other hand, the bridge itself assures that + * maximal configured data cycle is used and splits it + * automatically for non-aligned addresses. + */ + if ((uintptr_t)addr & 0x1) { + *(u8 *)buf = ioread8(addr); + done += 1; + if (done == count) + goto out; + } + if ((uintptr_t)addr & 0x2) { + if ((count - done) < 2) { + *(u8 *)(buf + done) = ioread8(addr + done); + done += 1; + goto out; + } else { + *(u16 *)(buf + done) = ioread16(addr + done); + done += 2; + } + } + + count32 = (count - done) & ~0x3; + if (count32 > 0) { + memcpy_fromio(buf + done, addr + done, (unsigned int)count); + done += count32; + } + + if ((count - done) & 0x2) { + *(u16 *)(buf + done) = ioread16(addr + done); + done += 2; + } + if ((count - done) & 0x1) { + *(u8 *)(buf + done) = ioread8(addr + done); + done += 1; + } +out: + retval = count; + spin_unlock(&image->lock); + + return retval; +} + +static ssize_t ca91cx42_master_write(struct vme_master_resource *image, + void *buf, size_t count, loff_t offset) +{ + ssize_t retval; + void *addr = image->kern_base + offset; + unsigned int done = 0; + unsigned int count32; + + if (count == 0) + return 0; + + spin_lock(&image->lock); + + /* Here we apply for the same strategy we do in master_read + * function in order to assure D16 cycle when required. + */ + if ((uintptr_t)addr & 0x1) { + iowrite8(*(u8 *)buf, addr); + done += 1; + if (done == count) + goto out; + } + if ((uintptr_t)addr & 0x2) { + if ((count - done) < 2) { + iowrite8(*(u8 *)(buf + done), addr + done); + done += 1; + goto out; + } else { + iowrite16(*(u16 *)(buf + done), addr + done); + done += 2; + } + } + + count32 = (count - done) & ~0x3; + if (count32 > 0) { + memcpy_toio(addr + done, buf + done, count32); + done += count32; + } + + if ((count - done) & 0x2) { + iowrite16(*(u16 *)(buf + done), addr + done); + done += 2; + } + if ((count - done) & 0x1) { + iowrite8(*(u8 *)(buf + done), addr + done); + done += 1; + } +out: + retval = count; + + spin_unlock(&image->lock); + + return retval; +} + +static unsigned int ca91cx42_master_rmw(struct vme_master_resource *image, + unsigned int mask, unsigned int compare, unsigned int swap, + loff_t offset) +{ + u32 result; + uintptr_t pci_addr; + int i; + struct ca91cx42_driver *bridge; + struct device *dev; + + bridge = image->parent->driver_priv; + dev = image->parent->parent; + + /* Find the PCI address that maps to the desired VME address */ + i = image->number; + + /* Locking as we can only do one of these at a time */ + mutex_lock(&bridge->vme_rmw); + + /* Lock image */ + spin_lock(&image->lock); + + pci_addr = (uintptr_t)image->kern_base + offset; + + /* Address must be 4-byte aligned */ + if (pci_addr & 0x3) { + dev_err(dev, "RMW Address not 4-byte aligned\n"); + result = -EINVAL; + goto out; + } + + /* Ensure RMW Disabled whilst configuring */ + iowrite32(0, bridge->base + SCYC_CTL); + + /* Configure registers */ + iowrite32(mask, bridge->base + SCYC_EN); + iowrite32(compare, bridge->base + SCYC_CMP); + iowrite32(swap, bridge->base + SCYC_SWP); + iowrite32(pci_addr, bridge->base + SCYC_ADDR); + + /* Enable RMW */ + iowrite32(CA91CX42_SCYC_CTL_CYC_RMW, bridge->base + SCYC_CTL); + + /* Kick process off with a read to the required address. */ + result = ioread32(image->kern_base + offset); + + /* Disable RMW */ + iowrite32(0, bridge->base + SCYC_CTL); + +out: + spin_unlock(&image->lock); + + mutex_unlock(&bridge->vme_rmw); + + return result; +} + +static int ca91cx42_dma_list_add(struct vme_dma_list *list, + struct vme_dma_attr *src, struct vme_dma_attr *dest, size_t count) +{ + struct ca91cx42_dma_entry *entry, *prev; + struct vme_dma_pci *pci_attr; + struct vme_dma_vme *vme_attr; + dma_addr_t desc_ptr; + int retval = 0; + struct device *dev; + + dev = list->parent->parent->parent; + + /* XXX descriptor must be aligned on 64-bit boundaries */ + entry = kmalloc(sizeof(struct ca91cx42_dma_entry), GFP_KERNEL); + if (entry == NULL) { + dev_err(dev, "Failed to allocate memory for dma resource " + "structure\n"); + retval = -ENOMEM; + goto err_mem; + } + + /* Test descriptor alignment */ + if ((unsigned long)&entry->descriptor & CA91CX42_DCPP_M) { + dev_err(dev, "Descriptor not aligned to 16 byte boundary as " + "required: %p\n", &entry->descriptor); + retval = -EINVAL; + goto err_align; + } + + memset(&entry->descriptor, 0, sizeof(struct ca91cx42_dma_descriptor)); + + if (dest->type == VME_DMA_VME) { + entry->descriptor.dctl |= CA91CX42_DCTL_L2V; + vme_attr = dest->private; + pci_attr = src->private; + } else { + vme_attr = src->private; + pci_attr = dest->private; + } + + /* Check we can do fulfill required attributes */ + if ((vme_attr->aspace & ~(VME_A16 | VME_A24 | VME_A32 | VME_USER1 | + VME_USER2)) != 0) { + + dev_err(dev, "Unsupported cycle type\n"); + retval = -EINVAL; + goto err_aspace; + } + + if ((vme_attr->cycle & ~(VME_SCT | VME_BLT | VME_SUPER | VME_USER | + VME_PROG | VME_DATA)) != 0) { + + dev_err(dev, "Unsupported cycle type\n"); + retval = -EINVAL; + goto err_cycle; + } + + /* Check to see if we can fulfill source and destination */ + if (!(((src->type == VME_DMA_PCI) && (dest->type == VME_DMA_VME)) || + ((src->type == VME_DMA_VME) && (dest->type == VME_DMA_PCI)))) { + + dev_err(dev, "Cannot perform transfer with this " + "source-destination combination\n"); + retval = -EINVAL; + goto err_direct; + } + + /* Setup cycle types */ + if (vme_attr->cycle & VME_BLT) + entry->descriptor.dctl |= CA91CX42_DCTL_VCT_BLT; + + /* Setup data width */ + switch (vme_attr->dwidth) { + case VME_D8: + entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D8; + break; + case VME_D16: + entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D16; + break; + case VME_D32: + entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D32; + break; + case VME_D64: + entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D64; + break; + default: + dev_err(dev, "Invalid data width\n"); + return -EINVAL; + } + + /* Setup address space */ + switch (vme_attr->aspace) { + case VME_A16: + entry->descriptor.dctl |= CA91CX42_DCTL_VAS_A16; + break; + case VME_A24: + entry->descriptor.dctl |= CA91CX42_DCTL_VAS_A24; + break; + case VME_A32: + entry->descriptor.dctl |= CA91CX42_DCTL_VAS_A32; + break; + case VME_USER1: + entry->descriptor.dctl |= CA91CX42_DCTL_VAS_USER1; + break; + case VME_USER2: + entry->descriptor.dctl |= CA91CX42_DCTL_VAS_USER2; + break; + default: + dev_err(dev, "Invalid address space\n"); + return -EINVAL; + break; + } + + if (vme_attr->cycle & VME_SUPER) + entry->descriptor.dctl |= CA91CX42_DCTL_SUPER_SUPR; + if (vme_attr->cycle & VME_PROG) + entry->descriptor.dctl |= CA91CX42_DCTL_PGM_PGM; + + entry->descriptor.dtbc = count; + entry->descriptor.dla = pci_attr->address; + entry->descriptor.dva = vme_attr->address; + entry->descriptor.dcpp = CA91CX42_DCPP_NULL; + + /* Add to list */ + list_add_tail(&entry->list, &list->entries); + + /* Fill out previous descriptors "Next Address" */ + if (entry->list.prev != &list->entries) { + prev = list_entry(entry->list.prev, struct ca91cx42_dma_entry, + list); + /* We need the bus address for the pointer */ + desc_ptr = virt_to_bus(&entry->descriptor); + prev->descriptor.dcpp = desc_ptr & ~CA91CX42_DCPP_M; + } + + return 0; + +err_cycle: +err_aspace: +err_direct: +err_align: + kfree(entry); +err_mem: + return retval; +} + +static int ca91cx42_dma_busy(struct vme_bridge *ca91cx42_bridge) +{ + u32 tmp; + struct ca91cx42_driver *bridge; + + bridge = ca91cx42_bridge->driver_priv; + + tmp = ioread32(bridge->base + DGCS); + + if (tmp & CA91CX42_DGCS_ACT) + return 0; + else + return 1; +} + +static int ca91cx42_dma_list_exec(struct vme_dma_list *list) +{ + struct vme_dma_resource *ctrlr; + struct ca91cx42_dma_entry *entry; + int retval = 0; + dma_addr_t bus_addr; + u32 val; + struct device *dev; + struct ca91cx42_driver *bridge; + + ctrlr = list->parent; + + bridge = ctrlr->parent->driver_priv; + dev = ctrlr->parent->parent; + + mutex_lock(&ctrlr->mtx); + + if (!(list_empty(&ctrlr->running))) { + /* + * XXX We have an active DMA transfer and currently haven't + * sorted out the mechanism for "pending" DMA transfers. + * Return busy. + */ + /* Need to add to pending here */ + mutex_unlock(&ctrlr->mtx); + return -EBUSY; + } else { + list_add(&list->list, &ctrlr->running); + } + + /* Get first bus address and write into registers */ + entry = list_first_entry(&list->entries, struct ca91cx42_dma_entry, + list); + + bus_addr = virt_to_bus(&entry->descriptor); + + mutex_unlock(&ctrlr->mtx); + + iowrite32(0, bridge->base + DTBC); + iowrite32(bus_addr & ~CA91CX42_DCPP_M, bridge->base + DCPP); + + /* Start the operation */ + val = ioread32(bridge->base + DGCS); + + /* XXX Could set VMEbus On and Off Counters here */ + val &= (CA91CX42_DGCS_VON_M | CA91CX42_DGCS_VOFF_M); + + val |= (CA91CX42_DGCS_CHAIN | CA91CX42_DGCS_STOP | CA91CX42_DGCS_HALT | + CA91CX42_DGCS_DONE | CA91CX42_DGCS_LERR | CA91CX42_DGCS_VERR | + CA91CX42_DGCS_PERR); + + iowrite32(val, bridge->base + DGCS); + + val |= CA91CX42_DGCS_GO; + + iowrite32(val, bridge->base + DGCS); + + wait_event_interruptible(bridge->dma_queue, + ca91cx42_dma_busy(ctrlr->parent)); + + /* + * Read status register, this register is valid until we kick off a + * new transfer. + */ + val = ioread32(bridge->base + DGCS); + + if (val & (CA91CX42_DGCS_LERR | CA91CX42_DGCS_VERR | + CA91CX42_DGCS_PERR)) { + + dev_err(dev, "ca91c042: DMA Error. DGCS=%08X\n", val); + val = ioread32(bridge->base + DCTL); + } + + /* Remove list from running list */ + mutex_lock(&ctrlr->mtx); + list_del(&list->list); + mutex_unlock(&ctrlr->mtx); + + return retval; + +} + +static int ca91cx42_dma_list_empty(struct vme_dma_list *list) +{ + struct list_head *pos, *temp; + struct ca91cx42_dma_entry *entry; + + /* detach and free each entry */ + list_for_each_safe(pos, temp, &list->entries) { + list_del(pos); + entry = list_entry(pos, struct ca91cx42_dma_entry, list); + kfree(entry); + } + + return 0; +} + +/* + * All 4 location monitors reside at the same base - this is therefore a + * system wide configuration. + * + * This does not enable the LM monitor - that should be done when the first + * callback is attached and disabled when the last callback is removed. + */ +static int ca91cx42_lm_set(struct vme_lm_resource *lm, + unsigned long long lm_base, u32 aspace, u32 cycle) +{ + u32 temp_base, lm_ctl = 0; + int i; + struct ca91cx42_driver *bridge; + struct device *dev; + + bridge = lm->parent->driver_priv; + dev = lm->parent->parent; + + /* Check the alignment of the location monitor */ + temp_base = (u32)lm_base; + if (temp_base & 0xffff) { + dev_err(dev, "Location monitor must be aligned to 64KB " + "boundary"); + return -EINVAL; + } + + mutex_lock(&lm->mtx); + + /* If we already have a callback attached, we can't move it! */ + for (i = 0; i < lm->monitors; i++) { + if (bridge->lm_callback[i] != NULL) { + mutex_unlock(&lm->mtx); + dev_err(dev, "Location monitor callback attached, " + "can't reset\n"); + return -EBUSY; + } + } + + switch (aspace) { + case VME_A16: + lm_ctl |= CA91CX42_LM_CTL_AS_A16; + break; + case VME_A24: + lm_ctl |= CA91CX42_LM_CTL_AS_A24; + break; + case VME_A32: + lm_ctl |= CA91CX42_LM_CTL_AS_A32; + break; + default: + mutex_unlock(&lm->mtx); + dev_err(dev, "Invalid address space\n"); + return -EINVAL; + break; + } + + if (cycle & VME_SUPER) + lm_ctl |= CA91CX42_LM_CTL_SUPR; + if (cycle & VME_USER) + lm_ctl |= CA91CX42_LM_CTL_NPRIV; + if (cycle & VME_PROG) + lm_ctl |= CA91CX42_LM_CTL_PGM; + if (cycle & VME_DATA) + lm_ctl |= CA91CX42_LM_CTL_DATA; + + iowrite32(lm_base, bridge->base + LM_BS); + iowrite32(lm_ctl, bridge->base + LM_CTL); + + mutex_unlock(&lm->mtx); + + return 0; +} + +/* Get configuration of the callback monitor and return whether it is enabled + * or disabled. + */ +static int ca91cx42_lm_get(struct vme_lm_resource *lm, + unsigned long long *lm_base, u32 *aspace, u32 *cycle) +{ + u32 lm_ctl, enabled = 0; + struct ca91cx42_driver *bridge; + + bridge = lm->parent->driver_priv; + + mutex_lock(&lm->mtx); + + *lm_base = (unsigned long long)ioread32(bridge->base + LM_BS); + lm_ctl = ioread32(bridge->base + LM_CTL); + + if (lm_ctl & CA91CX42_LM_CTL_EN) + enabled = 1; + + if ((lm_ctl & CA91CX42_LM_CTL_AS_M) == CA91CX42_LM_CTL_AS_A16) + *aspace = VME_A16; + if ((lm_ctl & CA91CX42_LM_CTL_AS_M) == CA91CX42_LM_CTL_AS_A24) + *aspace = VME_A24; + if ((lm_ctl & CA91CX42_LM_CTL_AS_M) == CA91CX42_LM_CTL_AS_A32) + *aspace = VME_A32; + + *cycle = 0; + if (lm_ctl & CA91CX42_LM_CTL_SUPR) + *cycle |= VME_SUPER; + if (lm_ctl & CA91CX42_LM_CTL_NPRIV) + *cycle |= VME_USER; + if (lm_ctl & CA91CX42_LM_CTL_PGM) + *cycle |= VME_PROG; + if (lm_ctl & CA91CX42_LM_CTL_DATA) + *cycle |= VME_DATA; + + mutex_unlock(&lm->mtx); + + return enabled; +} + +/* + * Attach a callback to a specific location monitor. + * + * Callback will be passed the monitor triggered. + */ +static int ca91cx42_lm_attach(struct vme_lm_resource *lm, int monitor, + void (*callback)(int)) +{ + u32 lm_ctl, tmp; + struct ca91cx42_driver *bridge; + struct device *dev; + + bridge = lm->parent->driver_priv; + dev = lm->parent->parent; + + mutex_lock(&lm->mtx); + + /* Ensure that the location monitor is configured - need PGM or DATA */ + lm_ctl = ioread32(bridge->base + LM_CTL); + if ((lm_ctl & (CA91CX42_LM_CTL_PGM | CA91CX42_LM_CTL_DATA)) == 0) { + mutex_unlock(&lm->mtx); + dev_err(dev, "Location monitor not properly configured\n"); + return -EINVAL; + } + + /* Check that a callback isn't already attached */ + if (bridge->lm_callback[monitor] != NULL) { + mutex_unlock(&lm->mtx); + dev_err(dev, "Existing callback attached\n"); + return -EBUSY; + } + + /* Attach callback */ + bridge->lm_callback[monitor] = callback; + + /* Enable Location Monitor interrupt */ + tmp = ioread32(bridge->base + LINT_EN); + tmp |= CA91CX42_LINT_LM[monitor]; + iowrite32(tmp, bridge->base + LINT_EN); + + /* Ensure that global Location Monitor Enable set */ + if ((lm_ctl & CA91CX42_LM_CTL_EN) == 0) { + lm_ctl |= CA91CX42_LM_CTL_EN; + iowrite32(lm_ctl, bridge->base + LM_CTL); + } + + mutex_unlock(&lm->mtx); + + return 0; +} + +/* + * Detach a callback function forn a specific location monitor. + */ +static int ca91cx42_lm_detach(struct vme_lm_resource *lm, int monitor) +{ + u32 tmp; + struct ca91cx42_driver *bridge; + + bridge = lm->parent->driver_priv; + + mutex_lock(&lm->mtx); + + /* Disable Location Monitor and ensure previous interrupts are clear */ + tmp = ioread32(bridge->base + LINT_EN); + tmp &= ~CA91CX42_LINT_LM[monitor]; + iowrite32(tmp, bridge->base + LINT_EN); + + iowrite32(CA91CX42_LINT_LM[monitor], + bridge->base + LINT_STAT); + + /* Detach callback */ + bridge->lm_callback[monitor] = NULL; + + /* If all location monitors disabled, disable global Location Monitor */ + if ((tmp & (CA91CX42_LINT_LM0 | CA91CX42_LINT_LM1 | CA91CX42_LINT_LM2 | + CA91CX42_LINT_LM3)) == 0) { + tmp = ioread32(bridge->base + LM_CTL); + tmp &= ~CA91CX42_LM_CTL_EN; + iowrite32(tmp, bridge->base + LM_CTL); + } + + mutex_unlock(&lm->mtx); + + return 0; +} + +static int ca91cx42_slot_get(struct vme_bridge *ca91cx42_bridge) +{ + u32 slot = 0; + struct ca91cx42_driver *bridge; + + bridge = ca91cx42_bridge->driver_priv; + + if (!geoid) { + slot = ioread32(bridge->base + VCSR_BS); + slot = ((slot & CA91CX42_VCSR_BS_SLOT_M) >> 27); + } else + slot = geoid; + + return (int)slot; + +} + +void *ca91cx42_alloc_consistent(struct device *parent, size_t size, + dma_addr_t *dma) +{ + struct pci_dev *pdev; + + /* Find pci_dev container of dev */ + pdev = container_of(parent, struct pci_dev, dev); + + return pci_alloc_consistent(pdev, size, dma); +} + +void ca91cx42_free_consistent(struct device *parent, size_t size, void *vaddr, + dma_addr_t dma) +{ + struct pci_dev *pdev; + + /* Find pci_dev container of dev */ + pdev = container_of(parent, struct pci_dev, dev); + + pci_free_consistent(pdev, size, vaddr, dma); +} + +static int __init ca91cx42_init(void) +{ + return pci_register_driver(&ca91cx42_driver); +} + +/* + * Configure CR/CSR space + * + * Access to the CR/CSR can be configured at power-up. The location of the + * CR/CSR registers in the CR/CSR address space is determined by the boards + * Auto-ID or Geographic address. This function ensures that the window is + * enabled at an offset consistent with the boards geopgraphic address. + */ +static int ca91cx42_crcsr_init(struct vme_bridge *ca91cx42_bridge, + struct pci_dev *pdev) +{ + unsigned int crcsr_addr; + int tmp, slot; + struct ca91cx42_driver *bridge; + + bridge = ca91cx42_bridge->driver_priv; + + slot = ca91cx42_slot_get(ca91cx42_bridge); + + /* Write CSR Base Address if slot ID is supplied as a module param */ + if (geoid) + iowrite32(geoid << 27, bridge->base + VCSR_BS); + + dev_info(&pdev->dev, "CR/CSR Offset: %d\n", slot); + if (slot == 0) { + dev_err(&pdev->dev, "Slot number is unset, not configuring " + "CR/CSR space\n"); + return -EINVAL; + } + + /* Allocate mem for CR/CSR image */ + bridge->crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE, + &bridge->crcsr_bus); + if (bridge->crcsr_kernel == NULL) { + dev_err(&pdev->dev, "Failed to allocate memory for CR/CSR " + "image\n"); + return -ENOMEM; + } + + memset(bridge->crcsr_kernel, 0, VME_CRCSR_BUF_SIZE); + + crcsr_addr = slot * (512 * 1024); + iowrite32(bridge->crcsr_bus - crcsr_addr, bridge->base + VCSR_TO); + + tmp = ioread32(bridge->base + VCSR_CTL); + tmp |= CA91CX42_VCSR_CTL_EN; + iowrite32(tmp, bridge->base + VCSR_CTL); + + return 0; +} + +static void ca91cx42_crcsr_exit(struct vme_bridge *ca91cx42_bridge, + struct pci_dev *pdev) +{ + u32 tmp; + struct ca91cx42_driver *bridge; + + bridge = ca91cx42_bridge->driver_priv; + + /* Turn off CR/CSR space */ + tmp = ioread32(bridge->base + VCSR_CTL); + tmp &= ~CA91CX42_VCSR_CTL_EN; + iowrite32(tmp, bridge->base + VCSR_CTL); + + /* Free image */ + iowrite32(0, bridge->base + VCSR_TO); + + pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, bridge->crcsr_kernel, + bridge->crcsr_bus); +} + +static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + int retval, i; + u32 data; + struct list_head *pos = NULL; + struct vme_bridge *ca91cx42_bridge; + struct ca91cx42_driver *ca91cx42_device; + struct vme_master_resource *master_image; + struct vme_slave_resource *slave_image; + struct vme_dma_resource *dma_ctrlr; + struct vme_lm_resource *lm; + + /* We want to support more than one of each bridge so we need to + * dynamically allocate the bridge structure + */ + ca91cx42_bridge = kzalloc(sizeof(struct vme_bridge), GFP_KERNEL); + + if (ca91cx42_bridge == NULL) { + dev_err(&pdev->dev, "Failed to allocate memory for device " + "structure\n"); + retval = -ENOMEM; + goto err_struct; + } + + ca91cx42_device = kzalloc(sizeof(struct ca91cx42_driver), GFP_KERNEL); + + if (ca91cx42_device == NULL) { + dev_err(&pdev->dev, "Failed to allocate memory for device " + "structure\n"); + retval = -ENOMEM; + goto err_driver; + } + + ca91cx42_bridge->driver_priv = ca91cx42_device; + + /* Enable the device */ + retval = pci_enable_device(pdev); + if (retval) { + dev_err(&pdev->dev, "Unable to enable device\n"); + goto err_enable; + } + + /* Map Registers */ + retval = pci_request_regions(pdev, driver_name); + if (retval) { + dev_err(&pdev->dev, "Unable to reserve resources\n"); + goto err_resource; + } + + /* map registers in BAR 0 */ + ca91cx42_device->base = ioremap_nocache(pci_resource_start(pdev, 0), + 4096); + if (!ca91cx42_device->base) { + dev_err(&pdev->dev, "Unable to remap CRG region\n"); + retval = -EIO; + goto err_remap; + } + + /* Check to see if the mapping worked out */ + data = ioread32(ca91cx42_device->base + CA91CX42_PCI_ID) & 0x0000FFFF; + if (data != PCI_VENDOR_ID_TUNDRA) { + dev_err(&pdev->dev, "PCI_ID check failed\n"); + retval = -EIO; + goto err_test; + } + + /* Initialize wait queues & mutual exclusion flags */ + init_waitqueue_head(&ca91cx42_device->dma_queue); + init_waitqueue_head(&ca91cx42_device->iack_queue); + mutex_init(&ca91cx42_device->vme_int); + mutex_init(&ca91cx42_device->vme_rmw); + + ca91cx42_bridge->parent = &pdev->dev; + strcpy(ca91cx42_bridge->name, driver_name); + + /* Setup IRQ */ + retval = ca91cx42_irq_init(ca91cx42_bridge); + if (retval != 0) { + dev_err(&pdev->dev, "Chip Initialization failed.\n"); + goto err_irq; + } + + /* Add master windows to list */ + INIT_LIST_HEAD(&ca91cx42_bridge->master_resources); + for (i = 0; i < CA91C142_MAX_MASTER; i++) { + master_image = kmalloc(sizeof(struct vme_master_resource), + GFP_KERNEL); + if (master_image == NULL) { + dev_err(&pdev->dev, "Failed to allocate memory for " + "master resource structure\n"); + retval = -ENOMEM; + goto err_master; + } + master_image->parent = ca91cx42_bridge; + spin_lock_init(&master_image->lock); + master_image->locked = 0; + master_image->number = i; + master_image->address_attr = VME_A16 | VME_A24 | VME_A32 | + VME_CRCSR | VME_USER1 | VME_USER2; + master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | + VME_SUPER | VME_USER | VME_PROG | VME_DATA; + master_image->width_attr = VME_D8 | VME_D16 | VME_D32 | VME_D64; + memset(&master_image->bus_resource, 0, + sizeof(struct resource)); + master_image->kern_base = NULL; + list_add_tail(&master_image->list, + &ca91cx42_bridge->master_resources); + } + + /* Add slave windows to list */ + INIT_LIST_HEAD(&ca91cx42_bridge->slave_resources); + for (i = 0; i < CA91C142_MAX_SLAVE; i++) { + slave_image = kmalloc(sizeof(struct vme_slave_resource), + GFP_KERNEL); + if (slave_image == NULL) { + dev_err(&pdev->dev, "Failed to allocate memory for " + "slave resource structure\n"); + retval = -ENOMEM; + goto err_slave; + } + slave_image->parent = ca91cx42_bridge; + mutex_init(&slave_image->mtx); + slave_image->locked = 0; + slave_image->number = i; + slave_image->address_attr = VME_A24 | VME_A32 | VME_USER1 | + VME_USER2; + + /* Only windows 0 and 4 support A16 */ + if (i == 0 || i == 4) + slave_image->address_attr |= VME_A16; + + slave_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | + VME_SUPER | VME_USER | VME_PROG | VME_DATA; + list_add_tail(&slave_image->list, + &ca91cx42_bridge->slave_resources); + } + + /* Add dma engines to list */ + INIT_LIST_HEAD(&ca91cx42_bridge->dma_resources); + for (i = 0; i < CA91C142_MAX_DMA; i++) { + dma_ctrlr = kmalloc(sizeof(struct vme_dma_resource), + GFP_KERNEL); + if (dma_ctrlr == NULL) { + dev_err(&pdev->dev, "Failed to allocate memory for " + "dma resource structure\n"); + retval = -ENOMEM; + goto err_dma; + } + dma_ctrlr->parent = ca91cx42_bridge; + mutex_init(&dma_ctrlr->mtx); + dma_ctrlr->locked = 0; + dma_ctrlr->number = i; + dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM | + VME_DMA_MEM_TO_VME; + INIT_LIST_HEAD(&dma_ctrlr->pending); + INIT_LIST_HEAD(&dma_ctrlr->running); + list_add_tail(&dma_ctrlr->list, + &ca91cx42_bridge->dma_resources); + } + + /* Add location monitor to list */ + INIT_LIST_HEAD(&ca91cx42_bridge->lm_resources); + lm = kmalloc(sizeof(struct vme_lm_resource), GFP_KERNEL); + if (lm == NULL) { + dev_err(&pdev->dev, "Failed to allocate memory for " + "location monitor resource structure\n"); + retval = -ENOMEM; + goto err_lm; + } + lm->parent = ca91cx42_bridge; + mutex_init(&lm->mtx); + lm->locked = 0; + lm->number = 1; + lm->monitors = 4; + list_add_tail(&lm->list, &ca91cx42_bridge->lm_resources); + + ca91cx42_bridge->slave_get = ca91cx42_slave_get; + ca91cx42_bridge->slave_set = ca91cx42_slave_set; + ca91cx42_bridge->master_get = ca91cx42_master_get; + ca91cx42_bridge->master_set = ca91cx42_master_set; + ca91cx42_bridge->master_read = ca91cx42_master_read; + ca91cx42_bridge->master_write = ca91cx42_master_write; + ca91cx42_bridge->master_rmw = ca91cx42_master_rmw; + ca91cx42_bridge->dma_list_add = ca91cx42_dma_list_add; + ca91cx42_bridge->dma_list_exec = ca91cx42_dma_list_exec; + ca91cx42_bridge->dma_list_empty = ca91cx42_dma_list_empty; + ca91cx42_bridge->irq_set = ca91cx42_irq_set; + ca91cx42_bridge->irq_generate = ca91cx42_irq_generate; + ca91cx42_bridge->lm_set = ca91cx42_lm_set; + ca91cx42_bridge->lm_get = ca91cx42_lm_get; + ca91cx42_bridge->lm_attach = ca91cx42_lm_attach; + ca91cx42_bridge->lm_detach = ca91cx42_lm_detach; + ca91cx42_bridge->slot_get = ca91cx42_slot_get; + ca91cx42_bridge->alloc_consistent = ca91cx42_alloc_consistent; + ca91cx42_bridge->free_consistent = ca91cx42_free_consistent; + + data = ioread32(ca91cx42_device->base + MISC_CTL); + dev_info(&pdev->dev, "Board is%s the VME system controller\n", + (data & CA91CX42_MISC_CTL_SYSCON) ? "" : " not"); + dev_info(&pdev->dev, "Slot ID is %d\n", + ca91cx42_slot_get(ca91cx42_bridge)); + + if (ca91cx42_crcsr_init(ca91cx42_bridge, pdev)) + dev_err(&pdev->dev, "CR/CSR configuration failed.\n"); + + /* Need to save ca91cx42_bridge pointer locally in link list for use in + * ca91cx42_remove() + */ + retval = vme_register_bridge(ca91cx42_bridge); + if (retval != 0) { + dev_err(&pdev->dev, "Chip Registration failed.\n"); + goto err_reg; + } + + pci_set_drvdata(pdev, ca91cx42_bridge); + + return 0; + +err_reg: + ca91cx42_crcsr_exit(ca91cx42_bridge, pdev); +err_lm: + /* resources are stored in link list */ + list_for_each(pos, &ca91cx42_bridge->lm_resources) { + lm = list_entry(pos, struct vme_lm_resource, list); + list_del(pos); + kfree(lm); + } +err_dma: + /* resources are stored in link list */ + list_for_each(pos, &ca91cx42_bridge->dma_resources) { + dma_ctrlr = list_entry(pos, struct vme_dma_resource, list); + list_del(pos); + kfree(dma_ctrlr); + } +err_slave: + /* resources are stored in link list */ + list_for_each(pos, &ca91cx42_bridge->slave_resources) { + slave_image = list_entry(pos, struct vme_slave_resource, list); + list_del(pos); + kfree(slave_image); + } +err_master: + /* resources are stored in link list */ + list_for_each(pos, &ca91cx42_bridge->master_resources) { + master_image = list_entry(pos, struct vme_master_resource, + list); + list_del(pos); + kfree(master_image); + } + + ca91cx42_irq_exit(ca91cx42_device, pdev); +err_irq: +err_test: + iounmap(ca91cx42_device->base); +err_remap: + pci_release_regions(pdev); +err_resource: + pci_disable_device(pdev); +err_enable: + kfree(ca91cx42_device); +err_driver: + kfree(ca91cx42_bridge); +err_struct: + return retval; + +} + +static void ca91cx42_remove(struct pci_dev *pdev) +{ + struct list_head *pos = NULL; + struct vme_master_resource *master_image; + struct vme_slave_resource *slave_image; + struct vme_dma_resource *dma_ctrlr; + struct vme_lm_resource *lm; + struct ca91cx42_driver *bridge; + struct vme_bridge *ca91cx42_bridge = pci_get_drvdata(pdev); + + bridge = ca91cx42_bridge->driver_priv; + + + /* Turn off Ints */ + iowrite32(0, bridge->base + LINT_EN); + + /* Turn off the windows */ + iowrite32(0x00800000, bridge->base + LSI0_CTL); + iowrite32(0x00800000, bridge->base + LSI1_CTL); + iowrite32(0x00800000, bridge->base + LSI2_CTL); + iowrite32(0x00800000, bridge->base + LSI3_CTL); + iowrite32(0x00800000, bridge->base + LSI4_CTL); + iowrite32(0x00800000, bridge->base + LSI5_CTL); + iowrite32(0x00800000, bridge->base + LSI6_CTL); + iowrite32(0x00800000, bridge->base + LSI7_CTL); + iowrite32(0x00F00000, bridge->base + VSI0_CTL); + iowrite32(0x00F00000, bridge->base + VSI1_CTL); + iowrite32(0x00F00000, bridge->base + VSI2_CTL); + iowrite32(0x00F00000, bridge->base + VSI3_CTL); + iowrite32(0x00F00000, bridge->base + VSI4_CTL); + iowrite32(0x00F00000, bridge->base + VSI5_CTL); + iowrite32(0x00F00000, bridge->base + VSI6_CTL); + iowrite32(0x00F00000, bridge->base + VSI7_CTL); + + vme_unregister_bridge(ca91cx42_bridge); + + ca91cx42_crcsr_exit(ca91cx42_bridge, pdev); + + /* resources are stored in link list */ + list_for_each(pos, &ca91cx42_bridge->lm_resources) { + lm = list_entry(pos, struct vme_lm_resource, list); + list_del(pos); + kfree(lm); + } + + /* resources are stored in link list */ + list_for_each(pos, &ca91cx42_bridge->dma_resources) { + dma_ctrlr = list_entry(pos, struct vme_dma_resource, list); + list_del(pos); + kfree(dma_ctrlr); + } + + /* resources are stored in link list */ + list_for_each(pos, &ca91cx42_bridge->slave_resources) { + slave_image = list_entry(pos, struct vme_slave_resource, list); + list_del(pos); + kfree(slave_image); + } + + /* resources are stored in link list */ + list_for_each(pos, &ca91cx42_bridge->master_resources) { + master_image = list_entry(pos, struct vme_master_resource, + list); + list_del(pos); + kfree(master_image); + } + + ca91cx42_irq_exit(bridge, pdev); + + iounmap(bridge->base); + + pci_release_regions(pdev); + + pci_disable_device(pdev); + + kfree(ca91cx42_bridge); +} + +static void __exit ca91cx42_exit(void) +{ + pci_unregister_driver(&ca91cx42_driver); +} + +MODULE_PARM_DESC(geoid, "Override geographical addressing"); +module_param(geoid, int, 0); + +MODULE_DESCRIPTION("VME driver for the Tundra Universe II VME bridge"); +MODULE_LICENSE("GPL"); + +module_init(ca91cx42_init); +module_exit(ca91cx42_exit); diff --git a/drivers/vme/bridges/vme_ca91cx42.h b/drivers/vme/bridges/vme_ca91cx42.h new file mode 100644 index 0000000..02a7c79 --- /dev/null +++ b/drivers/vme/bridges/vme_ca91cx42.h @@ -0,0 +1,583 @@ +/* + * ca91c042.h + * + * Support for the Tundra Universe 1 and Universe II VME bridge chips + * + * Author: Tom Armistead + * Updated by Ajit Prem + * Copyright 2004 Motorola Inc. + * + * Further updated by Martyn Welch + * Copyright 2009 GE Intelligent Platforms Embedded Systems, Inc. + * + * Derived from ca91c042.h by Michael Wyrick + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef _CA91CX42_H +#define _CA91CX42_H + +#ifndef PCI_VENDOR_ID_TUNDRA +#define PCI_VENDOR_ID_TUNDRA 0x10e3 +#endif + +#ifndef PCI_DEVICE_ID_TUNDRA_CA91C142 +#define PCI_DEVICE_ID_TUNDRA_CA91C142 0x0000 +#endif + +/* + * Define the number of each that the CA91C142 supports. + */ +#define CA91C142_MAX_MASTER 8 /* Max Master Windows */ +#define CA91C142_MAX_SLAVE 8 /* Max Slave Windows */ +#define CA91C142_MAX_DMA 1 /* Max DMA Controllers */ +#define CA91C142_MAX_MAILBOX 4 /* Max Mail Box registers */ + +/* Structure used to hold driver specific information */ +struct ca91cx42_driver { + void __iomem *base; /* Base Address of device registers */ + wait_queue_head_t dma_queue; + wait_queue_head_t iack_queue; + wait_queue_head_t mbox_queue; + void (*lm_callback[4])(int); /* Called in interrupt handler */ + void *crcsr_kernel; + dma_addr_t crcsr_bus; + struct mutex vme_rmw; /* Only one RMW cycle at a time */ + struct mutex vme_int; /* + * Only one VME interrupt can be + * generated at a time, provide locking + */ +}; + +/* See Page 2-77 in the Universe User Manual */ +struct ca91cx42_dma_descriptor { + unsigned int dctl; /* DMA Control */ + unsigned int dtbc; /* Transfer Byte Count */ + unsigned int dla; /* PCI Address */ + unsigned int res1; /* Reserved */ + unsigned int dva; /* Vme Address */ + unsigned int res2; /* Reserved */ + unsigned int dcpp; /* Pointer to Numed Cmd Packet with rPN */ + unsigned int res3; /* Reserved */ +}; + +struct ca91cx42_dma_entry { + struct ca91cx42_dma_descriptor descriptor; + struct list_head list; +}; + +/* Universe Register Offsets */ +/* general PCI configuration registers */ +#define CA91CX42_PCI_ID 0x000 +#define CA91CX42_PCI_CSR 0x004 +#define CA91CX42_PCI_CLASS 0x008 +#define CA91CX42_PCI_MISC0 0x00C +#define CA91CX42_PCI_BS 0x010 +#define CA91CX42_PCI_MISC1 0x03C + +#define LSI0_CTL 0x0100 +#define LSI0_BS 0x0104 +#define LSI0_BD 0x0108 +#define LSI0_TO 0x010C + +#define LSI1_CTL 0x0114 +#define LSI1_BS 0x0118 +#define LSI1_BD 0x011C +#define LSI1_TO 0x0120 + +#define LSI2_CTL 0x0128 +#define LSI2_BS 0x012C +#define LSI2_BD 0x0130 +#define LSI2_TO 0x0134 + +#define LSI3_CTL 0x013C +#define LSI3_BS 0x0140 +#define LSI3_BD 0x0144 +#define LSI3_TO 0x0148 + +#define LSI4_CTL 0x01A0 +#define LSI4_BS 0x01A4 +#define LSI4_BD 0x01A8 +#define LSI4_TO 0x01AC + +#define LSI5_CTL 0x01B4 +#define LSI5_BS 0x01B8 +#define LSI5_BD 0x01BC +#define LSI5_TO 0x01C0 + +#define LSI6_CTL 0x01C8 +#define LSI6_BS 0x01CC +#define LSI6_BD 0x01D0 +#define LSI6_TO 0x01D4 + +#define LSI7_CTL 0x01DC +#define LSI7_BS 0x01E0 +#define LSI7_BD 0x01E4 +#define LSI7_TO 0x01E8 + +static const int CA91CX42_LSI_CTL[] = { LSI0_CTL, LSI1_CTL, LSI2_CTL, LSI3_CTL, + LSI4_CTL, LSI5_CTL, LSI6_CTL, LSI7_CTL }; + +static const int CA91CX42_LSI_BS[] = { LSI0_BS, LSI1_BS, LSI2_BS, LSI3_BS, + LSI4_BS, LSI5_BS, LSI6_BS, LSI7_BS }; + +static const int CA91CX42_LSI_BD[] = { LSI0_BD, LSI1_BD, LSI2_BD, LSI3_BD, + LSI4_BD, LSI5_BD, LSI6_BD, LSI7_BD }; + +static const int CA91CX42_LSI_TO[] = { LSI0_TO, LSI1_TO, LSI2_TO, LSI3_TO, + LSI4_TO, LSI5_TO, LSI6_TO, LSI7_TO }; + +#define SCYC_CTL 0x0170 +#define SCYC_ADDR 0x0174 +#define SCYC_EN 0x0178 +#define SCYC_CMP 0x017C +#define SCYC_SWP 0x0180 +#define LMISC 0x0184 +#define SLSI 0x0188 +#define L_CMDERR 0x018C +#define LAERR 0x0190 + +#define DCTL 0x0200 +#define DTBC 0x0204 +#define DLA 0x0208 +#define DVA 0x0210 +#define DCPP 0x0218 +#define DGCS 0x0220 +#define D_LLUE 0x0224 + +#define LINT_EN 0x0300 +#define LINT_STAT 0x0304 +#define LINT_MAP0 0x0308 +#define LINT_MAP1 0x030C +#define VINT_EN 0x0310 +#define VINT_STAT 0x0314 +#define VINT_MAP0 0x0318 +#define VINT_MAP1 0x031C +#define STATID 0x0320 + +#define V1_STATID 0x0324 +#define V2_STATID 0x0328 +#define V3_STATID 0x032C +#define V4_STATID 0x0330 +#define V5_STATID 0x0334 +#define V6_STATID 0x0338 +#define V7_STATID 0x033C + +static const int CA91CX42_V_STATID[8] = { 0, V1_STATID, V2_STATID, V3_STATID, + V4_STATID, V5_STATID, V6_STATID, + V7_STATID }; + +#define LINT_MAP2 0x0340 +#define VINT_MAP2 0x0344 + +#define MBOX0 0x0348 +#define MBOX1 0x034C +#define MBOX2 0x0350 +#define MBOX3 0x0354 +#define SEMA0 0x0358 +#define SEMA1 0x035C + +#define MAST_CTL 0x0400 +#define MISC_CTL 0x0404 +#define MISC_STAT 0x0408 +#define USER_AM 0x040C + +#define VSI0_CTL 0x0F00 +#define VSI0_BS 0x0F04 +#define VSI0_BD 0x0F08 +#define VSI0_TO 0x0F0C + +#define VSI1_CTL 0x0F14 +#define VSI1_BS 0x0F18 +#define VSI1_BD 0x0F1C +#define VSI1_TO 0x0F20 + +#define VSI2_CTL 0x0F28 +#define VSI2_BS 0x0F2C +#define VSI2_BD 0x0F30 +#define VSI2_TO 0x0F34 + +#define VSI3_CTL 0x0F3C +#define VSI3_BS 0x0F40 +#define VSI3_BD 0x0F44 +#define VSI3_TO 0x0F48 + +#define LM_CTL 0x0F64 +#define LM_BS 0x0F68 + +#define VRAI_CTL 0x0F70 + +#define VRAI_BS 0x0F74 +#define VCSR_CTL 0x0F80 +#define VCSR_TO 0x0F84 +#define V_AMERR 0x0F88 +#define VAERR 0x0F8C + +#define VSI4_CTL 0x0F90 +#define VSI4_BS 0x0F94 +#define VSI4_BD 0x0F98 +#define VSI4_TO 0x0F9C + +#define VSI5_CTL 0x0FA4 +#define VSI5_BS 0x0FA8 +#define VSI5_BD 0x0FAC +#define VSI5_TO 0x0FB0 + +#define VSI6_CTL 0x0FB8 +#define VSI6_BS 0x0FBC +#define VSI6_BD 0x0FC0 +#define VSI6_TO 0x0FC4 + +#define VSI7_CTL 0x0FCC +#define VSI7_BS 0x0FD0 +#define VSI7_BD 0x0FD4 +#define VSI7_TO 0x0FD8 + +static const int CA91CX42_VSI_CTL[] = { VSI0_CTL, VSI1_CTL, VSI2_CTL, VSI3_CTL, + VSI4_CTL, VSI5_CTL, VSI6_CTL, VSI7_CTL }; + +static const int CA91CX42_VSI_BS[] = { VSI0_BS, VSI1_BS, VSI2_BS, VSI3_BS, + VSI4_BS, VSI5_BS, VSI6_BS, VSI7_BS }; + +static const int CA91CX42_VSI_BD[] = { VSI0_BD, VSI1_BD, VSI2_BD, VSI3_BD, + VSI4_BD, VSI5_BD, VSI6_BD, VSI7_BD }; + +static const int CA91CX42_VSI_TO[] = { VSI0_TO, VSI1_TO, VSI2_TO, VSI3_TO, + VSI4_TO, VSI5_TO, VSI6_TO, VSI7_TO }; + +#define VCSR_CLR 0x0FF4 +#define VCSR_SET 0x0FF8 +#define VCSR_BS 0x0FFC + +/* + * PCI Class Register + * offset 008 + */ +#define CA91CX42_BM_PCI_CLASS_BASE 0xFF000000 +#define CA91CX42_OF_PCI_CLASS_BASE 24 +#define CA91CX42_BM_PCI_CLASS_SUB 0x00FF0000 +#define CA91CX42_OF_PCI_CLASS_SUB 16 +#define CA91CX42_BM_PCI_CLASS_PROG 0x0000FF00 +#define CA91CX42_OF_PCI_CLASS_PROG 8 +#define CA91CX42_BM_PCI_CLASS_RID 0x000000FF +#define CA91CX42_OF_PCI_CLASS_RID 0 + +#define CA91CX42_OF_PCI_CLASS_RID_UNIVERSE_I 0 +#define CA91CX42_OF_PCI_CLASS_RID_UNIVERSE_II 1 + +/* + * PCI Misc Register + * offset 00C + */ +#define CA91CX42_BM_PCI_MISC0_BISTC 0x80000000 +#define CA91CX42_BM_PCI_MISC0_SBIST 0x60000000 +#define CA91CX42_BM_PCI_MISC0_CCODE 0x0F000000 +#define CA91CX42_BM_PCI_MISC0_MFUNCT 0x00800000 +#define CA91CX42_BM_PCI_MISC0_LAYOUT 0x007F0000 +#define CA91CX42_BM_PCI_MISC0_LTIMER 0x0000FF00 +#define CA91CX42_OF_PCI_MISC0_LTIMER 8 + + +/* + * LSI Control Register + * offset 100 + */ +#define CA91CX42_LSI_CTL_EN (1<<31) +#define CA91CX42_LSI_CTL_PWEN (1<<30) + +#define CA91CX42_LSI_CTL_VDW_M (3<<22) +#define CA91CX42_LSI_CTL_VDW_D8 0 +#define CA91CX42_LSI_CTL_VDW_D16 (1<<22) +#define CA91CX42_LSI_CTL_VDW_D32 (1<<23) +#define CA91CX42_LSI_CTL_VDW_D64 (3<<22) + +#define CA91CX42_LSI_CTL_VAS_M (7<<16) +#define CA91CX42_LSI_CTL_VAS_A16 0 +#define CA91CX42_LSI_CTL_VAS_A24 (1<<16) +#define CA91CX42_LSI_CTL_VAS_A32 (1<<17) +#define CA91CX42_LSI_CTL_VAS_CRCSR (5<<16) +#define CA91CX42_LSI_CTL_VAS_USER1 (3<<17) +#define CA91CX42_LSI_CTL_VAS_USER2 (7<<16) + +#define CA91CX42_LSI_CTL_PGM_M (1<<14) +#define CA91CX42_LSI_CTL_PGM_DATA 0 +#define CA91CX42_LSI_CTL_PGM_PGM (1<<14) + +#define CA91CX42_LSI_CTL_SUPER_M (1<<12) +#define CA91CX42_LSI_CTL_SUPER_NPRIV 0 +#define CA91CX42_LSI_CTL_SUPER_SUPR (1<<12) + +#define CA91CX42_LSI_CTL_VCT_M (1<<8) +#define CA91CX42_LSI_CTL_VCT_BLT (1<<8) +#define CA91CX42_LSI_CTL_VCT_MBLT (1<<8) +#define CA91CX42_LSI_CTL_LAS (1<<0) + +/* + * SCYC_CTL Register + * offset 178 + */ +#define CA91CX42_SCYC_CTL_LAS_PCIMEM 0 +#define CA91CX42_SCYC_CTL_LAS_PCIIO (1<<2) + +#define CA91CX42_SCYC_CTL_CYC_M (3<<0) +#define CA91CX42_SCYC_CTL_CYC_RMW (1<<0) +#define CA91CX42_SCYC_CTL_CYC_ADOH (1<<1) + +/* + * LMISC Register + * offset 184 + */ +#define CA91CX42_BM_LMISC_CRT 0xF0000000 +#define CA91CX42_OF_LMISC_CRT 28 +#define CA91CX42_BM_LMISC_CWT 0x0F000000 +#define CA91CX42_OF_LMISC_CWT 24 + +/* + * SLSI Register + * offset 188 + */ +#define CA91CX42_BM_SLSI_EN 0x80000000 +#define CA91CX42_BM_SLSI_PWEN 0x40000000 +#define CA91CX42_BM_SLSI_VDW 0x00F00000 +#define CA91CX42_OF_SLSI_VDW 20 +#define CA91CX42_BM_SLSI_PGM 0x0000F000 +#define CA91CX42_OF_SLSI_PGM 12 +#define CA91CX42_BM_SLSI_SUPER 0x00000F00 +#define CA91CX42_OF_SLSI_SUPER 8 +#define CA91CX42_BM_SLSI_BS 0x000000F6 +#define CA91CX42_OF_SLSI_BS 2 +#define CA91CX42_BM_SLSI_LAS 0x00000003 +#define CA91CX42_OF_SLSI_LAS 0 +#define CA91CX42_BM_SLSI_RESERVED 0x3F0F0000 + +/* + * DCTL Register + * offset 200 + */ +#define CA91CX42_DCTL_L2V (1<<31) +#define CA91CX42_DCTL_VDW_M (3<<22) +#define CA91CX42_DCTL_VDW_M (3<<22) +#define CA91CX42_DCTL_VDW_D8 0 +#define CA91CX42_DCTL_VDW_D16 (1<<22) +#define CA91CX42_DCTL_VDW_D32 (1<<23) +#define CA91CX42_DCTL_VDW_D64 (3<<22) + +#define CA91CX42_DCTL_VAS_M (7<<16) +#define CA91CX42_DCTL_VAS_A16 0 +#define CA91CX42_DCTL_VAS_A24 (1<<16) +#define CA91CX42_DCTL_VAS_A32 (1<<17) +#define CA91CX42_DCTL_VAS_USER1 (3<<17) +#define CA91CX42_DCTL_VAS_USER2 (7<<16) + +#define CA91CX42_DCTL_PGM_M (1<<14) +#define CA91CX42_DCTL_PGM_DATA 0 +#define CA91CX42_DCTL_PGM_PGM (1<<14) + +#define CA91CX42_DCTL_SUPER_M (1<<12) +#define CA91CX42_DCTL_SUPER_NPRIV 0 +#define CA91CX42_DCTL_SUPER_SUPR (1<<12) + +#define CA91CX42_DCTL_VCT_M (1<<8) +#define CA91CX42_DCTL_VCT_BLT (1<<8) +#define CA91CX42_DCTL_LD64EN (1<<7) + +/* + * DCPP Register + * offset 218 + */ +#define CA91CX42_DCPP_M 0xf +#define CA91CX42_DCPP_NULL (1<<0) + +/* + * DMA General Control/Status Register (DGCS) + * offset 220 + */ +#define CA91CX42_DGCS_GO (1<<31) +#define CA91CX42_DGCS_STOP_REQ (1<<30) +#define CA91CX42_DGCS_HALT_REQ (1<<29) +#define CA91CX42_DGCS_CHAIN (1<<27) + +#define CA91CX42_DGCS_VON_M (7<<20) + +#define CA91CX42_DGCS_VOFF_M (0xf<<16) + +#define CA91CX42_DGCS_ACT (1<<15) +#define CA91CX42_DGCS_STOP (1<<14) +#define CA91CX42_DGCS_HALT (1<<13) +#define CA91CX42_DGCS_DONE (1<<11) +#define CA91CX42_DGCS_LERR (1<<10) +#define CA91CX42_DGCS_VERR (1<<9) +#define CA91CX42_DGCS_PERR (1<<8) +#define CA91CX42_DGCS_INT_STOP (1<<6) +#define CA91CX42_DGCS_INT_HALT (1<<5) +#define CA91CX42_DGCS_INT_DONE (1<<3) +#define CA91CX42_DGCS_INT_LERR (1<<2) +#define CA91CX42_DGCS_INT_VERR (1<<1) +#define CA91CX42_DGCS_INT_PERR (1<<0) + +/* + * PCI Interrupt Enable Register + * offset 300 + */ +#define CA91CX42_LINT_LM3 0x00800000 +#define CA91CX42_LINT_LM2 0x00400000 +#define CA91CX42_LINT_LM1 0x00200000 +#define CA91CX42_LINT_LM0 0x00100000 +#define CA91CX42_LINT_MBOX3 0x00080000 +#define CA91CX42_LINT_MBOX2 0x00040000 +#define CA91CX42_LINT_MBOX1 0x00020000 +#define CA91CX42_LINT_MBOX0 0x00010000 +#define CA91CX42_LINT_ACFAIL 0x00008000 +#define CA91CX42_LINT_SYSFAIL 0x00004000 +#define CA91CX42_LINT_SW_INT 0x00002000 +#define CA91CX42_LINT_SW_IACK 0x00001000 + +#define CA91CX42_LINT_VERR 0x00000400 +#define CA91CX42_LINT_LERR 0x00000200 +#define CA91CX42_LINT_DMA 0x00000100 +#define CA91CX42_LINT_VIRQ7 0x00000080 +#define CA91CX42_LINT_VIRQ6 0x00000040 +#define CA91CX42_LINT_VIRQ5 0x00000020 +#define CA91CX42_LINT_VIRQ4 0x00000010 +#define CA91CX42_LINT_VIRQ3 0x00000008 +#define CA91CX42_LINT_VIRQ2 0x00000004 +#define CA91CX42_LINT_VIRQ1 0x00000002 +#define CA91CX42_LINT_VOWN 0x00000001 + +static const int CA91CX42_LINT_VIRQ[] = { 0, CA91CX42_LINT_VIRQ1, + CA91CX42_LINT_VIRQ2, CA91CX42_LINT_VIRQ3, + CA91CX42_LINT_VIRQ4, CA91CX42_LINT_VIRQ5, + CA91CX42_LINT_VIRQ6, CA91CX42_LINT_VIRQ7 }; + +#define CA91CX42_LINT_MBOX 0x000F0000 + +static const int CA91CX42_LINT_LM[] = { CA91CX42_LINT_LM0, CA91CX42_LINT_LM1, + CA91CX42_LINT_LM2, CA91CX42_LINT_LM3 }; + +/* + * MAST_CTL Register + * offset 400 + */ +#define CA91CX42_BM_MAST_CTL_MAXRTRY 0xF0000000 +#define CA91CX42_OF_MAST_CTL_MAXRTRY 28 +#define CA91CX42_BM_MAST_CTL_PWON 0x0F000000 +#define CA91CX42_OF_MAST_CTL_PWON 24 +#define CA91CX42_BM_MAST_CTL_VRL 0x00C00000 +#define CA91CX42_OF_MAST_CTL_VRL 22 +#define CA91CX42_BM_MAST_CTL_VRM 0x00200000 +#define CA91CX42_BM_MAST_CTL_VREL 0x00100000 +#define CA91CX42_BM_MAST_CTL_VOWN 0x00080000 +#define CA91CX42_BM_MAST_CTL_VOWN_ACK 0x00040000 +#define CA91CX42_BM_MAST_CTL_PABS 0x00001000 +#define CA91CX42_BM_MAST_CTL_BUS_NO 0x0000000F +#define CA91CX42_OF_MAST_CTL_BUS_NO 0 + +/* + * MISC_CTL Register + * offset 404 + */ +#define CA91CX42_MISC_CTL_VBTO 0xF0000000 +#define CA91CX42_MISC_CTL_VARB 0x04000000 +#define CA91CX42_MISC_CTL_VARBTO 0x03000000 +#define CA91CX42_MISC_CTL_SW_LRST 0x00800000 +#define CA91CX42_MISC_CTL_SW_SRST 0x00400000 +#define CA91CX42_MISC_CTL_BI 0x00100000 +#define CA91CX42_MISC_CTL_ENGBI 0x00080000 +#define CA91CX42_MISC_CTL_RESCIND 0x00040000 +#define CA91CX42_MISC_CTL_SYSCON 0x00020000 +#define CA91CX42_MISC_CTL_V64AUTO 0x00010000 +#define CA91CX42_MISC_CTL_RESERVED 0x0820FFFF + +#define CA91CX42_OF_MISC_CTL_VARBTO 24 +#define CA91CX42_OF_MISC_CTL_VBTO 28 + +/* + * MISC_STAT Register + * offset 408 + */ +#define CA91CX42_BM_MISC_STAT_ENDIAN 0x80000000 +#define CA91CX42_BM_MISC_STAT_LCLSIZE 0x40000000 +#define CA91CX42_BM_MISC_STAT_DY4AUTO 0x08000000 +#define CA91CX42_BM_MISC_STAT_MYBBSY 0x00200000 +#define CA91CX42_BM_MISC_STAT_DY4DONE 0x00080000 +#define CA91CX42_BM_MISC_STAT_TXFE 0x00040000 +#define CA91CX42_BM_MISC_STAT_RXFE 0x00020000 +#define CA91CX42_BM_MISC_STAT_DY4AUTOID 0x0000FF00 +#define CA91CX42_OF_MISC_STAT_DY4AUTOID 8 + +/* + * VSI Control Register + * offset F00 + */ +#define CA91CX42_VSI_CTL_EN (1<<31) +#define CA91CX42_VSI_CTL_PWEN (1<<30) +#define CA91CX42_VSI_CTL_PREN (1<<29) + +#define CA91CX42_VSI_CTL_PGM_M (3<<22) +#define CA91CX42_VSI_CTL_PGM_DATA (1<<22) +#define CA91CX42_VSI_CTL_PGM_PGM (1<<23) + +#define CA91CX42_VSI_CTL_SUPER_M (3<<20) +#define CA91CX42_VSI_CTL_SUPER_NPRIV (1<<20) +#define CA91CX42_VSI_CTL_SUPER_SUPR (1<<21) + +#define CA91CX42_VSI_CTL_VAS_M (7<<16) +#define CA91CX42_VSI_CTL_VAS_A16 0 +#define CA91CX42_VSI_CTL_VAS_A24 (1<<16) +#define CA91CX42_VSI_CTL_VAS_A32 (1<<17) +#define CA91CX42_VSI_CTL_VAS_USER1 (3<<17) +#define CA91CX42_VSI_CTL_VAS_USER2 (7<<16) + +#define CA91CX42_VSI_CTL_LD64EN (1<<7) +#define CA91CX42_VSI_CTL_LLRMW (1<<6) + +#define CA91CX42_VSI_CTL_LAS_M (3<<0) +#define CA91CX42_VSI_CTL_LAS_PCI_MS 0 +#define CA91CX42_VSI_CTL_LAS_PCI_IO (1<<0) +#define CA91CX42_VSI_CTL_LAS_PCI_CONF (1<<1) + +/* LM_CTL Register + * offset F64 + */ +#define CA91CX42_LM_CTL_EN (1<<31) +#define CA91CX42_LM_CTL_PGM (1<<23) +#define CA91CX42_LM_CTL_DATA (1<<22) +#define CA91CX42_LM_CTL_SUPR (1<<21) +#define CA91CX42_LM_CTL_NPRIV (1<<20) +#define CA91CX42_LM_CTL_AS_M (5<<16) +#define CA91CX42_LM_CTL_AS_A16 0 +#define CA91CX42_LM_CTL_AS_A24 (1<<16) +#define CA91CX42_LM_CTL_AS_A32 (1<<17) + +/* + * VRAI_CTL Register + * offset F70 + */ +#define CA91CX42_BM_VRAI_CTL_EN 0x80000000 +#define CA91CX42_BM_VRAI_CTL_PGM 0x00C00000 +#define CA91CX42_OF_VRAI_CTL_PGM 22 +#define CA91CX42_BM_VRAI_CTL_SUPER 0x00300000 +#define CA91CX42_OF_VRAI_CTL_SUPER 20 +#define CA91CX42_BM_VRAI_CTL_VAS 0x00030000 +#define CA91CX42_OF_VRAI_CTL_VAS 16 + +/* VCSR_CTL Register + * offset F80 + */ +#define CA91CX42_VCSR_CTL_EN (1<<31) + +#define CA91CX42_VCSR_CTL_LAS_M (3<<0) +#define CA91CX42_VCSR_CTL_LAS_PCI_MS 0 +#define CA91CX42_VCSR_CTL_LAS_PCI_IO (1<<0) +#define CA91CX42_VCSR_CTL_LAS_PCI_CONF (1<<1) + +/* VCSR_BS Register + * offset FFC + */ +#define CA91CX42_VCSR_BS_SLOT_M (0x1F<<27) + +#endif /* _CA91CX42_H */ diff --git a/drivers/vme/bridges/vme_tsi148.c b/drivers/vme/bridges/vme_tsi148.c new file mode 100644 index 0000000..081e9c4 --- /dev/null +++ b/drivers/vme/bridges/vme_tsi148.c @@ -0,0 +1,2691 @@ +/* + * Support for the Tundra TSI148 VME-PCI Bridge Chip + * + * Author: Martyn Welch + * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. + * + * Based on work by Tom Armistead and Ajit Prem + * Copyright 2004 Motorola 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../vme_bridge.h" +#include "vme_tsi148.h" + +static int __init tsi148_init(void); +static int tsi148_probe(struct pci_dev *, const struct pci_device_id *); +static void tsi148_remove(struct pci_dev *); +static void __exit tsi148_exit(void); + + +/* Module parameter */ +static bool err_chk; +static int geoid; + +static const char driver_name[] = "vme_tsi148"; + +static DEFINE_PCI_DEVICE_TABLE(tsi148_ids) = { + { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_TSI148) }, + { }, +}; + +static struct pci_driver tsi148_driver = { + .name = driver_name, + .id_table = tsi148_ids, + .probe = tsi148_probe, + .remove = tsi148_remove, +}; + +static void reg_join(unsigned int high, unsigned int low, + unsigned long long *variable) +{ + *variable = (unsigned long long)high << 32; + *variable |= (unsigned long long)low; +} + +static void reg_split(unsigned long long variable, unsigned int *high, + unsigned int *low) +{ + *low = (unsigned int)variable & 0xFFFFFFFF; + *high = (unsigned int)(variable >> 32); +} + +/* + * Wakes up DMA queue. + */ +static u32 tsi148_DMA_irqhandler(struct tsi148_driver *bridge, + int channel_mask) +{ + u32 serviced = 0; + + if (channel_mask & TSI148_LCSR_INTS_DMA0S) { + wake_up(&bridge->dma_queue[0]); + serviced |= TSI148_LCSR_INTC_DMA0C; + } + if (channel_mask & TSI148_LCSR_INTS_DMA1S) { + wake_up(&bridge->dma_queue[1]); + serviced |= TSI148_LCSR_INTC_DMA1C; + } + + return serviced; +} + +/* + * Wake up location monitor queue + */ +static u32 tsi148_LM_irqhandler(struct tsi148_driver *bridge, u32 stat) +{ + int i; + u32 serviced = 0; + + for (i = 0; i < 4; i++) { + if (stat & TSI148_LCSR_INTS_LMS[i]) { + /* We only enable interrupts if the callback is set */ + bridge->lm_callback[i](i); + serviced |= TSI148_LCSR_INTC_LMC[i]; + } + } + + return serviced; +} + +/* + * Wake up mail box queue. + * + * XXX This functionality is not exposed up though API. + */ +static u32 tsi148_MB_irqhandler(struct vme_bridge *tsi148_bridge, u32 stat) +{ + int i; + u32 val; + u32 serviced = 0; + struct tsi148_driver *bridge; + + bridge = tsi148_bridge->driver_priv; + + for (i = 0; i < 4; i++) { + if (stat & TSI148_LCSR_INTS_MBS[i]) { + val = ioread32be(bridge->base + TSI148_GCSR_MBOX[i]); + dev_err(tsi148_bridge->parent, "VME Mailbox %d received" + ": 0x%x\n", i, val); + serviced |= TSI148_LCSR_INTC_MBC[i]; + } + } + + return serviced; +} + +/* + * Display error & status message when PERR (PCI) exception interrupt occurs. + */ +static u32 tsi148_PERR_irqhandler(struct vme_bridge *tsi148_bridge) +{ + struct tsi148_driver *bridge; + + bridge = tsi148_bridge->driver_priv; + + dev_err(tsi148_bridge->parent, "PCI Exception at address: 0x%08x:%08x, " + "attributes: %08x\n", + ioread32be(bridge->base + TSI148_LCSR_EDPAU), + ioread32be(bridge->base + TSI148_LCSR_EDPAL), + ioread32be(bridge->base + TSI148_LCSR_EDPAT)); + + dev_err(tsi148_bridge->parent, "PCI-X attribute reg: %08x, PCI-X split " + "completion reg: %08x\n", + ioread32be(bridge->base + TSI148_LCSR_EDPXA), + ioread32be(bridge->base + TSI148_LCSR_EDPXS)); + + iowrite32be(TSI148_LCSR_EDPAT_EDPCL, bridge->base + TSI148_LCSR_EDPAT); + + return TSI148_LCSR_INTC_PERRC; +} + +/* + * Save address and status when VME error interrupt occurs. + */ +static u32 tsi148_VERR_irqhandler(struct vme_bridge *tsi148_bridge) +{ + unsigned int error_addr_high, error_addr_low; + unsigned long long error_addr; + u32 error_attrib; + struct vme_bus_error *error; + struct tsi148_driver *bridge; + + bridge = tsi148_bridge->driver_priv; + + error_addr_high = ioread32be(bridge->base + TSI148_LCSR_VEAU); + error_addr_low = ioread32be(bridge->base + TSI148_LCSR_VEAL); + error_attrib = ioread32be(bridge->base + TSI148_LCSR_VEAT); + + reg_join(error_addr_high, error_addr_low, &error_addr); + + /* Check for exception register overflow (we have lost error data) */ + if (error_attrib & TSI148_LCSR_VEAT_VEOF) { + dev_err(tsi148_bridge->parent, "VME Bus Exception Overflow " + "Occurred\n"); + } + + error = kmalloc(sizeof(struct vme_bus_error), GFP_ATOMIC); + if (error) { + error->address = error_addr; + error->attributes = error_attrib; + list_add_tail(&error->list, &tsi148_bridge->vme_errors); + } else { + dev_err(tsi148_bridge->parent, "Unable to alloc memory for " + "VMEbus Error reporting\n"); + dev_err(tsi148_bridge->parent, "VME Bus Error at address: " + "0x%llx, attributes: %08x\n", error_addr, error_attrib); + } + + /* Clear Status */ + iowrite32be(TSI148_LCSR_VEAT_VESCL, bridge->base + TSI148_LCSR_VEAT); + + return TSI148_LCSR_INTC_VERRC; +} + +/* + * Wake up IACK queue. + */ +static u32 tsi148_IACK_irqhandler(struct tsi148_driver *bridge) +{ + wake_up(&bridge->iack_queue); + + return TSI148_LCSR_INTC_IACKC; +} + +/* + * Calling VME bus interrupt callback if provided. + */ +static u32 tsi148_VIRQ_irqhandler(struct vme_bridge *tsi148_bridge, + u32 stat) +{ + int vec, i, serviced = 0; + struct tsi148_driver *bridge; + + bridge = tsi148_bridge->driver_priv; + + for (i = 7; i > 0; i--) { + if (stat & (1 << i)) { + /* + * Note: Even though the registers are defined as + * 32-bits in the spec, we only want to issue 8-bit + * IACK cycles on the bus, read from offset 3. + */ + vec = ioread8(bridge->base + TSI148_LCSR_VIACK[i] + 3); + + vme_irq_handler(tsi148_bridge, i, vec); + + serviced |= (1 << i); + } + } + + return serviced; +} + +/* + * Top level interrupt handler. Clears appropriate interrupt status bits and + * then calls appropriate sub handler(s). + */ +static irqreturn_t tsi148_irqhandler(int irq, void *ptr) +{ + u32 stat, enable, serviced = 0; + struct vme_bridge *tsi148_bridge; + struct tsi148_driver *bridge; + + tsi148_bridge = ptr; + + bridge = tsi148_bridge->driver_priv; + + /* Determine which interrupts are unmasked and set */ + enable = ioread32be(bridge->base + TSI148_LCSR_INTEO); + stat = ioread32be(bridge->base + TSI148_LCSR_INTS); + + /* Only look at unmasked interrupts */ + stat &= enable; + + if (unlikely(!stat)) + return IRQ_NONE; + + /* Call subhandlers as appropriate */ + /* DMA irqs */ + if (stat & (TSI148_LCSR_INTS_DMA1S | TSI148_LCSR_INTS_DMA0S)) + serviced |= tsi148_DMA_irqhandler(bridge, stat); + + /* Location monitor irqs */ + if (stat & (TSI148_LCSR_INTS_LM3S | TSI148_LCSR_INTS_LM2S | + TSI148_LCSR_INTS_LM1S | TSI148_LCSR_INTS_LM0S)) + serviced |= tsi148_LM_irqhandler(bridge, stat); + + /* Mail box irqs */ + if (stat & (TSI148_LCSR_INTS_MB3S | TSI148_LCSR_INTS_MB2S | + TSI148_LCSR_INTS_MB1S | TSI148_LCSR_INTS_MB0S)) + serviced |= tsi148_MB_irqhandler(tsi148_bridge, stat); + + /* PCI bus error */ + if (stat & TSI148_LCSR_INTS_PERRS) + serviced |= tsi148_PERR_irqhandler(tsi148_bridge); + + /* VME bus error */ + if (stat & TSI148_LCSR_INTS_VERRS) + serviced |= tsi148_VERR_irqhandler(tsi148_bridge); + + /* IACK irq */ + if (stat & TSI148_LCSR_INTS_IACKS) + serviced |= tsi148_IACK_irqhandler(bridge); + + /* VME bus irqs */ + if (stat & (TSI148_LCSR_INTS_IRQ7S | TSI148_LCSR_INTS_IRQ6S | + TSI148_LCSR_INTS_IRQ5S | TSI148_LCSR_INTS_IRQ4S | + TSI148_LCSR_INTS_IRQ3S | TSI148_LCSR_INTS_IRQ2S | + TSI148_LCSR_INTS_IRQ1S)) + serviced |= tsi148_VIRQ_irqhandler(tsi148_bridge, stat); + + /* Clear serviced interrupts */ + iowrite32be(serviced, bridge->base + TSI148_LCSR_INTC); + + return IRQ_HANDLED; +} + +static int tsi148_irq_init(struct vme_bridge *tsi148_bridge) +{ + int result; + unsigned int tmp; + struct pci_dev *pdev; + struct tsi148_driver *bridge; + + pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev); + + bridge = tsi148_bridge->driver_priv; + + /* Initialise list for VME bus errors */ + INIT_LIST_HEAD(&tsi148_bridge->vme_errors); + + mutex_init(&tsi148_bridge->irq_mtx); + + result = request_irq(pdev->irq, + tsi148_irqhandler, + IRQF_SHARED, + driver_name, tsi148_bridge); + if (result) { + dev_err(tsi148_bridge->parent, "Can't get assigned pci irq " + "vector %02X\n", pdev->irq); + return result; + } + + /* Enable and unmask interrupts */ + tmp = TSI148_LCSR_INTEO_DMA1EO | TSI148_LCSR_INTEO_DMA0EO | + TSI148_LCSR_INTEO_MB3EO | TSI148_LCSR_INTEO_MB2EO | + TSI148_LCSR_INTEO_MB1EO | TSI148_LCSR_INTEO_MB0EO | + TSI148_LCSR_INTEO_PERREO | TSI148_LCSR_INTEO_VERREO | + TSI148_LCSR_INTEO_IACKEO; + + /* This leaves the following interrupts masked. + * TSI148_LCSR_INTEO_VIEEO + * TSI148_LCSR_INTEO_SYSFLEO + * TSI148_LCSR_INTEO_ACFLEO + */ + + /* Don't enable Location Monitor interrupts here - they will be + * enabled when the location monitors are properly configured and + * a callback has been attached. + * TSI148_LCSR_INTEO_LM0EO + * TSI148_LCSR_INTEO_LM1EO + * TSI148_LCSR_INTEO_LM2EO + * TSI148_LCSR_INTEO_LM3EO + */ + + /* Don't enable VME interrupts until we add a handler, else the board + * will respond to it and we don't want that unless it knows how to + * properly deal with it. + * TSI148_LCSR_INTEO_IRQ7EO + * TSI148_LCSR_INTEO_IRQ6EO + * TSI148_LCSR_INTEO_IRQ5EO + * TSI148_LCSR_INTEO_IRQ4EO + * TSI148_LCSR_INTEO_IRQ3EO + * TSI148_LCSR_INTEO_IRQ2EO + * TSI148_LCSR_INTEO_IRQ1EO + */ + + iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO); + iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN); + + return 0; +} + +static void tsi148_irq_exit(struct vme_bridge *tsi148_bridge, + struct pci_dev *pdev) +{ + struct tsi148_driver *bridge = tsi148_bridge->driver_priv; + + /* Turn off interrupts */ + iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEO); + iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEN); + + /* Clear all interrupts */ + iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_INTC); + + /* Detach interrupt handler */ + free_irq(pdev->irq, tsi148_bridge); +} + +/* + * Check to see if an IACk has been received, return true (1) or false (0). + */ +static int tsi148_iack_received(struct tsi148_driver *bridge) +{ + u32 tmp; + + tmp = ioread32be(bridge->base + TSI148_LCSR_VICR); + + if (tmp & TSI148_LCSR_VICR_IRQS) + return 0; + else + return 1; +} + +/* + * Configure VME interrupt + */ +static void tsi148_irq_set(struct vme_bridge *tsi148_bridge, int level, + int state, int sync) +{ + struct pci_dev *pdev; + u32 tmp; + struct tsi148_driver *bridge; + + bridge = tsi148_bridge->driver_priv; + + /* We need to do the ordering differently for enabling and disabling */ + if (state == 0) { + tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN); + tmp &= ~TSI148_LCSR_INTEN_IRQEN[level - 1]; + iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN); + + tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO); + tmp &= ~TSI148_LCSR_INTEO_IRQEO[level - 1]; + iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO); + + if (sync != 0) { + pdev = container_of(tsi148_bridge->parent, + struct pci_dev, dev); + + synchronize_irq(pdev->irq); + } + } else { + tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO); + tmp |= TSI148_LCSR_INTEO_IRQEO[level - 1]; + iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO); + + tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN); + tmp |= TSI148_LCSR_INTEN_IRQEN[level - 1]; + iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN); + } +} + +/* + * Generate a VME bus interrupt at the requested level & vector. Wait for + * interrupt to be acked. + */ +static int tsi148_irq_generate(struct vme_bridge *tsi148_bridge, int level, + int statid) +{ + u32 tmp; + struct tsi148_driver *bridge; + + bridge = tsi148_bridge->driver_priv; + + mutex_lock(&bridge->vme_int); + + /* Read VICR register */ + tmp = ioread32be(bridge->base + TSI148_LCSR_VICR); + + /* Set Status/ID */ + tmp = (tmp & ~TSI148_LCSR_VICR_STID_M) | + (statid & TSI148_LCSR_VICR_STID_M); + iowrite32be(tmp, bridge->base + TSI148_LCSR_VICR); + + /* Assert VMEbus IRQ */ + tmp = tmp | TSI148_LCSR_VICR_IRQL[level]; + iowrite32be(tmp, bridge->base + TSI148_LCSR_VICR); + + /* XXX Consider implementing a timeout? */ + wait_event_interruptible(bridge->iack_queue, + tsi148_iack_received(bridge)); + + mutex_unlock(&bridge->vme_int); + + return 0; +} + +/* + * Find the first error in this address range + */ +static struct vme_bus_error *tsi148_find_error(struct vme_bridge *tsi148_bridge, + u32 aspace, unsigned long long address, size_t count) +{ + struct list_head *err_pos; + struct vme_bus_error *vme_err, *valid = NULL; + unsigned long long bound; + + bound = address + count; + + /* + * XXX We are currently not looking at the address space when parsing + * for errors. This is because parsing the Address Modifier Codes + * is going to be quite resource intensive to do properly. We + * should be OK just looking at the addresses and this is certainly + * much better than what we had before. + */ + err_pos = NULL; + /* Iterate through errors */ + list_for_each(err_pos, &tsi148_bridge->vme_errors) { + vme_err = list_entry(err_pos, struct vme_bus_error, list); + if ((vme_err->address >= address) && + (vme_err->address < bound)) { + + valid = vme_err; + break; + } + } + + return valid; +} + +/* + * Clear errors in the provided address range. + */ +static void tsi148_clear_errors(struct vme_bridge *tsi148_bridge, + u32 aspace, unsigned long long address, size_t count) +{ + struct list_head *err_pos, *temp; + struct vme_bus_error *vme_err; + unsigned long long bound; + + bound = address + count; + + /* + * XXX We are currently not looking at the address space when parsing + * for errors. This is because parsing the Address Modifier Codes + * is going to be quite resource intensive to do properly. We + * should be OK just looking at the addresses and this is certainly + * much better than what we had before. + */ + err_pos = NULL; + /* Iterate through errors */ + list_for_each_safe(err_pos, temp, &tsi148_bridge->vme_errors) { + vme_err = list_entry(err_pos, struct vme_bus_error, list); + + if ((vme_err->address >= address) && + (vme_err->address < bound)) { + + list_del(err_pos); + kfree(vme_err); + } + } +} + +/* + * Initialize a slave window with the requested attributes. + */ +static int tsi148_slave_set(struct vme_slave_resource *image, int enabled, + unsigned long long vme_base, unsigned long long size, + dma_addr_t pci_base, u32 aspace, u32 cycle) +{ + unsigned int i, addr = 0, granularity = 0; + unsigned int temp_ctl = 0; + unsigned int vme_base_low, vme_base_high; + unsigned int vme_bound_low, vme_bound_high; + unsigned int pci_offset_low, pci_offset_high; + unsigned long long vme_bound, pci_offset; + struct vme_bridge *tsi148_bridge; + struct tsi148_driver *bridge; + + tsi148_bridge = image->parent; + bridge = tsi148_bridge->driver_priv; + + i = image->number; + + switch (aspace) { + case VME_A16: + granularity = 0x10; + addr |= TSI148_LCSR_ITAT_AS_A16; + break; + case VME_A24: + granularity = 0x1000; + addr |= TSI148_LCSR_ITAT_AS_A24; + break; + case VME_A32: + granularity = 0x10000; + addr |= TSI148_LCSR_ITAT_AS_A32; + break; + case VME_A64: + granularity = 0x10000; + addr |= TSI148_LCSR_ITAT_AS_A64; + break; + case VME_CRCSR: + case VME_USER1: + case VME_USER2: + case VME_USER3: + case VME_USER4: + default: + dev_err(tsi148_bridge->parent, "Invalid address space\n"); + return -EINVAL; + break; + } + + /* Convert 64-bit variables to 2x 32-bit variables */ + reg_split(vme_base, &vme_base_high, &vme_base_low); + + /* + * Bound address is a valid address for the window, adjust + * accordingly + */ + vme_bound = vme_base + size - granularity; + reg_split(vme_bound, &vme_bound_high, &vme_bound_low); + pci_offset = (unsigned long long)pci_base - vme_base; + reg_split(pci_offset, &pci_offset_high, &pci_offset_low); + + if (vme_base_low & (granularity - 1)) { + dev_err(tsi148_bridge->parent, "Invalid VME base alignment\n"); + return -EINVAL; + } + if (vme_bound_low & (granularity - 1)) { + dev_err(tsi148_bridge->parent, "Invalid VME bound alignment\n"); + return -EINVAL; + } + if (pci_offset_low & (granularity - 1)) { + dev_err(tsi148_bridge->parent, "Invalid PCI Offset " + "alignment\n"); + return -EINVAL; + } + + /* Disable while we are mucking around */ + temp_ctl = ioread32be(bridge->base + TSI148_LCSR_IT[i] + + TSI148_LCSR_OFFSET_ITAT); + temp_ctl &= ~TSI148_LCSR_ITAT_EN; + iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] + + TSI148_LCSR_OFFSET_ITAT); + + /* Setup mapping */ + iowrite32be(vme_base_high, bridge->base + TSI148_LCSR_IT[i] + + TSI148_LCSR_OFFSET_ITSAU); + iowrite32be(vme_base_low, bridge->base + TSI148_LCSR_IT[i] + + TSI148_LCSR_OFFSET_ITSAL); + iowrite32be(vme_bound_high, bridge->base + TSI148_LCSR_IT[i] + + TSI148_LCSR_OFFSET_ITEAU); + iowrite32be(vme_bound_low, bridge->base + TSI148_LCSR_IT[i] + + TSI148_LCSR_OFFSET_ITEAL); + iowrite32be(pci_offset_high, bridge->base + TSI148_LCSR_IT[i] + + TSI148_LCSR_OFFSET_ITOFU); + iowrite32be(pci_offset_low, bridge->base + TSI148_LCSR_IT[i] + + TSI148_LCSR_OFFSET_ITOFL); + + /* Setup 2eSST speeds */ + temp_ctl &= ~TSI148_LCSR_ITAT_2eSSTM_M; + switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) { + case VME_2eSST160: + temp_ctl |= TSI148_LCSR_ITAT_2eSSTM_160; + break; + case VME_2eSST267: + temp_ctl |= TSI148_LCSR_ITAT_2eSSTM_267; + break; + case VME_2eSST320: + temp_ctl |= TSI148_LCSR_ITAT_2eSSTM_320; + break; + } + + /* Setup cycle types */ + temp_ctl &= ~(0x1F << 7); + if (cycle & VME_BLT) + temp_ctl |= TSI148_LCSR_ITAT_BLT; + if (cycle & VME_MBLT) + temp_ctl |= TSI148_LCSR_ITAT_MBLT; + if (cycle & VME_2eVME) + temp_ctl |= TSI148_LCSR_ITAT_2eVME; + if (cycle & VME_2eSST) + temp_ctl |= TSI148_LCSR_ITAT_2eSST; + if (cycle & VME_2eSSTB) + temp_ctl |= TSI148_LCSR_ITAT_2eSSTB; + + /* Setup address space */ + temp_ctl &= ~TSI148_LCSR_ITAT_AS_M; + temp_ctl |= addr; + + temp_ctl &= ~0xF; + if (cycle & VME_SUPER) + temp_ctl |= TSI148_LCSR_ITAT_SUPR ; + if (cycle & VME_USER) + temp_ctl |= TSI148_LCSR_ITAT_NPRIV; + if (cycle & VME_PROG) + temp_ctl |= TSI148_LCSR_ITAT_PGM; + if (cycle & VME_DATA) + temp_ctl |= TSI148_LCSR_ITAT_DATA; + + /* Write ctl reg without enable */ + iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] + + TSI148_LCSR_OFFSET_ITAT); + + if (enabled) + temp_ctl |= TSI148_LCSR_ITAT_EN; + + iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] + + TSI148_LCSR_OFFSET_ITAT); + + return 0; +} + +/* + * Get slave window configuration. + */ +static int tsi148_slave_get(struct vme_slave_resource *image, int *enabled, + unsigned long long *vme_base, unsigned long long *size, + dma_addr_t *pci_base, u32 *aspace, u32 *cycle) +{ + unsigned int i, granularity = 0, ctl = 0; + unsigned int vme_base_low, vme_base_high; + unsigned int vme_bound_low, vme_bound_high; + unsigned int pci_offset_low, pci_offset_high; + unsigned long long vme_bound, pci_offset; + struct tsi148_driver *bridge; + + bridge = image->parent->driver_priv; + + i = image->number; + + /* Read registers */ + ctl = ioread32be(bridge->base + TSI148_LCSR_IT[i] + + TSI148_LCSR_OFFSET_ITAT); + + vme_base_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] + + TSI148_LCSR_OFFSET_ITSAU); + vme_base_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] + + TSI148_LCSR_OFFSET_ITSAL); + vme_bound_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] + + TSI148_LCSR_OFFSET_ITEAU); + vme_bound_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] + + TSI148_LCSR_OFFSET_ITEAL); + pci_offset_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] + + TSI148_LCSR_OFFSET_ITOFU); + pci_offset_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] + + TSI148_LCSR_OFFSET_ITOFL); + + /* Convert 64-bit variables to 2x 32-bit variables */ + reg_join(vme_base_high, vme_base_low, vme_base); + reg_join(vme_bound_high, vme_bound_low, &vme_bound); + reg_join(pci_offset_high, pci_offset_low, &pci_offset); + + *pci_base = (dma_addr_t)vme_base + pci_offset; + + *enabled = 0; + *aspace = 0; + *cycle = 0; + + if (ctl & TSI148_LCSR_ITAT_EN) + *enabled = 1; + + if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A16) { + granularity = 0x10; + *aspace |= VME_A16; + } + if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A24) { + granularity = 0x1000; + *aspace |= VME_A24; + } + if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A32) { + granularity = 0x10000; + *aspace |= VME_A32; + } + if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A64) { + granularity = 0x10000; + *aspace |= VME_A64; + } + + /* Need granularity before we set the size */ + *size = (unsigned long long)((vme_bound - *vme_base) + granularity); + + + if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_160) + *cycle |= VME_2eSST160; + if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_267) + *cycle |= VME_2eSST267; + if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_320) + *cycle |= VME_2eSST320; + + if (ctl & TSI148_LCSR_ITAT_BLT) + *cycle |= VME_BLT; + if (ctl & TSI148_LCSR_ITAT_MBLT) + *cycle |= VME_MBLT; + if (ctl & TSI148_LCSR_ITAT_2eVME) + *cycle |= VME_2eVME; + if (ctl & TSI148_LCSR_ITAT_2eSST) + *cycle |= VME_2eSST; + if (ctl & TSI148_LCSR_ITAT_2eSSTB) + *cycle |= VME_2eSSTB; + + if (ctl & TSI148_LCSR_ITAT_SUPR) + *cycle |= VME_SUPER; + if (ctl & TSI148_LCSR_ITAT_NPRIV) + *cycle |= VME_USER; + if (ctl & TSI148_LCSR_ITAT_PGM) + *cycle |= VME_PROG; + if (ctl & TSI148_LCSR_ITAT_DATA) + *cycle |= VME_DATA; + + return 0; +} + +/* + * Allocate and map PCI Resource + */ +static int tsi148_alloc_resource(struct vme_master_resource *image, + unsigned long long size) +{ + unsigned long long existing_size; + int retval = 0; + struct pci_dev *pdev; + struct vme_bridge *tsi148_bridge; + + tsi148_bridge = image->parent; + + pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev); + + existing_size = (unsigned long long)(image->bus_resource.end - + image->bus_resource.start); + + /* If the existing size is OK, return */ + if ((size != 0) && (existing_size == (size - 1))) + return 0; + + if (existing_size != 0) { + iounmap(image->kern_base); + image->kern_base = NULL; + kfree(image->bus_resource.name); + release_resource(&image->bus_resource); + memset(&image->bus_resource, 0, sizeof(struct resource)); + } + + /* Exit here if size is zero */ + if (size == 0) + return 0; + + if (image->bus_resource.name == NULL) { + image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_ATOMIC); + if (image->bus_resource.name == NULL) { + dev_err(tsi148_bridge->parent, "Unable to allocate " + "memory for resource name\n"); + retval = -ENOMEM; + goto err_name; + } + } + + sprintf((char *)image->bus_resource.name, "%s.%d", tsi148_bridge->name, + image->number); + + image->bus_resource.start = 0; + image->bus_resource.end = (unsigned long)size; + image->bus_resource.flags = IORESOURCE_MEM; + + retval = pci_bus_alloc_resource(pdev->bus, + &image->bus_resource, size, size, PCIBIOS_MIN_MEM, + 0, NULL, NULL); + if (retval) { + dev_err(tsi148_bridge->parent, "Failed to allocate mem " + "resource for window %d size 0x%lx start 0x%lx\n", + image->number, (unsigned long)size, + (unsigned long)image->bus_resource.start); + goto err_resource; + } + + image->kern_base = ioremap_nocache( + image->bus_resource.start, size); + if (image->kern_base == NULL) { + dev_err(tsi148_bridge->parent, "Failed to remap resource\n"); + retval = -ENOMEM; + goto err_remap; + } + + return 0; + +err_remap: + release_resource(&image->bus_resource); +err_resource: + kfree(image->bus_resource.name); + memset(&image->bus_resource, 0, sizeof(struct resource)); +err_name: + return retval; +} + +/* + * Free and unmap PCI Resource + */ +static void tsi148_free_resource(struct vme_master_resource *image) +{ + iounmap(image->kern_base); + image->kern_base = NULL; + release_resource(&image->bus_resource); + kfree(image->bus_resource.name); + memset(&image->bus_resource, 0, sizeof(struct resource)); +} + +/* + * Set the attributes of an outbound window. + */ +static int tsi148_master_set(struct vme_master_resource *image, int enabled, + unsigned long long vme_base, unsigned long long size, u32 aspace, + u32 cycle, u32 dwidth) +{ + int retval = 0; + unsigned int i; + unsigned int temp_ctl = 0; + unsigned int pci_base_low, pci_base_high; + unsigned int pci_bound_low, pci_bound_high; + unsigned int vme_offset_low, vme_offset_high; + unsigned long long pci_bound, vme_offset, pci_base; + struct vme_bridge *tsi148_bridge; + struct tsi148_driver *bridge; + + tsi148_bridge = image->parent; + + bridge = tsi148_bridge->driver_priv; + + /* Verify input data */ + if (vme_base & 0xFFFF) { + dev_err(tsi148_bridge->parent, "Invalid VME Window " + "alignment\n"); + retval = -EINVAL; + goto err_window; + } + + if ((size == 0) && (enabled != 0)) { + dev_err(tsi148_bridge->parent, "Size must be non-zero for " + "enabled windows\n"); + retval = -EINVAL; + goto err_window; + } + + spin_lock(&image->lock); + + /* Let's allocate the resource here rather than further up the stack as + * it avoids pushing loads of bus dependent stuff up the stack. If size + * is zero, any existing resource will be freed. + */ + retval = tsi148_alloc_resource(image, size); + if (retval) { + spin_unlock(&image->lock); + dev_err(tsi148_bridge->parent, "Unable to allocate memory for " + "resource\n"); + goto err_res; + } + + if (size == 0) { + pci_base = 0; + pci_bound = 0; + vme_offset = 0; + } else { + pci_base = (unsigned long long)image->bus_resource.start; + + /* + * Bound address is a valid address for the window, adjust + * according to window granularity. + */ + pci_bound = pci_base + (size - 0x10000); + vme_offset = vme_base - pci_base; + } + + /* Convert 64-bit variables to 2x 32-bit variables */ + reg_split(pci_base, &pci_base_high, &pci_base_low); + reg_split(pci_bound, &pci_bound_high, &pci_bound_low); + reg_split(vme_offset, &vme_offset_high, &vme_offset_low); + + if (pci_base_low & 0xFFFF) { + spin_unlock(&image->lock); + dev_err(tsi148_bridge->parent, "Invalid PCI base alignment\n"); + retval = -EINVAL; + goto err_gran; + } + if (pci_bound_low & 0xFFFF) { + spin_unlock(&image->lock); + dev_err(tsi148_bridge->parent, "Invalid PCI bound alignment\n"); + retval = -EINVAL; + goto err_gran; + } + if (vme_offset_low & 0xFFFF) { + spin_unlock(&image->lock); + dev_err(tsi148_bridge->parent, "Invalid VME Offset " + "alignment\n"); + retval = -EINVAL; + goto err_gran; + } + + i = image->number; + + /* Disable while we are mucking around */ + temp_ctl = ioread32be(bridge->base + TSI148_LCSR_OT[i] + + TSI148_LCSR_OFFSET_OTAT); + temp_ctl &= ~TSI148_LCSR_OTAT_EN; + iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] + + TSI148_LCSR_OFFSET_OTAT); + + /* Setup 2eSST speeds */ + temp_ctl &= ~TSI148_LCSR_OTAT_2eSSTM_M; + switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) { + case VME_2eSST160: + temp_ctl |= TSI148_LCSR_OTAT_2eSSTM_160; + break; + case VME_2eSST267: + temp_ctl |= TSI148_LCSR_OTAT_2eSSTM_267; + break; + case VME_2eSST320: + temp_ctl |= TSI148_LCSR_OTAT_2eSSTM_320; + break; + } + + /* Setup cycle types */ + if (cycle & VME_BLT) { + temp_ctl &= ~TSI148_LCSR_OTAT_TM_M; + temp_ctl |= TSI148_LCSR_OTAT_TM_BLT; + } + if (cycle & VME_MBLT) { + temp_ctl &= ~TSI148_LCSR_OTAT_TM_M; + temp_ctl |= TSI148_LCSR_OTAT_TM_MBLT; + } + if (cycle & VME_2eVME) { + temp_ctl &= ~TSI148_LCSR_OTAT_TM_M; + temp_ctl |= TSI148_LCSR_OTAT_TM_2eVME; + } + if (cycle & VME_2eSST) { + temp_ctl &= ~TSI148_LCSR_OTAT_TM_M; + temp_ctl |= TSI148_LCSR_OTAT_TM_2eSST; + } + if (cycle & VME_2eSSTB) { + dev_warn(tsi148_bridge->parent, "Currently not setting " + "Broadcast Select Registers\n"); + temp_ctl &= ~TSI148_LCSR_OTAT_TM_M; + temp_ctl |= TSI148_LCSR_OTAT_TM_2eSSTB; + } + + /* Setup data width */ + temp_ctl &= ~TSI148_LCSR_OTAT_DBW_M; + switch (dwidth) { + case VME_D16: + temp_ctl |= TSI148_LCSR_OTAT_DBW_16; + break; + case VME_D32: + temp_ctl |= TSI148_LCSR_OTAT_DBW_32; + break; + default: + spin_unlock(&image->lock); + dev_err(tsi148_bridge->parent, "Invalid data width\n"); + retval = -EINVAL; + goto err_dwidth; + } + + /* Setup address space */ + temp_ctl &= ~TSI148_LCSR_OTAT_AMODE_M; + switch (aspace) { + case VME_A16: + temp_ctl |= TSI148_LCSR_OTAT_AMODE_A16; + break; + case VME_A24: + temp_ctl |= TSI148_LCSR_OTAT_AMODE_A24; + break; + case VME_A32: + temp_ctl |= TSI148_LCSR_OTAT_AMODE_A32; + break; + case VME_A64: + temp_ctl |= TSI148_LCSR_OTAT_AMODE_A64; + break; + case VME_CRCSR: + temp_ctl |= TSI148_LCSR_OTAT_AMODE_CRCSR; + break; + case VME_USER1: + temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER1; + break; + case VME_USER2: + temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER2; + break; + case VME_USER3: + temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER3; + break; + case VME_USER4: + temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER4; + break; + default: + spin_unlock(&image->lock); + dev_err(tsi148_bridge->parent, "Invalid address space\n"); + retval = -EINVAL; + goto err_aspace; + break; + } + + temp_ctl &= ~(3<<4); + if (cycle & VME_SUPER) + temp_ctl |= TSI148_LCSR_OTAT_SUP; + if (cycle & VME_PROG) + temp_ctl |= TSI148_LCSR_OTAT_PGM; + + /* Setup mapping */ + iowrite32be(pci_base_high, bridge->base + TSI148_LCSR_OT[i] + + TSI148_LCSR_OFFSET_OTSAU); + iowrite32be(pci_base_low, bridge->base + TSI148_LCSR_OT[i] + + TSI148_LCSR_OFFSET_OTSAL); + iowrite32be(pci_bound_high, bridge->base + TSI148_LCSR_OT[i] + + TSI148_LCSR_OFFSET_OTEAU); + iowrite32be(pci_bound_low, bridge->base + TSI148_LCSR_OT[i] + + TSI148_LCSR_OFFSET_OTEAL); + iowrite32be(vme_offset_high, bridge->base + TSI148_LCSR_OT[i] + + TSI148_LCSR_OFFSET_OTOFU); + iowrite32be(vme_offset_low, bridge->base + TSI148_LCSR_OT[i] + + TSI148_LCSR_OFFSET_OTOFL); + + /* Write ctl reg without enable */ + iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] + + TSI148_LCSR_OFFSET_OTAT); + + if (enabled) + temp_ctl |= TSI148_LCSR_OTAT_EN; + + iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] + + TSI148_LCSR_OFFSET_OTAT); + + spin_unlock(&image->lock); + return 0; + +err_aspace: +err_dwidth: +err_gran: + tsi148_free_resource(image); +err_res: +err_window: + return retval; + +} + +/* + * Set the attributes of an outbound window. + * + * XXX Not parsing prefetch information. + */ +static int __tsi148_master_get(struct vme_master_resource *image, int *enabled, + unsigned long long *vme_base, unsigned long long *size, u32 *aspace, + u32 *cycle, u32 *dwidth) +{ + unsigned int i, ctl; + unsigned int pci_base_low, pci_base_high; + unsigned int pci_bound_low, pci_bound_high; + unsigned int vme_offset_low, vme_offset_high; + + unsigned long long pci_base, pci_bound, vme_offset; + struct tsi148_driver *bridge; + + bridge = image->parent->driver_priv; + + i = image->number; + + ctl = ioread32be(bridge->base + TSI148_LCSR_OT[i] + + TSI148_LCSR_OFFSET_OTAT); + + pci_base_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] + + TSI148_LCSR_OFFSET_OTSAU); + pci_base_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] + + TSI148_LCSR_OFFSET_OTSAL); + pci_bound_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] + + TSI148_LCSR_OFFSET_OTEAU); + pci_bound_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] + + TSI148_LCSR_OFFSET_OTEAL); + vme_offset_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] + + TSI148_LCSR_OFFSET_OTOFU); + vme_offset_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] + + TSI148_LCSR_OFFSET_OTOFL); + + /* Convert 64-bit variables to 2x 32-bit variables */ + reg_join(pci_base_high, pci_base_low, &pci_base); + reg_join(pci_bound_high, pci_bound_low, &pci_bound); + reg_join(vme_offset_high, vme_offset_low, &vme_offset); + + *vme_base = pci_base + vme_offset; + *size = (unsigned long long)(pci_bound - pci_base) + 0x10000; + + *enabled = 0; + *aspace = 0; + *cycle = 0; + *dwidth = 0; + + if (ctl & TSI148_LCSR_OTAT_EN) + *enabled = 1; + + /* Setup address space */ + if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A16) + *aspace |= VME_A16; + if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A24) + *aspace |= VME_A24; + if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A32) + *aspace |= VME_A32; + if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A64) + *aspace |= VME_A64; + if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_CRCSR) + *aspace |= VME_CRCSR; + if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER1) + *aspace |= VME_USER1; + if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER2) + *aspace |= VME_USER2; + if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER3) + *aspace |= VME_USER3; + if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER4) + *aspace |= VME_USER4; + + /* Setup 2eSST speeds */ + if ((ctl & TSI148_LCSR_OTAT_2eSSTM_M) == TSI148_LCSR_OTAT_2eSSTM_160) + *cycle |= VME_2eSST160; + if ((ctl & TSI148_LCSR_OTAT_2eSSTM_M) == TSI148_LCSR_OTAT_2eSSTM_267) + *cycle |= VME_2eSST267; + if ((ctl & TSI148_LCSR_OTAT_2eSSTM_M) == TSI148_LCSR_OTAT_2eSSTM_320) + *cycle |= VME_2eSST320; + + /* Setup cycle types */ + if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_SCT) + *cycle |= VME_SCT; + if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_BLT) + *cycle |= VME_BLT; + if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_MBLT) + *cycle |= VME_MBLT; + if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_2eVME) + *cycle |= VME_2eVME; + if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_2eSST) + *cycle |= VME_2eSST; + if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_2eSSTB) + *cycle |= VME_2eSSTB; + + if (ctl & TSI148_LCSR_OTAT_SUP) + *cycle |= VME_SUPER; + else + *cycle |= VME_USER; + + if (ctl & TSI148_LCSR_OTAT_PGM) + *cycle |= VME_PROG; + else + *cycle |= VME_DATA; + + /* Setup data width */ + if ((ctl & TSI148_LCSR_OTAT_DBW_M) == TSI148_LCSR_OTAT_DBW_16) + *dwidth = VME_D16; + if ((ctl & TSI148_LCSR_OTAT_DBW_M) == TSI148_LCSR_OTAT_DBW_32) + *dwidth = VME_D32; + + return 0; +} + + +static int tsi148_master_get(struct vme_master_resource *image, int *enabled, + unsigned long long *vme_base, unsigned long long *size, u32 *aspace, + u32 *cycle, u32 *dwidth) +{ + int retval; + + spin_lock(&image->lock); + + retval = __tsi148_master_get(image, enabled, vme_base, size, aspace, + cycle, dwidth); + + spin_unlock(&image->lock); + + return retval; +} + +static ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf, + size_t count, loff_t offset) +{ + int retval, enabled; + unsigned long long vme_base, size; + u32 aspace, cycle, dwidth; + struct vme_bus_error *vme_err = NULL; + struct vme_bridge *tsi148_bridge; + + tsi148_bridge = image->parent; + + spin_lock(&image->lock); + + memcpy_fromio(buf, image->kern_base + offset, (unsigned int)count); + retval = count; + + if (!err_chk) + goto skip_chk; + + __tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle, + &dwidth); + + vme_err = tsi148_find_error(tsi148_bridge, aspace, vme_base + offset, + count); + if (vme_err != NULL) { + dev_err(image->parent->parent, "First VME read error detected " + "an at address 0x%llx\n", vme_err->address); + retval = vme_err->address - (vme_base + offset); + /* Clear down save errors in this address range */ + tsi148_clear_errors(tsi148_bridge, aspace, vme_base + offset, + count); + } + +skip_chk: + spin_unlock(&image->lock); + + return retval; +} + + +static ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf, + size_t count, loff_t offset) +{ + int retval = 0, enabled; + unsigned long long vme_base, size; + u32 aspace, cycle, dwidth; + + struct vme_bus_error *vme_err = NULL; + struct vme_bridge *tsi148_bridge; + struct tsi148_driver *bridge; + + tsi148_bridge = image->parent; + + bridge = tsi148_bridge->driver_priv; + + spin_lock(&image->lock); + + memcpy_toio(image->kern_base + offset, buf, (unsigned int)count); + retval = count; + + /* + * Writes are posted. We need to do a read on the VME bus to flush out + * all of the writes before we check for errors. We can't guarantee + * that reading the data we have just written is safe. It is believed + * that there isn't any read, write re-ordering, so we can read any + * location in VME space, so lets read the Device ID from the tsi148's + * own registers as mapped into CR/CSR space. + * + * We check for saved errors in the written address range/space. + */ + + if (!err_chk) + goto skip_chk; + + /* + * Get window info first, to maximise the time that the buffers may + * fluch on their own + */ + __tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle, + &dwidth); + + ioread16(bridge->flush_image->kern_base + 0x7F000); + + vme_err = tsi148_find_error(tsi148_bridge, aspace, vme_base + offset, + count); + if (vme_err != NULL) { + dev_warn(tsi148_bridge->parent, "First VME write error detected" + " an at address 0x%llx\n", vme_err->address); + retval = vme_err->address - (vme_base + offset); + /* Clear down save errors in this address range */ + tsi148_clear_errors(tsi148_bridge, aspace, vme_base + offset, + count); + } + +skip_chk: + spin_unlock(&image->lock); + + return retval; +} + +/* + * Perform an RMW cycle on the VME bus. + * + * Requires a previously configured master window, returns final value. + */ +static unsigned int tsi148_master_rmw(struct vme_master_resource *image, + unsigned int mask, unsigned int compare, unsigned int swap, + loff_t offset) +{ + unsigned long long pci_addr; + unsigned int pci_addr_high, pci_addr_low; + u32 tmp, result; + int i; + struct tsi148_driver *bridge; + + bridge = image->parent->driver_priv; + + /* Find the PCI address that maps to the desired VME address */ + i = image->number; + + /* Locking as we can only do one of these at a time */ + mutex_lock(&bridge->vme_rmw); + + /* Lock image */ + spin_lock(&image->lock); + + pci_addr_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] + + TSI148_LCSR_OFFSET_OTSAU); + pci_addr_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] + + TSI148_LCSR_OFFSET_OTSAL); + + reg_join(pci_addr_high, pci_addr_low, &pci_addr); + reg_split(pci_addr + offset, &pci_addr_high, &pci_addr_low); + + /* Configure registers */ + iowrite32be(mask, bridge->base + TSI148_LCSR_RMWEN); + iowrite32be(compare, bridge->base + TSI148_LCSR_RMWC); + iowrite32be(swap, bridge->base + TSI148_LCSR_RMWS); + iowrite32be(pci_addr_high, bridge->base + TSI148_LCSR_RMWAU); + iowrite32be(pci_addr_low, bridge->base + TSI148_LCSR_RMWAL); + + /* Enable RMW */ + tmp = ioread32be(bridge->base + TSI148_LCSR_VMCTRL); + tmp |= TSI148_LCSR_VMCTRL_RMWEN; + iowrite32be(tmp, bridge->base + TSI148_LCSR_VMCTRL); + + /* Kick process off with a read to the required address. */ + result = ioread32be(image->kern_base + offset); + + /* Disable RMW */ + tmp = ioread32be(bridge->base + TSI148_LCSR_VMCTRL); + tmp &= ~TSI148_LCSR_VMCTRL_RMWEN; + iowrite32be(tmp, bridge->base + TSI148_LCSR_VMCTRL); + + spin_unlock(&image->lock); + + mutex_unlock(&bridge->vme_rmw); + + return result; +} + +static int tsi148_dma_set_vme_src_attributes(struct device *dev, __be32 *attr, + u32 aspace, u32 cycle, u32 dwidth) +{ + u32 val; + + val = be32_to_cpu(*attr); + + /* Setup 2eSST speeds */ + switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) { + case VME_2eSST160: + val |= TSI148_LCSR_DSAT_2eSSTM_160; + break; + case VME_2eSST267: + val |= TSI148_LCSR_DSAT_2eSSTM_267; + break; + case VME_2eSST320: + val |= TSI148_LCSR_DSAT_2eSSTM_320; + break; + } + + /* Setup cycle types */ + if (cycle & VME_SCT) + val |= TSI148_LCSR_DSAT_TM_SCT; + + if (cycle & VME_BLT) + val |= TSI148_LCSR_DSAT_TM_BLT; + + if (cycle & VME_MBLT) + val |= TSI148_LCSR_DSAT_TM_MBLT; + + if (cycle & VME_2eVME) + val |= TSI148_LCSR_DSAT_TM_2eVME; + + if (cycle & VME_2eSST) + val |= TSI148_LCSR_DSAT_TM_2eSST; + + if (cycle & VME_2eSSTB) { + dev_err(dev, "Currently not setting Broadcast Select " + "Registers\n"); + val |= TSI148_LCSR_DSAT_TM_2eSSTB; + } + + /* Setup data width */ + switch (dwidth) { + case VME_D16: + val |= TSI148_LCSR_DSAT_DBW_16; + break; + case VME_D32: + val |= TSI148_LCSR_DSAT_DBW_32; + break; + default: + dev_err(dev, "Invalid data width\n"); + return -EINVAL; + } + + /* Setup address space */ + switch (aspace) { + case VME_A16: + val |= TSI148_LCSR_DSAT_AMODE_A16; + break; + case VME_A24: + val |= TSI148_LCSR_DSAT_AMODE_A24; + break; + case VME_A32: + val |= TSI148_LCSR_DSAT_AMODE_A32; + break; + case VME_A64: + val |= TSI148_LCSR_DSAT_AMODE_A64; + break; + case VME_CRCSR: + val |= TSI148_LCSR_DSAT_AMODE_CRCSR; + break; + case VME_USER1: + val |= TSI148_LCSR_DSAT_AMODE_USER1; + break; + case VME_USER2: + val |= TSI148_LCSR_DSAT_AMODE_USER2; + break; + case VME_USER3: + val |= TSI148_LCSR_DSAT_AMODE_USER3; + break; + case VME_USER4: + val |= TSI148_LCSR_DSAT_AMODE_USER4; + break; + default: + dev_err(dev, "Invalid address space\n"); + return -EINVAL; + break; + } + + if (cycle & VME_SUPER) + val |= TSI148_LCSR_DSAT_SUP; + if (cycle & VME_PROG) + val |= TSI148_LCSR_DSAT_PGM; + + *attr = cpu_to_be32(val); + + return 0; +} + +static int tsi148_dma_set_vme_dest_attributes(struct device *dev, __be32 *attr, + u32 aspace, u32 cycle, u32 dwidth) +{ + u32 val; + + val = be32_to_cpu(*attr); + + /* Setup 2eSST speeds */ + switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) { + case VME_2eSST160: + val |= TSI148_LCSR_DDAT_2eSSTM_160; + break; + case VME_2eSST267: + val |= TSI148_LCSR_DDAT_2eSSTM_267; + break; + case VME_2eSST320: + val |= TSI148_LCSR_DDAT_2eSSTM_320; + break; + } + + /* Setup cycle types */ + if (cycle & VME_SCT) + val |= TSI148_LCSR_DDAT_TM_SCT; + + if (cycle & VME_BLT) + val |= TSI148_LCSR_DDAT_TM_BLT; + + if (cycle & VME_MBLT) + val |= TSI148_LCSR_DDAT_TM_MBLT; + + if (cycle & VME_2eVME) + val |= TSI148_LCSR_DDAT_TM_2eVME; + + if (cycle & VME_2eSST) + val |= TSI148_LCSR_DDAT_TM_2eSST; + + if (cycle & VME_2eSSTB) { + dev_err(dev, "Currently not setting Broadcast Select " + "Registers\n"); + val |= TSI148_LCSR_DDAT_TM_2eSSTB; + } + + /* Setup data width */ + switch (dwidth) { + case VME_D16: + val |= TSI148_LCSR_DDAT_DBW_16; + break; + case VME_D32: + val |= TSI148_LCSR_DDAT_DBW_32; + break; + default: + dev_err(dev, "Invalid data width\n"); + return -EINVAL; + } + + /* Setup address space */ + switch (aspace) { + case VME_A16: + val |= TSI148_LCSR_DDAT_AMODE_A16; + break; + case VME_A24: + val |= TSI148_LCSR_DDAT_AMODE_A24; + break; + case VME_A32: + val |= TSI148_LCSR_DDAT_AMODE_A32; + break; + case VME_A64: + val |= TSI148_LCSR_DDAT_AMODE_A64; + break; + case VME_CRCSR: + val |= TSI148_LCSR_DDAT_AMODE_CRCSR; + break; + case VME_USER1: + val |= TSI148_LCSR_DDAT_AMODE_USER1; + break; + case VME_USER2: + val |= TSI148_LCSR_DDAT_AMODE_USER2; + break; + case VME_USER3: + val |= TSI148_LCSR_DDAT_AMODE_USER3; + break; + case VME_USER4: + val |= TSI148_LCSR_DDAT_AMODE_USER4; + break; + default: + dev_err(dev, "Invalid address space\n"); + return -EINVAL; + break; + } + + if (cycle & VME_SUPER) + val |= TSI148_LCSR_DDAT_SUP; + if (cycle & VME_PROG) + val |= TSI148_LCSR_DDAT_PGM; + + *attr = cpu_to_be32(val); + + return 0; +} + +/* + * Add a link list descriptor to the list + * + * Note: DMA engine expects the DMA descriptor to be big endian. + */ +static int tsi148_dma_list_add(struct vme_dma_list *list, + struct vme_dma_attr *src, struct vme_dma_attr *dest, size_t count) +{ + struct tsi148_dma_entry *entry, *prev; + u32 address_high, address_low, val; + struct vme_dma_pattern *pattern_attr; + struct vme_dma_pci *pci_attr; + struct vme_dma_vme *vme_attr; + int retval = 0; + struct vme_bridge *tsi148_bridge; + + tsi148_bridge = list->parent->parent; + + /* Descriptor must be aligned on 64-bit boundaries */ + entry = kmalloc(sizeof(struct tsi148_dma_entry), GFP_KERNEL); + if (entry == NULL) { + dev_err(tsi148_bridge->parent, "Failed to allocate memory for " + "dma resource structure\n"); + retval = -ENOMEM; + goto err_mem; + } + + /* Test descriptor alignment */ + if ((unsigned long)&entry->descriptor & 0x7) { + dev_err(tsi148_bridge->parent, "Descriptor not aligned to 8 " + "byte boundary as required: %p\n", + &entry->descriptor); + retval = -EINVAL; + goto err_align; + } + + /* Given we are going to fill out the structure, we probably don't + * need to zero it, but better safe than sorry for now. + */ + memset(&entry->descriptor, 0, sizeof(struct tsi148_dma_descriptor)); + + /* Fill out source part */ + switch (src->type) { + case VME_DMA_PATTERN: + pattern_attr = src->private; + + entry->descriptor.dsal = cpu_to_be32(pattern_attr->pattern); + + val = TSI148_LCSR_DSAT_TYP_PAT; + + /* Default behaviour is 32 bit pattern */ + if (pattern_attr->type & VME_DMA_PATTERN_BYTE) + val |= TSI148_LCSR_DSAT_PSZ; + + /* It seems that the default behaviour is to increment */ + if ((pattern_attr->type & VME_DMA_PATTERN_INCREMENT) == 0) + val |= TSI148_LCSR_DSAT_NIN; + entry->descriptor.dsat = cpu_to_be32(val); + break; + case VME_DMA_PCI: + pci_attr = src->private; + + reg_split((unsigned long long)pci_attr->address, &address_high, + &address_low); + entry->descriptor.dsau = cpu_to_be32(address_high); + entry->descriptor.dsal = cpu_to_be32(address_low); + entry->descriptor.dsat = cpu_to_be32(TSI148_LCSR_DSAT_TYP_PCI); + break; + case VME_DMA_VME: + vme_attr = src->private; + + reg_split((unsigned long long)vme_attr->address, &address_high, + &address_low); + entry->descriptor.dsau = cpu_to_be32(address_high); + entry->descriptor.dsal = cpu_to_be32(address_low); + entry->descriptor.dsat = cpu_to_be32(TSI148_LCSR_DSAT_TYP_VME); + + retval = tsi148_dma_set_vme_src_attributes( + tsi148_bridge->parent, &entry->descriptor.dsat, + vme_attr->aspace, vme_attr->cycle, vme_attr->dwidth); + if (retval < 0) + goto err_source; + break; + default: + dev_err(tsi148_bridge->parent, "Invalid source type\n"); + retval = -EINVAL; + goto err_source; + break; + } + + /* Assume last link - this will be over-written by adding another */ + entry->descriptor.dnlau = cpu_to_be32(0); + entry->descriptor.dnlal = cpu_to_be32(TSI148_LCSR_DNLAL_LLA); + + /* Fill out destination part */ + switch (dest->type) { + case VME_DMA_PCI: + pci_attr = dest->private; + + reg_split((unsigned long long)pci_attr->address, &address_high, + &address_low); + entry->descriptor.ddau = cpu_to_be32(address_high); + entry->descriptor.ddal = cpu_to_be32(address_low); + entry->descriptor.ddat = cpu_to_be32(TSI148_LCSR_DDAT_TYP_PCI); + break; + case VME_DMA_VME: + vme_attr = dest->private; + + reg_split((unsigned long long)vme_attr->address, &address_high, + &address_low); + entry->descriptor.ddau = cpu_to_be32(address_high); + entry->descriptor.ddal = cpu_to_be32(address_low); + entry->descriptor.ddat = cpu_to_be32(TSI148_LCSR_DDAT_TYP_VME); + + retval = tsi148_dma_set_vme_dest_attributes( + tsi148_bridge->parent, &entry->descriptor.ddat, + vme_attr->aspace, vme_attr->cycle, vme_attr->dwidth); + if (retval < 0) + goto err_dest; + break; + default: + dev_err(tsi148_bridge->parent, "Invalid destination type\n"); + retval = -EINVAL; + goto err_dest; + break; + } + + /* Fill out count */ + entry->descriptor.dcnt = cpu_to_be32((u32)count); + + /* Add to list */ + list_add_tail(&entry->list, &list->entries); + + /* Fill out previous descriptors "Next Address" */ + if (entry->list.prev != &list->entries) { + prev = list_entry(entry->list.prev, struct tsi148_dma_entry, + list); + /* We need the bus address for the pointer */ + entry->dma_handle = dma_map_single(tsi148_bridge->parent, + &entry->descriptor, + sizeof(struct tsi148_dma_descriptor), DMA_TO_DEVICE); + + reg_split((unsigned long long)entry->dma_handle, &address_high, + &address_low); + entry->descriptor.dnlau = cpu_to_be32(address_high); + entry->descriptor.dnlal = cpu_to_be32(address_low); + + } + + return 0; + +err_dest: +err_source: +err_align: + kfree(entry); +err_mem: + return retval; +} + +/* + * Check to see if the provided DMA channel is busy. + */ +static int tsi148_dma_busy(struct vme_bridge *tsi148_bridge, int channel) +{ + u32 tmp; + struct tsi148_driver *bridge; + + bridge = tsi148_bridge->driver_priv; + + tmp = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] + + TSI148_LCSR_OFFSET_DSTA); + + if (tmp & TSI148_LCSR_DSTA_BSY) + return 0; + else + return 1; + +} + +/* + * Execute a previously generated link list + * + * XXX Need to provide control register configuration. + */ +static int tsi148_dma_list_exec(struct vme_dma_list *list) +{ + struct vme_dma_resource *ctrlr; + int channel, retval = 0; + struct tsi148_dma_entry *entry; + u32 bus_addr_high, bus_addr_low; + u32 val, dctlreg = 0; + struct vme_bridge *tsi148_bridge; + struct tsi148_driver *bridge; + + ctrlr = list->parent; + + tsi148_bridge = ctrlr->parent; + + bridge = tsi148_bridge->driver_priv; + + mutex_lock(&ctrlr->mtx); + + channel = ctrlr->number; + + if (!list_empty(&ctrlr->running)) { + /* + * XXX We have an active DMA transfer and currently haven't + * sorted out the mechanism for "pending" DMA transfers. + * Return busy. + */ + /* Need to add to pending here */ + mutex_unlock(&ctrlr->mtx); + return -EBUSY; + } else { + list_add(&list->list, &ctrlr->running); + } + + /* Get first bus address and write into registers */ + entry = list_first_entry(&list->entries, struct tsi148_dma_entry, + list); + + entry->dma_handle = dma_map_single(tsi148_bridge->parent, + &entry->descriptor, + sizeof(struct tsi148_dma_descriptor), DMA_TO_DEVICE); + + mutex_unlock(&ctrlr->mtx); + + reg_split(entry->dma_handle, &bus_addr_high, &bus_addr_low); + + iowrite32be(bus_addr_high, bridge->base + + TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAU); + iowrite32be(bus_addr_low, bridge->base + + TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAL); + + dctlreg = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] + + TSI148_LCSR_OFFSET_DCTL); + + /* Start the operation */ + iowrite32be(dctlreg | TSI148_LCSR_DCTL_DGO, bridge->base + + TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL); + + wait_event_interruptible(bridge->dma_queue[channel], + tsi148_dma_busy(ctrlr->parent, channel)); + + /* + * Read status register, this register is valid until we kick off a + * new transfer. + */ + val = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] + + TSI148_LCSR_OFFSET_DSTA); + + if (val & TSI148_LCSR_DSTA_VBE) { + dev_err(tsi148_bridge->parent, "DMA Error. DSTA=%08X\n", val); + retval = -EIO; + } + + /* Remove list from running list */ + mutex_lock(&ctrlr->mtx); + list_del(&list->list); + mutex_unlock(&ctrlr->mtx); + + return retval; +} + +/* + * Clean up a previously generated link list + * + * We have a separate function, don't assume that the chain can't be reused. + */ +static int tsi148_dma_list_empty(struct vme_dma_list *list) +{ + struct list_head *pos, *temp; + struct tsi148_dma_entry *entry; + + struct vme_bridge *tsi148_bridge = list->parent->parent; + + /* detach and free each entry */ + list_for_each_safe(pos, temp, &list->entries) { + list_del(pos); + entry = list_entry(pos, struct tsi148_dma_entry, list); + + dma_unmap_single(tsi148_bridge->parent, entry->dma_handle, + sizeof(struct tsi148_dma_descriptor), DMA_TO_DEVICE); + kfree(entry); + } + + return 0; +} + +/* + * All 4 location monitors reside at the same base - this is therefore a + * system wide configuration. + * + * This does not enable the LM monitor - that should be done when the first + * callback is attached and disabled when the last callback is removed. + */ +static int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, + u32 aspace, u32 cycle) +{ + u32 lm_base_high, lm_base_low, lm_ctl = 0; + int i; + struct vme_bridge *tsi148_bridge; + struct tsi148_driver *bridge; + + tsi148_bridge = lm->parent; + + bridge = tsi148_bridge->driver_priv; + + mutex_lock(&lm->mtx); + + /* If we already have a callback attached, we can't move it! */ + for (i = 0; i < lm->monitors; i++) { + if (bridge->lm_callback[i] != NULL) { + mutex_unlock(&lm->mtx); + dev_err(tsi148_bridge->parent, "Location monitor " + "callback attached, can't reset\n"); + return -EBUSY; + } + } + + switch (aspace) { + case VME_A16: + lm_ctl |= TSI148_LCSR_LMAT_AS_A16; + break; + case VME_A24: + lm_ctl |= TSI148_LCSR_LMAT_AS_A24; + break; + case VME_A32: + lm_ctl |= TSI148_LCSR_LMAT_AS_A32; + break; + case VME_A64: + lm_ctl |= TSI148_LCSR_LMAT_AS_A64; + break; + default: + mutex_unlock(&lm->mtx); + dev_err(tsi148_bridge->parent, "Invalid address space\n"); + return -EINVAL; + break; + } + + if (cycle & VME_SUPER) + lm_ctl |= TSI148_LCSR_LMAT_SUPR ; + if (cycle & VME_USER) + lm_ctl |= TSI148_LCSR_LMAT_NPRIV; + if (cycle & VME_PROG) + lm_ctl |= TSI148_LCSR_LMAT_PGM; + if (cycle & VME_DATA) + lm_ctl |= TSI148_LCSR_LMAT_DATA; + + reg_split(lm_base, &lm_base_high, &lm_base_low); + + iowrite32be(lm_base_high, bridge->base + TSI148_LCSR_LMBAU); + iowrite32be(lm_base_low, bridge->base + TSI148_LCSR_LMBAL); + iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT); + + mutex_unlock(&lm->mtx); + + return 0; +} + +/* Get configuration of the callback monitor and return whether it is enabled + * or disabled. + */ +static int tsi148_lm_get(struct vme_lm_resource *lm, + unsigned long long *lm_base, u32 *aspace, u32 *cycle) +{ + u32 lm_base_high, lm_base_low, lm_ctl, enabled = 0; + struct tsi148_driver *bridge; + + bridge = lm->parent->driver_priv; + + mutex_lock(&lm->mtx); + + lm_base_high = ioread32be(bridge->base + TSI148_LCSR_LMBAU); + lm_base_low = ioread32be(bridge->base + TSI148_LCSR_LMBAL); + lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT); + + reg_join(lm_base_high, lm_base_low, lm_base); + + if (lm_ctl & TSI148_LCSR_LMAT_EN) + enabled = 1; + + if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A16) + *aspace |= VME_A16; + + if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A24) + *aspace |= VME_A24; + + if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A32) + *aspace |= VME_A32; + + if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A64) + *aspace |= VME_A64; + + + if (lm_ctl & TSI148_LCSR_LMAT_SUPR) + *cycle |= VME_SUPER; + if (lm_ctl & TSI148_LCSR_LMAT_NPRIV) + *cycle |= VME_USER; + if (lm_ctl & TSI148_LCSR_LMAT_PGM) + *cycle |= VME_PROG; + if (lm_ctl & TSI148_LCSR_LMAT_DATA) + *cycle |= VME_DATA; + + mutex_unlock(&lm->mtx); + + return enabled; +} + +/* + * Attach a callback to a specific location monitor. + * + * Callback will be passed the monitor triggered. + */ +static int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor, + void (*callback)(int)) +{ + u32 lm_ctl, tmp; + struct vme_bridge *tsi148_bridge; + struct tsi148_driver *bridge; + + tsi148_bridge = lm->parent; + + bridge = tsi148_bridge->driver_priv; + + mutex_lock(&lm->mtx); + + /* Ensure that the location monitor is configured - need PGM or DATA */ + lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT); + if ((lm_ctl & (TSI148_LCSR_LMAT_PGM | TSI148_LCSR_LMAT_DATA)) == 0) { + mutex_unlock(&lm->mtx); + dev_err(tsi148_bridge->parent, "Location monitor not properly " + "configured\n"); + return -EINVAL; + } + + /* Check that a callback isn't already attached */ + if (bridge->lm_callback[monitor] != NULL) { + mutex_unlock(&lm->mtx); + dev_err(tsi148_bridge->parent, "Existing callback attached\n"); + return -EBUSY; + } + + /* Attach callback */ + bridge->lm_callback[monitor] = callback; + + /* Enable Location Monitor interrupt */ + tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN); + tmp |= TSI148_LCSR_INTEN_LMEN[monitor]; + iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN); + + tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO); + tmp |= TSI148_LCSR_INTEO_LMEO[monitor]; + iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO); + + /* Ensure that global Location Monitor Enable set */ + if ((lm_ctl & TSI148_LCSR_LMAT_EN) == 0) { + lm_ctl |= TSI148_LCSR_LMAT_EN; + iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT); + } + + mutex_unlock(&lm->mtx); + + return 0; +} + +/* + * Detach a callback function forn a specific location monitor. + */ +static int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor) +{ + u32 lm_en, tmp; + struct tsi148_driver *bridge; + + bridge = lm->parent->driver_priv; + + mutex_lock(&lm->mtx); + + /* Disable Location Monitor and ensure previous interrupts are clear */ + lm_en = ioread32be(bridge->base + TSI148_LCSR_INTEN); + lm_en &= ~TSI148_LCSR_INTEN_LMEN[monitor]; + iowrite32be(lm_en, bridge->base + TSI148_LCSR_INTEN); + + tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO); + tmp &= ~TSI148_LCSR_INTEO_LMEO[monitor]; + iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO); + + iowrite32be(TSI148_LCSR_INTC_LMC[monitor], + bridge->base + TSI148_LCSR_INTC); + + /* Detach callback */ + bridge->lm_callback[monitor] = NULL; + + /* If all location monitors disabled, disable global Location Monitor */ + if ((lm_en & (TSI148_LCSR_INTS_LM0S | TSI148_LCSR_INTS_LM1S | + TSI148_LCSR_INTS_LM2S | TSI148_LCSR_INTS_LM3S)) == 0) { + tmp = ioread32be(bridge->base + TSI148_LCSR_LMAT); + tmp &= ~TSI148_LCSR_LMAT_EN; + iowrite32be(tmp, bridge->base + TSI148_LCSR_LMAT); + } + + mutex_unlock(&lm->mtx); + + return 0; +} + +/* + * Determine Geographical Addressing + */ +static int tsi148_slot_get(struct vme_bridge *tsi148_bridge) +{ + u32 slot = 0; + struct tsi148_driver *bridge; + + bridge = tsi148_bridge->driver_priv; + + if (!geoid) { + slot = ioread32be(bridge->base + TSI148_LCSR_VSTAT); + slot = slot & TSI148_LCSR_VSTAT_GA_M; + } else + slot = geoid; + + return (int)slot; +} + +void *tsi148_alloc_consistent(struct device *parent, size_t size, + dma_addr_t *dma) +{ + struct pci_dev *pdev; + + /* Find pci_dev container of dev */ + pdev = container_of(parent, struct pci_dev, dev); + + return pci_alloc_consistent(pdev, size, dma); +} + +void tsi148_free_consistent(struct device *parent, size_t size, void *vaddr, + dma_addr_t dma) +{ + struct pci_dev *pdev; + + /* Find pci_dev container of dev */ + pdev = container_of(parent, struct pci_dev, dev); + + pci_free_consistent(pdev, size, vaddr, dma); +} + +static int __init tsi148_init(void) +{ + return pci_register_driver(&tsi148_driver); +} + +/* + * Configure CR/CSR space + * + * Access to the CR/CSR can be configured at power-up. The location of the + * CR/CSR registers in the CR/CSR address space is determined by the boards + * Auto-ID or Geographic address. This function ensures that the window is + * enabled at an offset consistent with the boards geopgraphic address. + * + * Each board has a 512kB window, with the highest 4kB being used for the + * boards registers, this means there is a fix length 508kB window which must + * be mapped onto PCI memory. + */ +static int tsi148_crcsr_init(struct vme_bridge *tsi148_bridge, + struct pci_dev *pdev) +{ + u32 cbar, crat, vstat; + u32 crcsr_bus_high, crcsr_bus_low; + int retval; + struct tsi148_driver *bridge; + + bridge = tsi148_bridge->driver_priv; + + /* Allocate mem for CR/CSR image */ + bridge->crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE, + &bridge->crcsr_bus); + if (bridge->crcsr_kernel == NULL) { + dev_err(tsi148_bridge->parent, "Failed to allocate memory for " + "CR/CSR image\n"); + return -ENOMEM; + } + + memset(bridge->crcsr_kernel, 0, VME_CRCSR_BUF_SIZE); + + reg_split(bridge->crcsr_bus, &crcsr_bus_high, &crcsr_bus_low); + + iowrite32be(crcsr_bus_high, bridge->base + TSI148_LCSR_CROU); + iowrite32be(crcsr_bus_low, bridge->base + TSI148_LCSR_CROL); + + /* Ensure that the CR/CSR is configured at the correct offset */ + cbar = ioread32be(bridge->base + TSI148_CBAR); + cbar = (cbar & TSI148_CRCSR_CBAR_M)>>3; + + vstat = tsi148_slot_get(tsi148_bridge); + + if (cbar != vstat) { + cbar = vstat; + dev_info(tsi148_bridge->parent, "Setting CR/CSR offset\n"); + iowrite32be(cbar<<3, bridge->base + TSI148_CBAR); + } + dev_info(tsi148_bridge->parent, "CR/CSR Offset: %d\n", cbar); + + crat = ioread32be(bridge->base + TSI148_LCSR_CRAT); + if (crat & TSI148_LCSR_CRAT_EN) { + dev_info(tsi148_bridge->parent, "Enabling CR/CSR space\n"); + iowrite32be(crat | TSI148_LCSR_CRAT_EN, + bridge->base + TSI148_LCSR_CRAT); + } else + dev_info(tsi148_bridge->parent, "CR/CSR already enabled\n"); + + /* If we want flushed, error-checked writes, set up a window + * over the CR/CSR registers. We read from here to safely flush + * through VME writes. + */ + if (err_chk) { + retval = tsi148_master_set(bridge->flush_image, 1, + (vstat * 0x80000), 0x80000, VME_CRCSR, VME_SCT, + VME_D16); + if (retval) + dev_err(tsi148_bridge->parent, "Configuring flush image" + " failed\n"); + } + + return 0; + +} + +static void tsi148_crcsr_exit(struct vme_bridge *tsi148_bridge, + struct pci_dev *pdev) +{ + u32 crat; + struct tsi148_driver *bridge; + + bridge = tsi148_bridge->driver_priv; + + /* Turn off CR/CSR space */ + crat = ioread32be(bridge->base + TSI148_LCSR_CRAT); + iowrite32be(crat & ~TSI148_LCSR_CRAT_EN, + bridge->base + TSI148_LCSR_CRAT); + + /* Free image */ + iowrite32be(0, bridge->base + TSI148_LCSR_CROU); + iowrite32be(0, bridge->base + TSI148_LCSR_CROL); + + pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, bridge->crcsr_kernel, + bridge->crcsr_bus); +} + +static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + int retval, i, master_num; + u32 data; + struct list_head *pos = NULL; + struct vme_bridge *tsi148_bridge; + struct tsi148_driver *tsi148_device; + struct vme_master_resource *master_image; + struct vme_slave_resource *slave_image; + struct vme_dma_resource *dma_ctrlr; + struct vme_lm_resource *lm; + + /* If we want to support more than one of each bridge, we need to + * dynamically generate this so we get one per device + */ + tsi148_bridge = kzalloc(sizeof(struct vme_bridge), GFP_KERNEL); + if (tsi148_bridge == NULL) { + dev_err(&pdev->dev, "Failed to allocate memory for device " + "structure\n"); + retval = -ENOMEM; + goto err_struct; + } + + tsi148_device = kzalloc(sizeof(struct tsi148_driver), GFP_KERNEL); + if (tsi148_device == NULL) { + dev_err(&pdev->dev, "Failed to allocate memory for device " + "structure\n"); + retval = -ENOMEM; + goto err_driver; + } + + tsi148_bridge->driver_priv = tsi148_device; + + /* Enable the device */ + retval = pci_enable_device(pdev); + if (retval) { + dev_err(&pdev->dev, "Unable to enable device\n"); + goto err_enable; + } + + /* Map Registers */ + retval = pci_request_regions(pdev, driver_name); + if (retval) { + dev_err(&pdev->dev, "Unable to reserve resources\n"); + goto err_resource; + } + + /* map registers in BAR 0 */ + tsi148_device->base = ioremap_nocache(pci_resource_start(pdev, 0), + 4096); + if (!tsi148_device->base) { + dev_err(&pdev->dev, "Unable to remap CRG region\n"); + retval = -EIO; + goto err_remap; + } + + /* Check to see if the mapping worked out */ + data = ioread32(tsi148_device->base + TSI148_PCFS_ID) & 0x0000FFFF; + if (data != PCI_VENDOR_ID_TUNDRA) { + dev_err(&pdev->dev, "CRG region check failed\n"); + retval = -EIO; + goto err_test; + } + + /* Initialize wait queues & mutual exclusion flags */ + init_waitqueue_head(&tsi148_device->dma_queue[0]); + init_waitqueue_head(&tsi148_device->dma_queue[1]); + init_waitqueue_head(&tsi148_device->iack_queue); + mutex_init(&tsi148_device->vme_int); + mutex_init(&tsi148_device->vme_rmw); + + tsi148_bridge->parent = &pdev->dev; + strcpy(tsi148_bridge->name, driver_name); + + /* Setup IRQ */ + retval = tsi148_irq_init(tsi148_bridge); + if (retval != 0) { + dev_err(&pdev->dev, "Chip Initialization failed.\n"); + goto err_irq; + } + + /* If we are going to flush writes, we need to read from the VME bus. + * We need to do this safely, thus we read the devices own CR/CSR + * register. To do this we must set up a window in CR/CSR space and + * hence have one less master window resource available. + */ + master_num = TSI148_MAX_MASTER; + if (err_chk) { + master_num--; + + tsi148_device->flush_image = + kmalloc(sizeof(struct vme_master_resource), GFP_KERNEL); + if (tsi148_device->flush_image == NULL) { + dev_err(&pdev->dev, "Failed to allocate memory for " + "flush resource structure\n"); + retval = -ENOMEM; + goto err_master; + } + tsi148_device->flush_image->parent = tsi148_bridge; + spin_lock_init(&tsi148_device->flush_image->lock); + tsi148_device->flush_image->locked = 1; + tsi148_device->flush_image->number = master_num; + tsi148_device->flush_image->address_attr = VME_A16 | VME_A24 | + VME_A32 | VME_A64; + tsi148_device->flush_image->cycle_attr = VME_SCT | VME_BLT | + VME_MBLT | VME_2eVME | VME_2eSST | VME_2eSSTB | + VME_2eSST160 | VME_2eSST267 | VME_2eSST320 | VME_SUPER | + VME_USER | VME_PROG | VME_DATA; + tsi148_device->flush_image->width_attr = VME_D16 | VME_D32; + memset(&tsi148_device->flush_image->bus_resource, 0, + sizeof(struct resource)); + tsi148_device->flush_image->kern_base = NULL; + } + + /* Add master windows to list */ + INIT_LIST_HEAD(&tsi148_bridge->master_resources); + for (i = 0; i < master_num; i++) { + master_image = kmalloc(sizeof(struct vme_master_resource), + GFP_KERNEL); + if (master_image == NULL) { + dev_err(&pdev->dev, "Failed to allocate memory for " + "master resource structure\n"); + retval = -ENOMEM; + goto err_master; + } + master_image->parent = tsi148_bridge; + spin_lock_init(&master_image->lock); + master_image->locked = 0; + master_image->number = i; + master_image->address_attr = VME_A16 | VME_A24 | VME_A32 | + VME_A64; + master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | + VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 | + VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER | + VME_PROG | VME_DATA; + master_image->width_attr = VME_D16 | VME_D32; + memset(&master_image->bus_resource, 0, + sizeof(struct resource)); + master_image->kern_base = NULL; + list_add_tail(&master_image->list, + &tsi148_bridge->master_resources); + } + + /* Add slave windows to list */ + INIT_LIST_HEAD(&tsi148_bridge->slave_resources); + for (i = 0; i < TSI148_MAX_SLAVE; i++) { + slave_image = kmalloc(sizeof(struct vme_slave_resource), + GFP_KERNEL); + if (slave_image == NULL) { + dev_err(&pdev->dev, "Failed to allocate memory for " + "slave resource structure\n"); + retval = -ENOMEM; + goto err_slave; + } + slave_image->parent = tsi148_bridge; + mutex_init(&slave_image->mtx); + slave_image->locked = 0; + slave_image->number = i; + slave_image->address_attr = VME_A16 | VME_A24 | VME_A32 | + VME_A64 | VME_CRCSR | VME_USER1 | VME_USER2 | + VME_USER3 | VME_USER4; + slave_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | + VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 | + VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER | + VME_PROG | VME_DATA; + list_add_tail(&slave_image->list, + &tsi148_bridge->slave_resources); + } + + /* Add dma engines to list */ + INIT_LIST_HEAD(&tsi148_bridge->dma_resources); + for (i = 0; i < TSI148_MAX_DMA; i++) { + dma_ctrlr = kmalloc(sizeof(struct vme_dma_resource), + GFP_KERNEL); + if (dma_ctrlr == NULL) { + dev_err(&pdev->dev, "Failed to allocate memory for " + "dma resource structure\n"); + retval = -ENOMEM; + goto err_dma; + } + dma_ctrlr->parent = tsi148_bridge; + mutex_init(&dma_ctrlr->mtx); + dma_ctrlr->locked = 0; + dma_ctrlr->number = i; + dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM | + VME_DMA_MEM_TO_VME | VME_DMA_VME_TO_VME | + VME_DMA_MEM_TO_MEM | VME_DMA_PATTERN_TO_VME | + VME_DMA_PATTERN_TO_MEM; + INIT_LIST_HEAD(&dma_ctrlr->pending); + INIT_LIST_HEAD(&dma_ctrlr->running); + list_add_tail(&dma_ctrlr->list, + &tsi148_bridge->dma_resources); + } + + /* Add location monitor to list */ + INIT_LIST_HEAD(&tsi148_bridge->lm_resources); + lm = kmalloc(sizeof(struct vme_lm_resource), GFP_KERNEL); + if (lm == NULL) { + dev_err(&pdev->dev, "Failed to allocate memory for " + "location monitor resource structure\n"); + retval = -ENOMEM; + goto err_lm; + } + lm->parent = tsi148_bridge; + mutex_init(&lm->mtx); + lm->locked = 0; + lm->number = 1; + lm->monitors = 4; + list_add_tail(&lm->list, &tsi148_bridge->lm_resources); + + tsi148_bridge->slave_get = tsi148_slave_get; + tsi148_bridge->slave_set = tsi148_slave_set; + tsi148_bridge->master_get = tsi148_master_get; + tsi148_bridge->master_set = tsi148_master_set; + tsi148_bridge->master_read = tsi148_master_read; + tsi148_bridge->master_write = tsi148_master_write; + tsi148_bridge->master_rmw = tsi148_master_rmw; + tsi148_bridge->dma_list_add = tsi148_dma_list_add; + tsi148_bridge->dma_list_exec = tsi148_dma_list_exec; + tsi148_bridge->dma_list_empty = tsi148_dma_list_empty; + tsi148_bridge->irq_set = tsi148_irq_set; + tsi148_bridge->irq_generate = tsi148_irq_generate; + tsi148_bridge->lm_set = tsi148_lm_set; + tsi148_bridge->lm_get = tsi148_lm_get; + tsi148_bridge->lm_attach = tsi148_lm_attach; + tsi148_bridge->lm_detach = tsi148_lm_detach; + tsi148_bridge->slot_get = tsi148_slot_get; + tsi148_bridge->alloc_consistent = tsi148_alloc_consistent; + tsi148_bridge->free_consistent = tsi148_free_consistent; + + data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT); + dev_info(&pdev->dev, "Board is%s the VME system controller\n", + (data & TSI148_LCSR_VSTAT_SCONS) ? "" : " not"); + if (!geoid) + dev_info(&pdev->dev, "VME geographical address is %d\n", + data & TSI148_LCSR_VSTAT_GA_M); + else + dev_info(&pdev->dev, "VME geographical address is set to %d\n", + geoid); + + dev_info(&pdev->dev, "VME Write and flush and error check is %s\n", + err_chk ? "enabled" : "disabled"); + + if (tsi148_crcsr_init(tsi148_bridge, pdev)) { + dev_err(&pdev->dev, "CR/CSR configuration failed.\n"); + goto err_crcsr; + } + + retval = vme_register_bridge(tsi148_bridge); + if (retval != 0) { + dev_err(&pdev->dev, "Chip Registration failed.\n"); + goto err_reg; + } + + pci_set_drvdata(pdev, tsi148_bridge); + + /* Clear VME bus "board fail", and "power-up reset" lines */ + data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT); + data &= ~TSI148_LCSR_VSTAT_BRDFL; + data |= TSI148_LCSR_VSTAT_CPURST; + iowrite32be(data, tsi148_device->base + TSI148_LCSR_VSTAT); + + return 0; + +err_reg: + tsi148_crcsr_exit(tsi148_bridge, pdev); +err_crcsr: +err_lm: + /* resources are stored in link list */ + list_for_each(pos, &tsi148_bridge->lm_resources) { + lm = list_entry(pos, struct vme_lm_resource, list); + list_del(pos); + kfree(lm); + } +err_dma: + /* resources are stored in link list */ + list_for_each(pos, &tsi148_bridge->dma_resources) { + dma_ctrlr = list_entry(pos, struct vme_dma_resource, list); + list_del(pos); + kfree(dma_ctrlr); + } +err_slave: + /* resources are stored in link list */ + list_for_each(pos, &tsi148_bridge->slave_resources) { + slave_image = list_entry(pos, struct vme_slave_resource, list); + list_del(pos); + kfree(slave_image); + } +err_master: + /* resources are stored in link list */ + list_for_each(pos, &tsi148_bridge->master_resources) { + master_image = list_entry(pos, struct vme_master_resource, + list); + list_del(pos); + kfree(master_image); + } + + tsi148_irq_exit(tsi148_bridge, pdev); +err_irq: +err_test: + iounmap(tsi148_device->base); +err_remap: + pci_release_regions(pdev); +err_resource: + pci_disable_device(pdev); +err_enable: + kfree(tsi148_device); +err_driver: + kfree(tsi148_bridge); +err_struct: + return retval; + +} + +static void tsi148_remove(struct pci_dev *pdev) +{ + struct list_head *pos = NULL; + struct list_head *tmplist; + struct vme_master_resource *master_image; + struct vme_slave_resource *slave_image; + struct vme_dma_resource *dma_ctrlr; + int i; + struct tsi148_driver *bridge; + struct vme_bridge *tsi148_bridge = pci_get_drvdata(pdev); + + bridge = tsi148_bridge->driver_priv; + + + dev_dbg(&pdev->dev, "Driver is being unloaded.\n"); + + /* + * Shutdown all inbound and outbound windows. + */ + for (i = 0; i < 8; i++) { + iowrite32be(0, bridge->base + TSI148_LCSR_IT[i] + + TSI148_LCSR_OFFSET_ITAT); + iowrite32be(0, bridge->base + TSI148_LCSR_OT[i] + + TSI148_LCSR_OFFSET_OTAT); + } + + /* + * Shutdown Location monitor. + */ + iowrite32be(0, bridge->base + TSI148_LCSR_LMAT); + + /* + * Shutdown CRG map. + */ + iowrite32be(0, bridge->base + TSI148_LCSR_CSRAT); + + /* + * Clear error status. + */ + iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_EDPAT); + iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_VEAT); + iowrite32be(0x07000700, bridge->base + TSI148_LCSR_PSTAT); + + /* + * Remove VIRQ interrupt (if any) + */ + if (ioread32be(bridge->base + TSI148_LCSR_VICR) & 0x800) + iowrite32be(0x8000, bridge->base + TSI148_LCSR_VICR); + + /* + * Map all Interrupts to PCI INTA + */ + iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM1); + iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM2); + + tsi148_irq_exit(tsi148_bridge, pdev); + + vme_unregister_bridge(tsi148_bridge); + + tsi148_crcsr_exit(tsi148_bridge, pdev); + + /* resources are stored in link list */ + list_for_each_safe(pos, tmplist, &tsi148_bridge->dma_resources) { + dma_ctrlr = list_entry(pos, struct vme_dma_resource, list); + list_del(pos); + kfree(dma_ctrlr); + } + + /* resources are stored in link list */ + list_for_each_safe(pos, tmplist, &tsi148_bridge->slave_resources) { + slave_image = list_entry(pos, struct vme_slave_resource, list); + list_del(pos); + kfree(slave_image); + } + + /* resources are stored in link list */ + list_for_each_safe(pos, tmplist, &tsi148_bridge->master_resources) { + master_image = list_entry(pos, struct vme_master_resource, + list); + list_del(pos); + kfree(master_image); + } + + iounmap(bridge->base); + + pci_release_regions(pdev); + + pci_disable_device(pdev); + + kfree(tsi148_bridge->driver_priv); + + kfree(tsi148_bridge); +} + +static void __exit tsi148_exit(void) +{ + pci_unregister_driver(&tsi148_driver); +} + +MODULE_PARM_DESC(err_chk, "Check for VME errors on reads and writes"); +module_param(err_chk, bool, 0); + +MODULE_PARM_DESC(geoid, "Override geographical addressing"); +module_param(geoid, int, 0); + +MODULE_DESCRIPTION("VME driver for the Tundra Tempe VME bridge"); +MODULE_LICENSE("GPL"); + +module_init(tsi148_init); +module_exit(tsi148_exit); diff --git a/drivers/vme/bridges/vme_tsi148.h b/drivers/vme/bridges/vme_tsi148.h new file mode 100644 index 0000000..f5ed143 --- /dev/null +++ b/drivers/vme/bridges/vme_tsi148.h @@ -0,0 +1,1410 @@ +/* + * tsi148.h + * + * Support for the Tundra TSI148 VME Bridge chip + * + * Author: Tom Armistead + * Updated and maintained by Ajit Prem + * Copyright 2004 Motorola Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef TSI148_H +#define TSI148_H + +#ifndef PCI_VENDOR_ID_TUNDRA +#define PCI_VENDOR_ID_TUNDRA 0x10e3 +#endif + +#ifndef PCI_DEVICE_ID_TUNDRA_TSI148 +#define PCI_DEVICE_ID_TUNDRA_TSI148 0x148 +#endif + +/* + * Define the number of each that the Tsi148 supports. + */ +#define TSI148_MAX_MASTER 8 /* Max Master Windows */ +#define TSI148_MAX_SLAVE 8 /* Max Slave Windows */ +#define TSI148_MAX_DMA 2 /* Max DMA Controllers */ +#define TSI148_MAX_MAILBOX 4 /* Max Mail Box registers */ +#define TSI148_MAX_SEMAPHORE 8 /* Max Semaphores */ + +/* Structure used to hold driver specific information */ +struct tsi148_driver { + void __iomem *base; /* Base Address of device registers */ + wait_queue_head_t dma_queue[2]; + wait_queue_head_t iack_queue; + void (*lm_callback[4])(int); /* Called in interrupt handler */ + void *crcsr_kernel; + dma_addr_t crcsr_bus; + struct vme_master_resource *flush_image; + struct mutex vme_rmw; /* Only one RMW cycle at a time */ + struct mutex vme_int; /* + * Only one VME interrupt can be + * generated at a time, provide locking + */ +}; + +/* + * Layout of a DMAC Linked-List Descriptor + * + * Note: This structure is accessed via the chip and therefore must be + * correctly laid out - It must also be aligned on 64-bit boundaries. + */ +struct tsi148_dma_descriptor { + __be32 dsau; /* Source Address */ + __be32 dsal; + __be32 ddau; /* Destination Address */ + __be32 ddal; + __be32 dsat; /* Source attributes */ + __be32 ddat; /* Destination attributes */ + __be32 dnlau; /* Next link address */ + __be32 dnlal; + __be32 dcnt; /* Byte count */ + __be32 ddbs; /* 2eSST Broadcast select */ +}; + +struct tsi148_dma_entry { + /* + * The descriptor needs to be aligned on a 64-bit boundary, we increase + * the chance of this by putting it first in the structure. + */ + struct tsi148_dma_descriptor descriptor; + struct list_head list; + dma_addr_t dma_handle; +}; + +/* + * TSI148 ASIC register structure overlays and bit field definitions. + * + * Note: Tsi148 Register Group (CRG) consists of the following + * combination of registers: + * PCFS - PCI Configuration Space Registers + * LCSR - Local Control and Status Registers + * GCSR - Global Control and Status Registers + * CR/CSR - Subset of Configuration ROM / + * Control and Status Registers + */ + + +/* + * Command/Status Registers (CRG + $004) + */ +#define TSI148_PCFS_ID 0x0 +#define TSI148_PCFS_CSR 0x4 +#define TSI148_PCFS_CLASS 0x8 +#define TSI148_PCFS_MISC0 0xC +#define TSI148_PCFS_MBARL 0x10 +#define TSI148_PCFS_MBARU 0x14 + +#define TSI148_PCFS_SUBID 0x28 + +#define TSI148_PCFS_CAPP 0x34 + +#define TSI148_PCFS_MISC1 0x3C + +#define TSI148_PCFS_XCAPP 0x40 +#define TSI148_PCFS_XSTAT 0x44 + +/* + * LCSR definitions + */ + +/* + * Outbound Translations + */ +#define TSI148_LCSR_OT0_OTSAU 0x100 +#define TSI148_LCSR_OT0_OTSAL 0x104 +#define TSI148_LCSR_OT0_OTEAU 0x108 +#define TSI148_LCSR_OT0_OTEAL 0x10C +#define TSI148_LCSR_OT0_OTOFU 0x110 +#define TSI148_LCSR_OT0_OTOFL 0x114 +#define TSI148_LCSR_OT0_OTBS 0x118 +#define TSI148_LCSR_OT0_OTAT 0x11C + +#define TSI148_LCSR_OT1_OTSAU 0x120 +#define TSI148_LCSR_OT1_OTSAL 0x124 +#define TSI148_LCSR_OT1_OTEAU 0x128 +#define TSI148_LCSR_OT1_OTEAL 0x12C +#define TSI148_LCSR_OT1_OTOFU 0x130 +#define TSI148_LCSR_OT1_OTOFL 0x134 +#define TSI148_LCSR_OT1_OTBS 0x138 +#define TSI148_LCSR_OT1_OTAT 0x13C + +#define TSI148_LCSR_OT2_OTSAU 0x140 +#define TSI148_LCSR_OT2_OTSAL 0x144 +#define TSI148_LCSR_OT2_OTEAU 0x148 +#define TSI148_LCSR_OT2_OTEAL 0x14C +#define TSI148_LCSR_OT2_OTOFU 0x150 +#define TSI148_LCSR_OT2_OTOFL 0x154 +#define TSI148_LCSR_OT2_OTBS 0x158 +#define TSI148_LCSR_OT2_OTAT 0x15C + +#define TSI148_LCSR_OT3_OTSAU 0x160 +#define TSI148_LCSR_OT3_OTSAL 0x164 +#define TSI148_LCSR_OT3_OTEAU 0x168 +#define TSI148_LCSR_OT3_OTEAL 0x16C +#define TSI148_LCSR_OT3_OTOFU 0x170 +#define TSI148_LCSR_OT3_OTOFL 0x174 +#define TSI148_LCSR_OT3_OTBS 0x178 +#define TSI148_LCSR_OT3_OTAT 0x17C + +#define TSI148_LCSR_OT4_OTSAU 0x180 +#define TSI148_LCSR_OT4_OTSAL 0x184 +#define TSI148_LCSR_OT4_OTEAU 0x188 +#define TSI148_LCSR_OT4_OTEAL 0x18C +#define TSI148_LCSR_OT4_OTOFU 0x190 +#define TSI148_LCSR_OT4_OTOFL 0x194 +#define TSI148_LCSR_OT4_OTBS 0x198 +#define TSI148_LCSR_OT4_OTAT 0x19C + +#define TSI148_LCSR_OT5_OTSAU 0x1A0 +#define TSI148_LCSR_OT5_OTSAL 0x1A4 +#define TSI148_LCSR_OT5_OTEAU 0x1A8 +#define TSI148_LCSR_OT5_OTEAL 0x1AC +#define TSI148_LCSR_OT5_OTOFU 0x1B0 +#define TSI148_LCSR_OT5_OTOFL 0x1B4 +#define TSI148_LCSR_OT5_OTBS 0x1B8 +#define TSI148_LCSR_OT5_OTAT 0x1BC + +#define TSI148_LCSR_OT6_OTSAU 0x1C0 +#define TSI148_LCSR_OT6_OTSAL 0x1C4 +#define TSI148_LCSR_OT6_OTEAU 0x1C8 +#define TSI148_LCSR_OT6_OTEAL 0x1CC +#define TSI148_LCSR_OT6_OTOFU 0x1D0 +#define TSI148_LCSR_OT6_OTOFL 0x1D4 +#define TSI148_LCSR_OT6_OTBS 0x1D8 +#define TSI148_LCSR_OT6_OTAT 0x1DC + +#define TSI148_LCSR_OT7_OTSAU 0x1E0 +#define TSI148_LCSR_OT7_OTSAL 0x1E4 +#define TSI148_LCSR_OT7_OTEAU 0x1E8 +#define TSI148_LCSR_OT7_OTEAL 0x1EC +#define TSI148_LCSR_OT7_OTOFU 0x1F0 +#define TSI148_LCSR_OT7_OTOFL 0x1F4 +#define TSI148_LCSR_OT7_OTBS 0x1F8 +#define TSI148_LCSR_OT7_OTAT 0x1FC + +#define TSI148_LCSR_OT0 0x100 +#define TSI148_LCSR_OT1 0x120 +#define TSI148_LCSR_OT2 0x140 +#define TSI148_LCSR_OT3 0x160 +#define TSI148_LCSR_OT4 0x180 +#define TSI148_LCSR_OT5 0x1A0 +#define TSI148_LCSR_OT6 0x1C0 +#define TSI148_LCSR_OT7 0x1E0 + +static const int TSI148_LCSR_OT[8] = { TSI148_LCSR_OT0, TSI148_LCSR_OT1, + TSI148_LCSR_OT2, TSI148_LCSR_OT3, + TSI148_LCSR_OT4, TSI148_LCSR_OT5, + TSI148_LCSR_OT6, TSI148_LCSR_OT7 }; + +#define TSI148_LCSR_OFFSET_OTSAU 0x0 +#define TSI148_LCSR_OFFSET_OTSAL 0x4 +#define TSI148_LCSR_OFFSET_OTEAU 0x8 +#define TSI148_LCSR_OFFSET_OTEAL 0xC +#define TSI148_LCSR_OFFSET_OTOFU 0x10 +#define TSI148_LCSR_OFFSET_OTOFL 0x14 +#define TSI148_LCSR_OFFSET_OTBS 0x18 +#define TSI148_LCSR_OFFSET_OTAT 0x1C + +/* + * VMEbus interrupt ack + * offset 200 + */ +#define TSI148_LCSR_VIACK1 0x204 +#define TSI148_LCSR_VIACK2 0x208 +#define TSI148_LCSR_VIACK3 0x20C +#define TSI148_LCSR_VIACK4 0x210 +#define TSI148_LCSR_VIACK5 0x214 +#define TSI148_LCSR_VIACK6 0x218 +#define TSI148_LCSR_VIACK7 0x21C + +static const int TSI148_LCSR_VIACK[8] = { 0, TSI148_LCSR_VIACK1, + TSI148_LCSR_VIACK2, TSI148_LCSR_VIACK3, + TSI148_LCSR_VIACK4, TSI148_LCSR_VIACK5, + TSI148_LCSR_VIACK6, TSI148_LCSR_VIACK7 }; + +/* + * RMW + * offset 220 + */ +#define TSI148_LCSR_RMWAU 0x220 +#define TSI148_LCSR_RMWAL 0x224 +#define TSI148_LCSR_RMWEN 0x228 +#define TSI148_LCSR_RMWC 0x22C +#define TSI148_LCSR_RMWS 0x230 + +/* + * VMEbus control + * offset 234 + */ +#define TSI148_LCSR_VMCTRL 0x234 +#define TSI148_LCSR_VCTRL 0x238 +#define TSI148_LCSR_VSTAT 0x23C + +/* + * PCI status + * offset 240 + */ +#define TSI148_LCSR_PSTAT 0x240 + +/* + * VME filter. + * offset 250 + */ +#define TSI148_LCSR_VMEFL 0x250 + + /* + * VME exception. + * offset 260 + */ +#define TSI148_LCSR_VEAU 0x260 +#define TSI148_LCSR_VEAL 0x264 +#define TSI148_LCSR_VEAT 0x268 + + /* + * PCI error + * offset 270 + */ +#define TSI148_LCSR_EDPAU 0x270 +#define TSI148_LCSR_EDPAL 0x274 +#define TSI148_LCSR_EDPXA 0x278 +#define TSI148_LCSR_EDPXS 0x27C +#define TSI148_LCSR_EDPAT 0x280 + + /* + * Inbound Translations + * offset 300 + */ +#define TSI148_LCSR_IT0_ITSAU 0x300 +#define TSI148_LCSR_IT0_ITSAL 0x304 +#define TSI148_LCSR_IT0_ITEAU 0x308 +#define TSI148_LCSR_IT0_ITEAL 0x30C +#define TSI148_LCSR_IT0_ITOFU 0x310 +#define TSI148_LCSR_IT0_ITOFL 0x314 +#define TSI148_LCSR_IT0_ITAT 0x318 + +#define TSI148_LCSR_IT1_ITSAU 0x320 +#define TSI148_LCSR_IT1_ITSAL 0x324 +#define TSI148_LCSR_IT1_ITEAU 0x328 +#define TSI148_LCSR_IT1_ITEAL 0x32C +#define TSI148_LCSR_IT1_ITOFU 0x330 +#define TSI148_LCSR_IT1_ITOFL 0x334 +#define TSI148_LCSR_IT1_ITAT 0x338 + +#define TSI148_LCSR_IT2_ITSAU 0x340 +#define TSI148_LCSR_IT2_ITSAL 0x344 +#define TSI148_LCSR_IT2_ITEAU 0x348 +#define TSI148_LCSR_IT2_ITEAL 0x34C +#define TSI148_LCSR_IT2_ITOFU 0x350 +#define TSI148_LCSR_IT2_ITOFL 0x354 +#define TSI148_LCSR_IT2_ITAT 0x358 + +#define TSI148_LCSR_IT3_ITSAU 0x360 +#define TSI148_LCSR_IT3_ITSAL 0x364 +#define TSI148_LCSR_IT3_ITEAU 0x368 +#define TSI148_LCSR_IT3_ITEAL 0x36C +#define TSI148_LCSR_IT3_ITOFU 0x370 +#define TSI148_LCSR_IT3_ITOFL 0x374 +#define TSI148_LCSR_IT3_ITAT 0x378 + +#define TSI148_LCSR_IT4_ITSAU 0x380 +#define TSI148_LCSR_IT4_ITSAL 0x384 +#define TSI148_LCSR_IT4_ITEAU 0x388 +#define TSI148_LCSR_IT4_ITEAL 0x38C +#define TSI148_LCSR_IT4_ITOFU 0x390 +#define TSI148_LCSR_IT4_ITOFL 0x394 +#define TSI148_LCSR_IT4_ITAT 0x398 + +#define TSI148_LCSR_IT5_ITSAU 0x3A0 +#define TSI148_LCSR_IT5_ITSAL 0x3A4 +#define TSI148_LCSR_IT5_ITEAU 0x3A8 +#define TSI148_LCSR_IT5_ITEAL 0x3AC +#define TSI148_LCSR_IT5_ITOFU 0x3B0 +#define TSI148_LCSR_IT5_ITOFL 0x3B4 +#define TSI148_LCSR_IT5_ITAT 0x3B8 + +#define TSI148_LCSR_IT6_ITSAU 0x3C0 +#define TSI148_LCSR_IT6_ITSAL 0x3C4 +#define TSI148_LCSR_IT6_ITEAU 0x3C8 +#define TSI148_LCSR_IT6_ITEAL 0x3CC +#define TSI148_LCSR_IT6_ITOFU 0x3D0 +#define TSI148_LCSR_IT6_ITOFL 0x3D4 +#define TSI148_LCSR_IT6_ITAT 0x3D8 + +#define TSI148_LCSR_IT7_ITSAU 0x3E0 +#define TSI148_LCSR_IT7_ITSAL 0x3E4 +#define TSI148_LCSR_IT7_ITEAU 0x3E8 +#define TSI148_LCSR_IT7_ITEAL 0x3EC +#define TSI148_LCSR_IT7_ITOFU 0x3F0 +#define TSI148_LCSR_IT7_ITOFL 0x3F4 +#define TSI148_LCSR_IT7_ITAT 0x3F8 + + +#define TSI148_LCSR_IT0 0x300 +#define TSI148_LCSR_IT1 0x320 +#define TSI148_LCSR_IT2 0x340 +#define TSI148_LCSR_IT3 0x360 +#define TSI148_LCSR_IT4 0x380 +#define TSI148_LCSR_IT5 0x3A0 +#define TSI148_LCSR_IT6 0x3C0 +#define TSI148_LCSR_IT7 0x3E0 + +static const int TSI148_LCSR_IT[8] = { TSI148_LCSR_IT0, TSI148_LCSR_IT1, + TSI148_LCSR_IT2, TSI148_LCSR_IT3, + TSI148_LCSR_IT4, TSI148_LCSR_IT5, + TSI148_LCSR_IT6, TSI148_LCSR_IT7 }; + +#define TSI148_LCSR_OFFSET_ITSAU 0x0 +#define TSI148_LCSR_OFFSET_ITSAL 0x4 +#define TSI148_LCSR_OFFSET_ITEAU 0x8 +#define TSI148_LCSR_OFFSET_ITEAL 0xC +#define TSI148_LCSR_OFFSET_ITOFU 0x10 +#define TSI148_LCSR_OFFSET_ITOFL 0x14 +#define TSI148_LCSR_OFFSET_ITAT 0x18 + + /* + * Inbound Translation GCSR + * offset 400 + */ +#define TSI148_LCSR_GBAU 0x400 +#define TSI148_LCSR_GBAL 0x404 +#define TSI148_LCSR_GCSRAT 0x408 + + /* + * Inbound Translation CRG + * offset 40C + */ +#define TSI148_LCSR_CBAU 0x40C +#define TSI148_LCSR_CBAL 0x410 +#define TSI148_LCSR_CSRAT 0x414 + + /* + * Inbound Translation CR/CSR + * CRG + * offset 418 + */ +#define TSI148_LCSR_CROU 0x418 +#define TSI148_LCSR_CROL 0x41C +#define TSI148_LCSR_CRAT 0x420 + + /* + * Inbound Translation Location Monitor + * offset 424 + */ +#define TSI148_LCSR_LMBAU 0x424 +#define TSI148_LCSR_LMBAL 0x428 +#define TSI148_LCSR_LMAT 0x42C + + /* + * VMEbus Interrupt Control. + * offset 430 + */ +#define TSI148_LCSR_BCU 0x430 +#define TSI148_LCSR_BCL 0x434 +#define TSI148_LCSR_BPGTR 0x438 +#define TSI148_LCSR_BPCTR 0x43C +#define TSI148_LCSR_VICR 0x440 + + /* + * Local Bus Interrupt Control. + * offset 448 + */ +#define TSI148_LCSR_INTEN 0x448 +#define TSI148_LCSR_INTEO 0x44C +#define TSI148_LCSR_INTS 0x450 +#define TSI148_LCSR_INTC 0x454 +#define TSI148_LCSR_INTM1 0x458 +#define TSI148_LCSR_INTM2 0x45C + + /* + * DMA Controllers + * offset 500 + */ +#define TSI148_LCSR_DCTL0 0x500 +#define TSI148_LCSR_DSTA0 0x504 +#define TSI148_LCSR_DCSAU0 0x508 +#define TSI148_LCSR_DCSAL0 0x50C +#define TSI148_LCSR_DCDAU0 0x510 +#define TSI148_LCSR_DCDAL0 0x514 +#define TSI148_LCSR_DCLAU0 0x518 +#define TSI148_LCSR_DCLAL0 0x51C +#define TSI148_LCSR_DSAU0 0x520 +#define TSI148_LCSR_DSAL0 0x524 +#define TSI148_LCSR_DDAU0 0x528 +#define TSI148_LCSR_DDAL0 0x52C +#define TSI148_LCSR_DSAT0 0x530 +#define TSI148_LCSR_DDAT0 0x534 +#define TSI148_LCSR_DNLAU0 0x538 +#define TSI148_LCSR_DNLAL0 0x53C +#define TSI148_LCSR_DCNT0 0x540 +#define TSI148_LCSR_DDBS0 0x544 + +#define TSI148_LCSR_DCTL1 0x580 +#define TSI148_LCSR_DSTA1 0x584 +#define TSI148_LCSR_DCSAU1 0x588 +#define TSI148_LCSR_DCSAL1 0x58C +#define TSI148_LCSR_DCDAU1 0x590 +#define TSI148_LCSR_DCDAL1 0x594 +#define TSI148_LCSR_DCLAU1 0x598 +#define TSI148_LCSR_DCLAL1 0x59C +#define TSI148_LCSR_DSAU1 0x5A0 +#define TSI148_LCSR_DSAL1 0x5A4 +#define TSI148_LCSR_DDAU1 0x5A8 +#define TSI148_LCSR_DDAL1 0x5AC +#define TSI148_LCSR_DSAT1 0x5B0 +#define TSI148_LCSR_DDAT1 0x5B4 +#define TSI148_LCSR_DNLAU1 0x5B8 +#define TSI148_LCSR_DNLAL1 0x5BC +#define TSI148_LCSR_DCNT1 0x5C0 +#define TSI148_LCSR_DDBS1 0x5C4 + +#define TSI148_LCSR_DMA0 0x500 +#define TSI148_LCSR_DMA1 0x580 + + +static const int TSI148_LCSR_DMA[TSI148_MAX_DMA] = { TSI148_LCSR_DMA0, + TSI148_LCSR_DMA1 }; + +#define TSI148_LCSR_OFFSET_DCTL 0x0 +#define TSI148_LCSR_OFFSET_DSTA 0x4 +#define TSI148_LCSR_OFFSET_DCSAU 0x8 +#define TSI148_LCSR_OFFSET_DCSAL 0xC +#define TSI148_LCSR_OFFSET_DCDAU 0x10 +#define TSI148_LCSR_OFFSET_DCDAL 0x14 +#define TSI148_LCSR_OFFSET_DCLAU 0x18 +#define TSI148_LCSR_OFFSET_DCLAL 0x1C +#define TSI148_LCSR_OFFSET_DSAU 0x20 +#define TSI148_LCSR_OFFSET_DSAL 0x24 +#define TSI148_LCSR_OFFSET_DDAU 0x28 +#define TSI148_LCSR_OFFSET_DDAL 0x2C +#define TSI148_LCSR_OFFSET_DSAT 0x30 +#define TSI148_LCSR_OFFSET_DDAT 0x34 +#define TSI148_LCSR_OFFSET_DNLAU 0x38 +#define TSI148_LCSR_OFFSET_DNLAL 0x3C +#define TSI148_LCSR_OFFSET_DCNT 0x40 +#define TSI148_LCSR_OFFSET_DDBS 0x44 + + /* + * GCSR Register Group + */ + + /* + * GCSR CRG + * offset 00 600 - DEVI/VENI + * offset 04 604 - CTRL/GA/REVID + * offset 08 608 - Semaphore3/2/1/0 + * offset 0C 60C - Seamphore7/6/5/4 + */ +#define TSI148_GCSR_ID 0x600 +#define TSI148_GCSR_CSR 0x604 +#define TSI148_GCSR_SEMA0 0x608 +#define TSI148_GCSR_SEMA1 0x60C + + /* + * Mail Box + * GCSR CRG + * offset 10 610 - Mailbox0 + */ +#define TSI148_GCSR_MBOX0 0x610 +#define TSI148_GCSR_MBOX1 0x614 +#define TSI148_GCSR_MBOX2 0x618 +#define TSI148_GCSR_MBOX3 0x61C + +static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, + TSI148_GCSR_MBOX1, + TSI148_GCSR_MBOX2, + TSI148_GCSR_MBOX3 }; + + /* + * CR/CSR + */ + + /* + * CR/CSR CRG + * offset 7FFF4 FF4 - CSRBCR + * offset 7FFF8 FF8 - CSRBSR + * offset 7FFFC FFC - CBAR + */ +#define TSI148_CSRBCR 0xFF4 +#define TSI148_CSRBSR 0xFF8 +#define TSI148_CBAR 0xFFC + + + + + /* + * TSI148 Register Bit Definitions + */ + + /* + * PFCS Register Set + */ +#define TSI148_PCFS_CMMD_SERR (1<<8) /* SERR_L out pin ssys err */ +#define TSI148_PCFS_CMMD_PERR (1<<6) /* PERR_L out pin parity */ +#define TSI148_PCFS_CMMD_MSTR (1<<2) /* PCI bus master */ +#define TSI148_PCFS_CMMD_MEMSP (1<<1) /* PCI mem space access */ +#define TSI148_PCFS_CMMD_IOSP (1<<0) /* PCI I/O space enable */ + +#define TSI148_PCFS_STAT_RCPVE (1<<15) /* Detected Parity Error */ +#define TSI148_PCFS_STAT_SIGSE (1<<14) /* Signalled System Error */ +#define TSI148_PCFS_STAT_RCVMA (1<<13) /* Received Master Abort */ +#define TSI148_PCFS_STAT_RCVTA (1<<12) /* Received Target Abort */ +#define TSI148_PCFS_STAT_SIGTA (1<<11) /* Signalled Target Abort */ +#define TSI148_PCFS_STAT_SELTIM (3<<9) /* DELSEL Timing */ +#define TSI148_PCFS_STAT_DPAR (1<<8) /* Data Parity Err Reported */ +#define TSI148_PCFS_STAT_FAST (1<<7) /* Fast back-to-back Cap */ +#define TSI148_PCFS_STAT_P66M (1<<5) /* 66 MHz Capable */ +#define TSI148_PCFS_STAT_CAPL (1<<4) /* Capab List - address $34 */ + +/* + * Revision ID/Class Code Registers (CRG +$008) + */ +#define TSI148_PCFS_CLAS_M (0xFF<<24) /* Class ID */ +#define TSI148_PCFS_SUBCLAS_M (0xFF<<16) /* Sub-Class ID */ +#define TSI148_PCFS_PROGIF_M (0xFF<<8) /* Sub-Class ID */ +#define TSI148_PCFS_REVID_M (0xFF<<0) /* Rev ID */ + +/* + * Cache Line Size/ Master Latency Timer/ Header Type Registers (CRG + $00C) + */ +#define TSI148_PCFS_HEAD_M (0xFF<<16) /* Master Lat Timer */ +#define TSI148_PCFS_MLAT_M (0xFF<<8) /* Master Lat Timer */ +#define TSI148_PCFS_CLSZ_M (0xFF<<0) /* Cache Line Size */ + +/* + * Memory Base Address Lower Reg (CRG + $010) + */ +#define TSI148_PCFS_MBARL_BASEL_M (0xFFFFF<<12) /* Base Addr Lower Mask */ +#define TSI148_PCFS_MBARL_PRE (1<<3) /* Prefetch */ +#define TSI148_PCFS_MBARL_MTYPE_M (3<<1) /* Memory Type Mask */ +#define TSI148_PCFS_MBARL_IOMEM (1<<0) /* I/O Space Indicator */ + +/* + * Message Signaled Interrupt Capabilities Register (CRG + $040) + */ +#define TSI148_PCFS_MSICAP_64BAC (1<<7) /* 64-bit Address Capable */ +#define TSI148_PCFS_MSICAP_MME_M (7<<4) /* Multiple Msg Enable Mask */ +#define TSI148_PCFS_MSICAP_MMC_M (7<<1) /* Multiple Msg Capable Mask */ +#define TSI148_PCFS_MSICAP_MSIEN (1<<0) /* Msg signaled INT Enable */ + +/* + * Message Address Lower Register (CRG +$044) + */ +#define TSI148_PCFS_MSIAL_M (0x3FFFFFFF<<2) /* Mask */ + +/* + * Message Data Register (CRG + 4C) + */ +#define TSI148_PCFS_MSIMD_M (0xFFFF<<0) /* Mask */ + +/* + * PCI-X Capabilities Register (CRG + $050) + */ +#define TSI148_PCFS_PCIXCAP_MOST_M (7<<4) /* Max outstanding Split Tran */ +#define TSI148_PCFS_PCIXCAP_MMRBC_M (3<<2) /* Max Mem Read byte cnt */ +#define TSI148_PCFS_PCIXCAP_ERO (1<<1) /* Enable Relaxed Ordering */ +#define TSI148_PCFS_PCIXCAP_DPERE (1<<0) /* Data Parity Recover Enable */ + +/* + * PCI-X Status Register (CRG +$054) + */ +#define TSI148_PCFS_PCIXSTAT_RSCEM (1<<29) /* Received Split Comp Error */ +#define TSI148_PCFS_PCIXSTAT_DMCRS_M (7<<26) /* max Cumulative Read Size */ +#define TSI148_PCFS_PCIXSTAT_DMOST_M (7<<23) /* max outstanding Split Trans + */ +#define TSI148_PCFS_PCIXSTAT_DMMRC_M (3<<21) /* max mem read byte count */ +#define TSI148_PCFS_PCIXSTAT_DC (1<<20) /* Device Complexity */ +#define TSI148_PCFS_PCIXSTAT_USC (1<<19) /* Unexpected Split comp */ +#define TSI148_PCFS_PCIXSTAT_SCD (1<<18) /* Split completion discard */ +#define TSI148_PCFS_PCIXSTAT_133C (1<<17) /* 133MHz capable */ +#define TSI148_PCFS_PCIXSTAT_64D (1<<16) /* 64 bit device */ +#define TSI148_PCFS_PCIXSTAT_BN_M (0xFF<<8) /* Bus number */ +#define TSI148_PCFS_PCIXSTAT_DN_M (0x1F<<3) /* Device number */ +#define TSI148_PCFS_PCIXSTAT_FN_M (7<<0) /* Function Number */ + +/* + * LCSR Registers + */ + +/* + * Outbound Translation Starting Address Lower + */ +#define TSI148_LCSR_OTSAL_M (0xFFFF<<16) /* Mask */ + +/* + * Outbound Translation Ending Address Lower + */ +#define TSI148_LCSR_OTEAL_M (0xFFFF<<16) /* Mask */ + +/* + * Outbound Translation Offset Lower + */ +#define TSI148_LCSR_OTOFFL_M (0xFFFF<<16) /* Mask */ + +/* + * Outbound Translation 2eSST Broadcast Select + */ +#define TSI148_LCSR_OTBS_M (0xFFFFF<<0) /* Mask */ + +/* + * Outbound Translation Attribute + */ +#define TSI148_LCSR_OTAT_EN (1<<31) /* Window Enable */ +#define TSI148_LCSR_OTAT_MRPFD (1<<18) /* Prefetch Disable */ + +#define TSI148_LCSR_OTAT_PFS_M (3<<16) /* Prefetch Size Mask */ +#define TSI148_LCSR_OTAT_PFS_2 (0<<16) /* 2 Cache Lines P Size */ +#define TSI148_LCSR_OTAT_PFS_4 (1<<16) /* 4 Cache Lines P Size */ +#define TSI148_LCSR_OTAT_PFS_8 (2<<16) /* 8 Cache Lines P Size */ +#define TSI148_LCSR_OTAT_PFS_16 (3<<16) /* 16 Cache Lines P Size */ + +#define TSI148_LCSR_OTAT_2eSSTM_M (7<<11) /* 2eSST Xfer Rate Mask */ +#define TSI148_LCSR_OTAT_2eSSTM_160 (0<<11) /* 160MB/s 2eSST Xfer Rate */ +#define TSI148_LCSR_OTAT_2eSSTM_267 (1<<11) /* 267MB/s 2eSST Xfer Rate */ +#define TSI148_LCSR_OTAT_2eSSTM_320 (2<<11) /* 320MB/s 2eSST Xfer Rate */ + +#define TSI148_LCSR_OTAT_TM_M (7<<8) /* Xfer Protocol Mask */ +#define TSI148_LCSR_OTAT_TM_SCT (0<<8) /* SCT Xfer Protocol */ +#define TSI148_LCSR_OTAT_TM_BLT (1<<8) /* BLT Xfer Protocol */ +#define TSI148_LCSR_OTAT_TM_MBLT (2<<8) /* MBLT Xfer Protocol */ +#define TSI148_LCSR_OTAT_TM_2eVME (3<<8) /* 2eVME Xfer Protocol */ +#define TSI148_LCSR_OTAT_TM_2eSST (4<<8) /* 2eSST Xfer Protocol */ +#define TSI148_LCSR_OTAT_TM_2eSSTB (5<<8) /* 2eSST Bcast Xfer Protocol */ + +#define TSI148_LCSR_OTAT_DBW_M (3<<6) /* Max Data Width */ +#define TSI148_LCSR_OTAT_DBW_16 (0<<6) /* 16-bit Data Width */ +#define TSI148_LCSR_OTAT_DBW_32 (1<<6) /* 32-bit Data Width */ + +#define TSI148_LCSR_OTAT_SUP (1<<5) /* Supervisory Access */ +#define TSI148_LCSR_OTAT_PGM (1<<4) /* Program Access */ + +#define TSI148_LCSR_OTAT_AMODE_M (0xf<<0) /* Address Mode Mask */ +#define TSI148_LCSR_OTAT_AMODE_A16 (0<<0) /* A16 Address Space */ +#define TSI148_LCSR_OTAT_AMODE_A24 (1<<0) /* A24 Address Space */ +#define TSI148_LCSR_OTAT_AMODE_A32 (2<<0) /* A32 Address Space */ +#define TSI148_LCSR_OTAT_AMODE_A64 (4<<0) /* A32 Address Space */ +#define TSI148_LCSR_OTAT_AMODE_CRCSR (5<<0) /* CR/CSR Address Space */ +#define TSI148_LCSR_OTAT_AMODE_USER1 (8<<0) /* User1 Address Space */ +#define TSI148_LCSR_OTAT_AMODE_USER2 (9<<0) /* User2 Address Space */ +#define TSI148_LCSR_OTAT_AMODE_USER3 (10<<0) /* User3 Address Space */ +#define TSI148_LCSR_OTAT_AMODE_USER4 (11<<0) /* User4 Address Space */ + +/* + * VME Master Control Register CRG+$234 + */ +#define TSI148_LCSR_VMCTRL_VSA (1<<27) /* VMEbus Stop Ack */ +#define TSI148_LCSR_VMCTRL_VS (1<<26) /* VMEbus Stop */ +#define TSI148_LCSR_VMCTRL_DHB (1<<25) /* Device Has Bus */ +#define TSI148_LCSR_VMCTRL_DWB (1<<24) /* Device Wants Bus */ + +#define TSI148_LCSR_VMCTRL_RMWEN (1<<20) /* RMW Enable */ + +#define TSI148_LCSR_VMCTRL_ATO_M (7<<16) /* Master Access Time-out Mask + */ +#define TSI148_LCSR_VMCTRL_ATO_32 (0<<16) /* 32 us */ +#define TSI148_LCSR_VMCTRL_ATO_128 (1<<16) /* 128 us */ +#define TSI148_LCSR_VMCTRL_ATO_512 (2<<16) /* 512 us */ +#define TSI148_LCSR_VMCTRL_ATO_2M (3<<16) /* 2 ms */ +#define TSI148_LCSR_VMCTRL_ATO_8M (4<<16) /* 8 ms */ +#define TSI148_LCSR_VMCTRL_ATO_32M (5<<16) /* 32 ms */ +#define TSI148_LCSR_VMCTRL_ATO_128M (6<<16) /* 128 ms */ +#define TSI148_LCSR_VMCTRL_ATO_DIS (7<<16) /* Disabled */ + +#define TSI148_LCSR_VMCTRL_VTOFF_M (7<<12) /* VMEbus Master Time off */ +#define TSI148_LCSR_VMCTRL_VTOFF_0 (0<<12) /* 0us */ +#define TSI148_LCSR_VMCTRL_VTOFF_1 (1<<12) /* 1us */ +#define TSI148_LCSR_VMCTRL_VTOFF_2 (2<<12) /* 2us */ +#define TSI148_LCSR_VMCTRL_VTOFF_4 (3<<12) /* 4us */ +#define TSI148_LCSR_VMCTRL_VTOFF_8 (4<<12) /* 8us */ +#define TSI148_LCSR_VMCTRL_VTOFF_16 (5<<12) /* 16us */ +#define TSI148_LCSR_VMCTRL_VTOFF_32 (6<<12) /* 32us */ +#define TSI148_LCSR_VMCTRL_VTOFF_64 (7<<12) /* 64us */ + +#define TSI148_LCSR_VMCTRL_VTON_M (7<<8) /* VMEbus Master Time On */ +#define TSI148_LCSR_VMCTRL_VTON_4 (0<<8) /* 8us */ +#define TSI148_LCSR_VMCTRL_VTON_8 (1<<8) /* 8us */ +#define TSI148_LCSR_VMCTRL_VTON_16 (2<<8) /* 16us */ +#define TSI148_LCSR_VMCTRL_VTON_32 (3<<8) /* 32us */ +#define TSI148_LCSR_VMCTRL_VTON_64 (4<<8) /* 64us */ +#define TSI148_LCSR_VMCTRL_VTON_128 (5<<8) /* 128us */ +#define TSI148_LCSR_VMCTRL_VTON_256 (6<<8) /* 256us */ +#define TSI148_LCSR_VMCTRL_VTON_512 (7<<8) /* 512us */ + +#define TSI148_LCSR_VMCTRL_VREL_M (3<<3) /* VMEbus Master Rel Mode Mask + */ +#define TSI148_LCSR_VMCTRL_VREL_T_D (0<<3) /* Time on or Done */ +#define TSI148_LCSR_VMCTRL_VREL_T_R_D (1<<3) /* Time on and REQ or Done */ +#define TSI148_LCSR_VMCTRL_VREL_T_B_D (2<<3) /* Time on and BCLR or Done */ +#define TSI148_LCSR_VMCTRL_VREL_T_D_R (3<<3) /* Time on or Done and REQ */ + +#define TSI148_LCSR_VMCTRL_VFAIR (1<<2) /* VMEbus Master Fair Mode */ +#define TSI148_LCSR_VMCTRL_VREQL_M (3<<0) /* VMEbus Master Req Level Mask + */ + +/* + * VMEbus Control Register CRG+$238 + */ +#define TSI148_LCSR_VCTRL_LRE (1<<31) /* Late Retry Enable */ + +#define TSI148_LCSR_VCTRL_DLT_M (0xF<<24) /* Deadlock Timer */ +#define TSI148_LCSR_VCTRL_DLT_OFF (0<<24) /* Deadlock Timer Off */ +#define TSI148_LCSR_VCTRL_DLT_16 (1<<24) /* 16 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_32 (2<<24) /* 32 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_64 (3<<24) /* 64 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_128 (4<<24) /* 128 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_256 (5<<24) /* 256 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_512 (6<<24) /* 512 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_1024 (7<<24) /* 1024 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_2048 (8<<24) /* 2048 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_4096 (9<<24) /* 4096 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_8192 (0xA<<24) /* 8192 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_16384 (0xB<<24) /* 16384 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_32768 (0xC<<24) /* 32768 VCLKS */ + +#define TSI148_LCSR_VCTRL_NERBB (1<<20) /* No Early Release of Bus Busy + */ + +#define TSI148_LCSR_VCTRL_SRESET (1<<17) /* System Reset */ +#define TSI148_LCSR_VCTRL_LRESET (1<<16) /* Local Reset */ + +#define TSI148_LCSR_VCTRL_SFAILAI (1<<15) /* SYSFAIL Auto Slot ID */ +#define TSI148_LCSR_VCTRL_BID_M (0x1F<<8) /* Broadcast ID Mask */ + +#define TSI148_LCSR_VCTRL_ATOEN (1<<7) /* Arbiter Time-out Enable */ +#define TSI148_LCSR_VCTRL_ROBIN (1<<6) /* VMEbus Round Robin */ + +#define TSI148_LCSR_VCTRL_GTO_M (7<<0) /* VMEbus Global Time-out Mask + */ +#define TSI148_LCSR_VCTRL_GTO_8 (0<<0) /* 8 us */ +#define TSI148_LCSR_VCTRL_GTO_16 (1<<0) /* 16 us */ +#define TSI148_LCSR_VCTRL_GTO_32 (2<<0) /* 32 us */ +#define TSI148_LCSR_VCTRL_GTO_64 (3<<0) /* 64 us */ +#define TSI148_LCSR_VCTRL_GTO_128 (4<<0) /* 128 us */ +#define TSI148_LCSR_VCTRL_GTO_256 (5<<0) /* 256 us */ +#define TSI148_LCSR_VCTRL_GTO_512 (6<<0) /* 512 us */ +#define TSI148_LCSR_VCTRL_GTO_DIS (7<<0) /* Disabled */ + +/* + * VMEbus Status Register CRG + $23C + */ +#define TSI148_LCSR_VSTAT_CPURST (1<<15) /* Clear power up reset */ +#define TSI148_LCSR_VSTAT_BRDFL (1<<14) /* Board fail */ +#define TSI148_LCSR_VSTAT_PURSTS (1<<12) /* Power up reset status */ +#define TSI148_LCSR_VSTAT_BDFAILS (1<<11) /* Board Fail Status */ +#define TSI148_LCSR_VSTAT_SYSFAILS (1<<10) /* System Fail Status */ +#define TSI148_LCSR_VSTAT_ACFAILS (1<<9) /* AC fail status */ +#define TSI148_LCSR_VSTAT_SCONS (1<<8) /* System Cont Status */ +#define TSI148_LCSR_VSTAT_GAP (1<<5) /* Geographic Addr Parity */ +#define TSI148_LCSR_VSTAT_GA_M (0x1F<<0) /* Geographic Addr Mask */ + +/* + * PCI Configuration Status Register CRG+$240 + */ +#define TSI148_LCSR_PSTAT_REQ64S (1<<6) /* Request 64 status set */ +#define TSI148_LCSR_PSTAT_M66ENS (1<<5) /* M66ENS 66Mhz enable */ +#define TSI148_LCSR_PSTAT_FRAMES (1<<4) /* Frame Status */ +#define TSI148_LCSR_PSTAT_IRDYS (1<<3) /* IRDY status */ +#define TSI148_LCSR_PSTAT_DEVSELS (1<<2) /* DEVL status */ +#define TSI148_LCSR_PSTAT_STOPS (1<<1) /* STOP status */ +#define TSI148_LCSR_PSTAT_TRDYS (1<<0) /* TRDY status */ + +/* + * VMEbus Exception Attributes Register CRG + $268 + */ +#define TSI148_LCSR_VEAT_VES (1<<31) /* Status */ +#define TSI148_LCSR_VEAT_VEOF (1<<30) /* Overflow */ +#define TSI148_LCSR_VEAT_VESCL (1<<29) /* Status Clear */ +#define TSI148_LCSR_VEAT_2EOT (1<<21) /* 2e Odd Termination */ +#define TSI148_LCSR_VEAT_2EST (1<<20) /* 2e Slave terminated */ +#define TSI148_LCSR_VEAT_BERR (1<<19) /* Bus Error */ +#define TSI148_LCSR_VEAT_LWORD (1<<18) /* LWORD_ signal state */ +#define TSI148_LCSR_VEAT_WRITE (1<<17) /* WRITE_ signal state */ +#define TSI148_LCSR_VEAT_IACK (1<<16) /* IACK_ signal state */ +#define TSI148_LCSR_VEAT_DS1 (1<<15) /* DS1_ signal state */ +#define TSI148_LCSR_VEAT_DS0 (1<<14) /* DS0_ signal state */ +#define TSI148_LCSR_VEAT_AM_M (0x3F<<8) /* Address Mode Mask */ +#define TSI148_LCSR_VEAT_XAM_M (0xFF<<0) /* Master AMode Mask */ + + +/* + * VMEbus PCI Error Diagnostics PCI/X Attributes Register CRG + $280 + */ +#define TSI148_LCSR_EDPAT_EDPCL (1<<29) + +/* + * Inbound Translation Starting Address Lower + */ +#define TSI148_LCSR_ITSAL6432_M (0xFFFF<<16) /* Mask */ +#define TSI148_LCSR_ITSAL24_M (0x00FFF<<12) /* Mask */ +#define TSI148_LCSR_ITSAL16_M (0x0000FFF<<4) /* Mask */ + +/* + * Inbound Translation Ending Address Lower + */ +#define TSI148_LCSR_ITEAL6432_M (0xFFFF<<16) /* Mask */ +#define TSI148_LCSR_ITEAL24_M (0x00FFF<<12) /* Mask */ +#define TSI148_LCSR_ITEAL16_M (0x0000FFF<<4) /* Mask */ + +/* + * Inbound Translation Offset Lower + */ +#define TSI148_LCSR_ITOFFL6432_M (0xFFFF<<16) /* Mask */ +#define TSI148_LCSR_ITOFFL24_M (0xFFFFF<<12) /* Mask */ +#define TSI148_LCSR_ITOFFL16_M (0xFFFFFFF<<4) /* Mask */ + +/* + * Inbound Translation Attribute + */ +#define TSI148_LCSR_ITAT_EN (1<<31) /* Window Enable */ +#define TSI148_LCSR_ITAT_TH (1<<18) /* Prefetch Threshold */ + +#define TSI148_LCSR_ITAT_VFS_M (3<<16) /* Virtual FIFO Size Mask */ +#define TSI148_LCSR_ITAT_VFS_64 (0<<16) /* 64 bytes Virtual FIFO Size */ +#define TSI148_LCSR_ITAT_VFS_128 (1<<16) /* 128 bytes Virtual FIFO Sz */ +#define TSI148_LCSR_ITAT_VFS_256 (2<<16) /* 256 bytes Virtual FIFO Sz */ +#define TSI148_LCSR_ITAT_VFS_512 (3<<16) /* 512 bytes Virtual FIFO Sz */ + +#define TSI148_LCSR_ITAT_2eSSTM_M (7<<12) /* 2eSST Xfer Rate Mask */ +#define TSI148_LCSR_ITAT_2eSSTM_160 (0<<12) /* 160MB/s 2eSST Xfer Rate */ +#define TSI148_LCSR_ITAT_2eSSTM_267 (1<<12) /* 267MB/s 2eSST Xfer Rate */ +#define TSI148_LCSR_ITAT_2eSSTM_320 (2<<12) /* 320MB/s 2eSST Xfer Rate */ + +#define TSI148_LCSR_ITAT_2eSSTB (1<<11) /* 2eSST Bcast Xfer Protocol */ +#define TSI148_LCSR_ITAT_2eSST (1<<10) /* 2eSST Xfer Protocol */ +#define TSI148_LCSR_ITAT_2eVME (1<<9) /* 2eVME Xfer Protocol */ +#define TSI148_LCSR_ITAT_MBLT (1<<8) /* MBLT Xfer Protocol */ +#define TSI148_LCSR_ITAT_BLT (1<<7) /* BLT Xfer Protocol */ + +#define TSI148_LCSR_ITAT_AS_M (7<<4) /* Address Space Mask */ +#define TSI148_LCSR_ITAT_AS_A16 (0<<4) /* A16 Address Space */ +#define TSI148_LCSR_ITAT_AS_A24 (1<<4) /* A24 Address Space */ +#define TSI148_LCSR_ITAT_AS_A32 (2<<4) /* A32 Address Space */ +#define TSI148_LCSR_ITAT_AS_A64 (4<<4) /* A64 Address Space */ + +#define TSI148_LCSR_ITAT_SUPR (1<<3) /* Supervisor Access */ +#define TSI148_LCSR_ITAT_NPRIV (1<<2) /* Non-Priv (User) Access */ +#define TSI148_LCSR_ITAT_PGM (1<<1) /* Program Access */ +#define TSI148_LCSR_ITAT_DATA (1<<0) /* Data Access */ + +/* + * GCSR Base Address Lower Address CRG +$404 + */ +#define TSI148_LCSR_GBAL_M (0x7FFFFFF<<5) /* Mask */ + +/* + * GCSR Attribute Register CRG + $408 + */ +#define TSI148_LCSR_GCSRAT_EN (1<<7) /* Enable access to GCSR */ + +#define TSI148_LCSR_GCSRAT_AS_M (7<<4) /* Address Space Mask */ +#define TSI148_LCSR_GCSRAT_AS_A16 (0<<4) /* Address Space 16 */ +#define TSI148_LCSR_GCSRAT_AS_A24 (1<<4) /* Address Space 24 */ +#define TSI148_LCSR_GCSRAT_AS_A32 (2<<4) /* Address Space 32 */ +#define TSI148_LCSR_GCSRAT_AS_A64 (4<<4) /* Address Space 64 */ + +#define TSI148_LCSR_GCSRAT_SUPR (1<<3) /* Sup set -GCSR decoder */ +#define TSI148_LCSR_GCSRAT_NPRIV (1<<2) /* Non-Privliged set - CGSR */ +#define TSI148_LCSR_GCSRAT_PGM (1<<1) /* Program set - GCSR decoder */ +#define TSI148_LCSR_GCSRAT_DATA (1<<0) /* DATA set GCSR decoder */ + +/* + * CRG Base Address Lower Address CRG + $410 + */ +#define TSI148_LCSR_CBAL_M (0xFFFFF<<12) + +/* + * CRG Attribute Register CRG + $414 + */ +#define TSI148_LCSR_CRGAT_EN (1<<7) /* Enable PRG Access */ + +#define TSI148_LCSR_CRGAT_AS_M (7<<4) /* Address Space */ +#define TSI148_LCSR_CRGAT_AS_A16 (0<<4) /* Address Space 16 */ +#define TSI148_LCSR_CRGAT_AS_A24 (1<<4) /* Address Space 24 */ +#define TSI148_LCSR_CRGAT_AS_A32 (2<<4) /* Address Space 32 */ +#define TSI148_LCSR_CRGAT_AS_A64 (4<<4) /* Address Space 64 */ + +#define TSI148_LCSR_CRGAT_SUPR (1<<3) /* Supervisor Access */ +#define TSI148_LCSR_CRGAT_NPRIV (1<<2) /* Non-Privliged(User) Access */ +#define TSI148_LCSR_CRGAT_PGM (1<<1) /* Program Access */ +#define TSI148_LCSR_CRGAT_DATA (1<<0) /* Data Access */ + +/* + * CR/CSR Offset Lower Register CRG + $41C + */ +#define TSI148_LCSR_CROL_M (0x1FFF<<19) /* Mask */ + +/* + * CR/CSR Attribute register CRG + $420 + */ +#define TSI148_LCSR_CRAT_EN (1<<7) /* Enable access to CR/CSR */ + +/* + * Location Monitor base address lower register CRG + $428 + */ +#define TSI148_LCSR_LMBAL_M (0x7FFFFFF<<5) /* Mask */ + +/* + * Location Monitor Attribute Register CRG + $42C + */ +#define TSI148_LCSR_LMAT_EN (1<<7) /* Enable Location Monitor */ + +#define TSI148_LCSR_LMAT_AS_M (7<<4) /* Address Space MASK */ +#define TSI148_LCSR_LMAT_AS_A16 (0<<4) /* A16 */ +#define TSI148_LCSR_LMAT_AS_A24 (1<<4) /* A24 */ +#define TSI148_LCSR_LMAT_AS_A32 (2<<4) /* A32 */ +#define TSI148_LCSR_LMAT_AS_A64 (4<<4) /* A64 */ + +#define TSI148_LCSR_LMAT_SUPR (1<<3) /* Supervisor Access */ +#define TSI148_LCSR_LMAT_NPRIV (1<<2) /* Non-Priv (User) Access */ +#define TSI148_LCSR_LMAT_PGM (1<<1) /* Program Access */ +#define TSI148_LCSR_LMAT_DATA (1<<0) /* Data Access */ + +/* + * Broadcast Pulse Generator Timer Register CRG + $438 + */ +#define TSI148_LCSR_BPGTR_BPGT_M (0xFFFF<<0) /* Mask */ + +/* + * Broadcast Programmable Clock Timer Register CRG + $43C + */ +#define TSI148_LCSR_BPCTR_BPCT_M (0xFFFFFF<<0) /* Mask */ + +/* + * VMEbus Interrupt Control Register CRG + $43C + */ +#define TSI148_LCSR_VICR_CNTS_M (3<<22) /* Cntr Source MASK */ +#define TSI148_LCSR_VICR_CNTS_DIS (1<<22) /* Cntr Disable */ +#define TSI148_LCSR_VICR_CNTS_IRQ1 (2<<22) /* IRQ1 to Cntr */ +#define TSI148_LCSR_VICR_CNTS_IRQ2 (3<<22) /* IRQ2 to Cntr */ + +#define TSI148_LCSR_VICR_EDGIS_M (3<<20) /* Edge interrupt MASK */ +#define TSI148_LCSR_VICR_EDGIS_DIS (1<<20) /* Edge interrupt Disable */ +#define TSI148_LCSR_VICR_EDGIS_IRQ1 (2<<20) /* IRQ1 to Edge */ +#define TSI148_LCSR_VICR_EDGIS_IRQ2 (3<<20) /* IRQ2 to Edge */ + +#define TSI148_LCSR_VICR_IRQIF_M (3<<18) /* IRQ1* Function MASK */ +#define TSI148_LCSR_VICR_IRQIF_NORM (1<<18) /* Normal */ +#define TSI148_LCSR_VICR_IRQIF_PULSE (2<<18) /* Pulse Generator */ +#define TSI148_LCSR_VICR_IRQIF_PROG (3<<18) /* Programmable Clock */ +#define TSI148_LCSR_VICR_IRQIF_1U (4<<18) /* 1us Clock */ + +#define TSI148_LCSR_VICR_IRQ2F_M (3<<16) /* IRQ2* Function MASK */ +#define TSI148_LCSR_VICR_IRQ2F_NORM (1<<16) /* Normal */ +#define TSI148_LCSR_VICR_IRQ2F_PULSE (2<<16) /* Pulse Generator */ +#define TSI148_LCSR_VICR_IRQ2F_PROG (3<<16) /* Programmable Clock */ +#define TSI148_LCSR_VICR_IRQ2F_1U (4<<16) /* 1us Clock */ + +#define TSI148_LCSR_VICR_BIP (1<<15) /* Broadcast Interrupt Pulse */ + +#define TSI148_LCSR_VICR_IRQC (1<<12) /* VMEbus IRQ Clear */ +#define TSI148_LCSR_VICR_IRQS (1<<11) /* VMEbus IRQ Status */ + +#define TSI148_LCSR_VICR_IRQL_M (7<<8) /* VMEbus SW IRQ Level Mask */ +#define TSI148_LCSR_VICR_IRQL_1 (1<<8) /* VMEbus SW IRQ Level 1 */ +#define TSI148_LCSR_VICR_IRQL_2 (2<<8) /* VMEbus SW IRQ Level 2 */ +#define TSI148_LCSR_VICR_IRQL_3 (3<<8) /* VMEbus SW IRQ Level 3 */ +#define TSI148_LCSR_VICR_IRQL_4 (4<<8) /* VMEbus SW IRQ Level 4 */ +#define TSI148_LCSR_VICR_IRQL_5 (5<<8) /* VMEbus SW IRQ Level 5 */ +#define TSI148_LCSR_VICR_IRQL_6 (6<<8) /* VMEbus SW IRQ Level 6 */ +#define TSI148_LCSR_VICR_IRQL_7 (7<<8) /* VMEbus SW IRQ Level 7 */ + +static const int TSI148_LCSR_VICR_IRQL[8] = { 0, TSI148_LCSR_VICR_IRQL_1, + TSI148_LCSR_VICR_IRQL_2, TSI148_LCSR_VICR_IRQL_3, + TSI148_LCSR_VICR_IRQL_4, TSI148_LCSR_VICR_IRQL_5, + TSI148_LCSR_VICR_IRQL_6, TSI148_LCSR_VICR_IRQL_7 }; + +#define TSI148_LCSR_VICR_STID_M (0xFF<<0) /* Status/ID Mask */ + +/* + * Interrupt Enable Register CRG + $440 + */ +#define TSI148_LCSR_INTEN_DMA1EN (1<<25) /* DMAC 1 */ +#define TSI148_LCSR_INTEN_DMA0EN (1<<24) /* DMAC 0 */ +#define TSI148_LCSR_INTEN_LM3EN (1<<23) /* Location Monitor 3 */ +#define TSI148_LCSR_INTEN_LM2EN (1<<22) /* Location Monitor 2 */ +#define TSI148_LCSR_INTEN_LM1EN (1<<21) /* Location Monitor 1 */ +#define TSI148_LCSR_INTEN_LM0EN (1<<20) /* Location Monitor 0 */ +#define TSI148_LCSR_INTEN_MB3EN (1<<19) /* Mail Box 3 */ +#define TSI148_LCSR_INTEN_MB2EN (1<<18) /* Mail Box 2 */ +#define TSI148_LCSR_INTEN_MB1EN (1<<17) /* Mail Box 1 */ +#define TSI148_LCSR_INTEN_MB0EN (1<<16) /* Mail Box 0 */ +#define TSI148_LCSR_INTEN_PERREN (1<<13) /* PCI/X Error */ +#define TSI148_LCSR_INTEN_VERREN (1<<12) /* VMEbus Error */ +#define TSI148_LCSR_INTEN_VIEEN (1<<11) /* VMEbus IRQ Edge */ +#define TSI148_LCSR_INTEN_IACKEN (1<<10) /* IACK */ +#define TSI148_LCSR_INTEN_SYSFLEN (1<<9) /* System Fail */ +#define TSI148_LCSR_INTEN_ACFLEN (1<<8) /* AC Fail */ +#define TSI148_LCSR_INTEN_IRQ7EN (1<<7) /* IRQ7 */ +#define TSI148_LCSR_INTEN_IRQ6EN (1<<6) /* IRQ6 */ +#define TSI148_LCSR_INTEN_IRQ5EN (1<<5) /* IRQ5 */ +#define TSI148_LCSR_INTEN_IRQ4EN (1<<4) /* IRQ4 */ +#define TSI148_LCSR_INTEN_IRQ3EN (1<<3) /* IRQ3 */ +#define TSI148_LCSR_INTEN_IRQ2EN (1<<2) /* IRQ2 */ +#define TSI148_LCSR_INTEN_IRQ1EN (1<<1) /* IRQ1 */ + +static const int TSI148_LCSR_INTEN_LMEN[4] = { TSI148_LCSR_INTEN_LM0EN, + TSI148_LCSR_INTEN_LM1EN, + TSI148_LCSR_INTEN_LM2EN, + TSI148_LCSR_INTEN_LM3EN }; + +static const int TSI148_LCSR_INTEN_IRQEN[7] = { TSI148_LCSR_INTEN_IRQ1EN, + TSI148_LCSR_INTEN_IRQ2EN, + TSI148_LCSR_INTEN_IRQ3EN, + TSI148_LCSR_INTEN_IRQ4EN, + TSI148_LCSR_INTEN_IRQ5EN, + TSI148_LCSR_INTEN_IRQ6EN, + TSI148_LCSR_INTEN_IRQ7EN }; + +/* + * Interrupt Enable Out Register CRG + $444 + */ +#define TSI148_LCSR_INTEO_DMA1EO (1<<25) /* DMAC 1 */ +#define TSI148_LCSR_INTEO_DMA0EO (1<<24) /* DMAC 0 */ +#define TSI148_LCSR_INTEO_LM3EO (1<<23) /* Loc Monitor 3 */ +#define TSI148_LCSR_INTEO_LM2EO (1<<22) /* Loc Monitor 2 */ +#define TSI148_LCSR_INTEO_LM1EO (1<<21) /* Loc Monitor 1 */ +#define TSI148_LCSR_INTEO_LM0EO (1<<20) /* Location Monitor 0 */ +#define TSI148_LCSR_INTEO_MB3EO (1<<19) /* Mail Box 3 */ +#define TSI148_LCSR_INTEO_MB2EO (1<<18) /* Mail Box 2 */ +#define TSI148_LCSR_INTEO_MB1EO (1<<17) /* Mail Box 1 */ +#define TSI148_LCSR_INTEO_MB0EO (1<<16) /* Mail Box 0 */ +#define TSI148_LCSR_INTEO_PERREO (1<<13) /* PCI/X Error */ +#define TSI148_LCSR_INTEO_VERREO (1<<12) /* VMEbus Error */ +#define TSI148_LCSR_INTEO_VIEEO (1<<11) /* VMEbus IRQ Edge */ +#define TSI148_LCSR_INTEO_IACKEO (1<<10) /* IACK */ +#define TSI148_LCSR_INTEO_SYSFLEO (1<<9) /* System Fail */ +#define TSI148_LCSR_INTEO_ACFLEO (1<<8) /* AC Fail */ +#define TSI148_LCSR_INTEO_IRQ7EO (1<<7) /* IRQ7 */ +#define TSI148_LCSR_INTEO_IRQ6EO (1<<6) /* IRQ6 */ +#define TSI148_LCSR_INTEO_IRQ5EO (1<<5) /* IRQ5 */ +#define TSI148_LCSR_INTEO_IRQ4EO (1<<4) /* IRQ4 */ +#define TSI148_LCSR_INTEO_IRQ3EO (1<<3) /* IRQ3 */ +#define TSI148_LCSR_INTEO_IRQ2EO (1<<2) /* IRQ2 */ +#define TSI148_LCSR_INTEO_IRQ1EO (1<<1) /* IRQ1 */ + +static const int TSI148_LCSR_INTEO_LMEO[4] = { TSI148_LCSR_INTEO_LM0EO, + TSI148_LCSR_INTEO_LM1EO, + TSI148_LCSR_INTEO_LM2EO, + TSI148_LCSR_INTEO_LM3EO }; + +static const int TSI148_LCSR_INTEO_IRQEO[7] = { TSI148_LCSR_INTEO_IRQ1EO, + TSI148_LCSR_INTEO_IRQ2EO, + TSI148_LCSR_INTEO_IRQ3EO, + TSI148_LCSR_INTEO_IRQ4EO, + TSI148_LCSR_INTEO_IRQ5EO, + TSI148_LCSR_INTEO_IRQ6EO, + TSI148_LCSR_INTEO_IRQ7EO }; + +/* + * Interrupt Status Register CRG + $448 + */ +#define TSI148_LCSR_INTS_DMA1S (1<<25) /* DMA 1 */ +#define TSI148_LCSR_INTS_DMA0S (1<<24) /* DMA 0 */ +#define TSI148_LCSR_INTS_LM3S (1<<23) /* Location Monitor 3 */ +#define TSI148_LCSR_INTS_LM2S (1<<22) /* Location Monitor 2 */ +#define TSI148_LCSR_INTS_LM1S (1<<21) /* Location Monitor 1 */ +#define TSI148_LCSR_INTS_LM0S (1<<20) /* Location Monitor 0 */ +#define TSI148_LCSR_INTS_MB3S (1<<19) /* Mail Box 3 */ +#define TSI148_LCSR_INTS_MB2S (1<<18) /* Mail Box 2 */ +#define TSI148_LCSR_INTS_MB1S (1<<17) /* Mail Box 1 */ +#define TSI148_LCSR_INTS_MB0S (1<<16) /* Mail Box 0 */ +#define TSI148_LCSR_INTS_PERRS (1<<13) /* PCI/X Error */ +#define TSI148_LCSR_INTS_VERRS (1<<12) /* VMEbus Error */ +#define TSI148_LCSR_INTS_VIES (1<<11) /* VMEbus IRQ Edge */ +#define TSI148_LCSR_INTS_IACKS (1<<10) /* IACK */ +#define TSI148_LCSR_INTS_SYSFLS (1<<9) /* System Fail */ +#define TSI148_LCSR_INTS_ACFLS (1<<8) /* AC Fail */ +#define TSI148_LCSR_INTS_IRQ7S (1<<7) /* IRQ7 */ +#define TSI148_LCSR_INTS_IRQ6S (1<<6) /* IRQ6 */ +#define TSI148_LCSR_INTS_IRQ5S (1<<5) /* IRQ5 */ +#define TSI148_LCSR_INTS_IRQ4S (1<<4) /* IRQ4 */ +#define TSI148_LCSR_INTS_IRQ3S (1<<3) /* IRQ3 */ +#define TSI148_LCSR_INTS_IRQ2S (1<<2) /* IRQ2 */ +#define TSI148_LCSR_INTS_IRQ1S (1<<1) /* IRQ1 */ + +static const int TSI148_LCSR_INTS_LMS[4] = { TSI148_LCSR_INTS_LM0S, + TSI148_LCSR_INTS_LM1S, + TSI148_LCSR_INTS_LM2S, + TSI148_LCSR_INTS_LM3S }; + +static const int TSI148_LCSR_INTS_MBS[4] = { TSI148_LCSR_INTS_MB0S, + TSI148_LCSR_INTS_MB1S, + TSI148_LCSR_INTS_MB2S, + TSI148_LCSR_INTS_MB3S }; + +/* + * Interrupt Clear Register CRG + $44C + */ +#define TSI148_LCSR_INTC_DMA1C (1<<25) /* DMA 1 */ +#define TSI148_LCSR_INTC_DMA0C (1<<24) /* DMA 0 */ +#define TSI148_LCSR_INTC_LM3C (1<<23) /* Location Monitor 3 */ +#define TSI148_LCSR_INTC_LM2C (1<<22) /* Location Monitor 2 */ +#define TSI148_LCSR_INTC_LM1C (1<<21) /* Location Monitor 1 */ +#define TSI148_LCSR_INTC_LM0C (1<<20) /* Location Monitor 0 */ +#define TSI148_LCSR_INTC_MB3C (1<<19) /* Mail Box 3 */ +#define TSI148_LCSR_INTC_MB2C (1<<18) /* Mail Box 2 */ +#define TSI148_LCSR_INTC_MB1C (1<<17) /* Mail Box 1 */ +#define TSI148_LCSR_INTC_MB0C (1<<16) /* Mail Box 0 */ +#define TSI148_LCSR_INTC_PERRC (1<<13) /* VMEbus Error */ +#define TSI148_LCSR_INTC_VERRC (1<<12) /* VMEbus Access Time-out */ +#define TSI148_LCSR_INTC_VIEC (1<<11) /* VMEbus IRQ Edge */ +#define TSI148_LCSR_INTC_IACKC (1<<10) /* IACK */ +#define TSI148_LCSR_INTC_SYSFLC (1<<9) /* System Fail */ +#define TSI148_LCSR_INTC_ACFLC (1<<8) /* AC Fail */ + +static const int TSI148_LCSR_INTC_LMC[4] = { TSI148_LCSR_INTC_LM0C, + TSI148_LCSR_INTC_LM1C, + TSI148_LCSR_INTC_LM2C, + TSI148_LCSR_INTC_LM3C }; + +static const int TSI148_LCSR_INTC_MBC[4] = { TSI148_LCSR_INTC_MB0C, + TSI148_LCSR_INTC_MB1C, + TSI148_LCSR_INTC_MB2C, + TSI148_LCSR_INTC_MB3C }; + +/* + * Interrupt Map Register 1 CRG + $458 + */ +#define TSI148_LCSR_INTM1_DMA1M_M (3<<18) /* DMA 1 */ +#define TSI148_LCSR_INTM1_DMA0M_M (3<<16) /* DMA 0 */ +#define TSI148_LCSR_INTM1_LM3M_M (3<<14) /* Location Monitor 3 */ +#define TSI148_LCSR_INTM1_LM2M_M (3<<12) /* Location Monitor 2 */ +#define TSI148_LCSR_INTM1_LM1M_M (3<<10) /* Location Monitor 1 */ +#define TSI148_LCSR_INTM1_LM0M_M (3<<8) /* Location Monitor 0 */ +#define TSI148_LCSR_INTM1_MB3M_M (3<<6) /* Mail Box 3 */ +#define TSI148_LCSR_INTM1_MB2M_M (3<<4) /* Mail Box 2 */ +#define TSI148_LCSR_INTM1_MB1M_M (3<<2) /* Mail Box 1 */ +#define TSI148_LCSR_INTM1_MB0M_M (3<<0) /* Mail Box 0 */ + +/* + * Interrupt Map Register 2 CRG + $45C + */ +#define TSI148_LCSR_INTM2_PERRM_M (3<<26) /* PCI Bus Error */ +#define TSI148_LCSR_INTM2_VERRM_M (3<<24) /* VMEbus Error */ +#define TSI148_LCSR_INTM2_VIEM_M (3<<22) /* VMEbus IRQ Edge */ +#define TSI148_LCSR_INTM2_IACKM_M (3<<20) /* IACK */ +#define TSI148_LCSR_INTM2_SYSFLM_M (3<<18) /* System Fail */ +#define TSI148_LCSR_INTM2_ACFLM_M (3<<16) /* AC Fail */ +#define TSI148_LCSR_INTM2_IRQ7M_M (3<<14) /* IRQ7 */ +#define TSI148_LCSR_INTM2_IRQ6M_M (3<<12) /* IRQ6 */ +#define TSI148_LCSR_INTM2_IRQ5M_M (3<<10) /* IRQ5 */ +#define TSI148_LCSR_INTM2_IRQ4M_M (3<<8) /* IRQ4 */ +#define TSI148_LCSR_INTM2_IRQ3M_M (3<<6) /* IRQ3 */ +#define TSI148_LCSR_INTM2_IRQ2M_M (3<<4) /* IRQ2 */ +#define TSI148_LCSR_INTM2_IRQ1M_M (3<<2) /* IRQ1 */ + +/* + * DMA Control (0-1) Registers CRG + $500 + */ +#define TSI148_LCSR_DCTL_ABT (1<<27) /* Abort */ +#define TSI148_LCSR_DCTL_PAU (1<<26) /* Pause */ +#define TSI148_LCSR_DCTL_DGO (1<<25) /* DMA Go */ + +#define TSI148_LCSR_DCTL_MOD (1<<23) /* Mode */ + +#define TSI148_LCSR_DCTL_VBKS_M (7<<12) /* VMEbus block Size MASK */ +#define TSI148_LCSR_DCTL_VBKS_32 (0<<12) /* VMEbus block Size 32 */ +#define TSI148_LCSR_DCTL_VBKS_64 (1<<12) /* VMEbus block Size 64 */ +#define TSI148_LCSR_DCTL_VBKS_128 (2<<12) /* VMEbus block Size 128 */ +#define TSI148_LCSR_DCTL_VBKS_256 (3<<12) /* VMEbus block Size 256 */ +#define TSI148_LCSR_DCTL_VBKS_512 (4<<12) /* VMEbus block Size 512 */ +#define TSI148_LCSR_DCTL_VBKS_1024 (5<<12) /* VMEbus block Size 1024 */ +#define TSI148_LCSR_DCTL_VBKS_2048 (6<<12) /* VMEbus block Size 2048 */ +#define TSI148_LCSR_DCTL_VBKS_4096 (7<<12) /* VMEbus block Size 4096 */ + +#define TSI148_LCSR_DCTL_VBOT_M (7<<8) /* VMEbus back-off MASK */ +#define TSI148_LCSR_DCTL_VBOT_0 (0<<8) /* VMEbus back-off 0us */ +#define TSI148_LCSR_DCTL_VBOT_1 (1<<8) /* VMEbus back-off 1us */ +#define TSI148_LCSR_DCTL_VBOT_2 (2<<8) /* VMEbus back-off 2us */ +#define TSI148_LCSR_DCTL_VBOT_4 (3<<8) /* VMEbus back-off 4us */ +#define TSI148_LCSR_DCTL_VBOT_8 (4<<8) /* VMEbus back-off 8us */ +#define TSI148_LCSR_DCTL_VBOT_16 (5<<8) /* VMEbus back-off 16us */ +#define TSI148_LCSR_DCTL_VBOT_32 (6<<8) /* VMEbus back-off 32us */ +#define TSI148_LCSR_DCTL_VBOT_64 (7<<8) /* VMEbus back-off 64us */ + +#define TSI148_LCSR_DCTL_PBKS_M (7<<4) /* PCI block size MASK */ +#define TSI148_LCSR_DCTL_PBKS_32 (0<<4) /* PCI block size 32 bytes */ +#define TSI148_LCSR_DCTL_PBKS_64 (1<<4) /* PCI block size 64 bytes */ +#define TSI148_LCSR_DCTL_PBKS_128 (2<<4) /* PCI block size 128 bytes */ +#define TSI148_LCSR_DCTL_PBKS_256 (3<<4) /* PCI block size 256 bytes */ +#define TSI148_LCSR_DCTL_PBKS_512 (4<<4) /* PCI block size 512 bytes */ +#define TSI148_LCSR_DCTL_PBKS_1024 (5<<4) /* PCI block size 1024 bytes */ +#define TSI148_LCSR_DCTL_PBKS_2048 (6<<4) /* PCI block size 2048 bytes */ +#define TSI148_LCSR_DCTL_PBKS_4096 (7<<4) /* PCI block size 4096 bytes */ + +#define TSI148_LCSR_DCTL_PBOT_M (7<<0) /* PCI back off MASK */ +#define TSI148_LCSR_DCTL_PBOT_0 (0<<0) /* PCI back off 0us */ +#define TSI148_LCSR_DCTL_PBOT_1 (1<<0) /* PCI back off 1us */ +#define TSI148_LCSR_DCTL_PBOT_2 (2<<0) /* PCI back off 2us */ +#define TSI148_LCSR_DCTL_PBOT_4 (3<<0) /* PCI back off 3us */ +#define TSI148_LCSR_DCTL_PBOT_8 (4<<0) /* PCI back off 4us */ +#define TSI148_LCSR_DCTL_PBOT_16 (5<<0) /* PCI back off 8us */ +#define TSI148_LCSR_DCTL_PBOT_32 (6<<0) /* PCI back off 16us */ +#define TSI148_LCSR_DCTL_PBOT_64 (7<<0) /* PCI back off 32us */ + +/* + * DMA Status Registers (0-1) CRG + $504 + */ +#define TSI148_LCSR_DSTA_SMA (1<<31) /* PCI Signalled Master Abt */ +#define TSI148_LCSR_DSTA_RTA (1<<30) /* PCI Received Target Abt */ +#define TSI148_LCSR_DSTA_MRC (1<<29) /* PCI Max Retry Count */ +#define TSI148_LCSR_DSTA_VBE (1<<28) /* VMEbus error */ +#define TSI148_LCSR_DSTA_ABT (1<<27) /* Abort */ +#define TSI148_LCSR_DSTA_PAU (1<<26) /* Pause */ +#define TSI148_LCSR_DSTA_DON (1<<25) /* Done */ +#define TSI148_LCSR_DSTA_BSY (1<<24) /* Busy */ + +/* + * DMA Current Link Address Lower (0-1) + */ +#define TSI148_LCSR_DCLAL_M (0x3FFFFFF<<6) /* Mask */ + +/* + * DMA Source Attribute (0-1) Reg + */ +#define TSI148_LCSR_DSAT_TYP_M (3<<28) /* Source Bus Type */ +#define TSI148_LCSR_DSAT_TYP_PCI (0<<28) /* PCI Bus */ +#define TSI148_LCSR_DSAT_TYP_VME (1<<28) /* VMEbus */ +#define TSI148_LCSR_DSAT_TYP_PAT (2<<28) /* Data Pattern */ + +#define TSI148_LCSR_DSAT_PSZ (1<<25) /* Pattern Size */ +#define TSI148_LCSR_DSAT_NIN (1<<24) /* No Increment */ + +#define TSI148_LCSR_DSAT_2eSSTM_M (3<<11) /* 2eSST Trans Rate Mask */ +#define TSI148_LCSR_DSAT_2eSSTM_160 (0<<11) /* 160 MB/s */ +#define TSI148_LCSR_DSAT_2eSSTM_267 (1<<11) /* 267 MB/s */ +#define TSI148_LCSR_DSAT_2eSSTM_320 (2<<11) /* 320 MB/s */ + +#define TSI148_LCSR_DSAT_TM_M (7<<8) /* Bus Transfer Protocol Mask */ +#define TSI148_LCSR_DSAT_TM_SCT (0<<8) /* SCT */ +#define TSI148_LCSR_DSAT_TM_BLT (1<<8) /* BLT */ +#define TSI148_LCSR_DSAT_TM_MBLT (2<<8) /* MBLT */ +#define TSI148_LCSR_DSAT_TM_2eVME (3<<8) /* 2eVME */ +#define TSI148_LCSR_DSAT_TM_2eSST (4<<8) /* 2eSST */ +#define TSI148_LCSR_DSAT_TM_2eSSTB (5<<8) /* 2eSST Broadcast */ + +#define TSI148_LCSR_DSAT_DBW_M (3<<6) /* Max Data Width MASK */ +#define TSI148_LCSR_DSAT_DBW_16 (0<<6) /* 16 Bits */ +#define TSI148_LCSR_DSAT_DBW_32 (1<<6) /* 32 Bits */ + +#define TSI148_LCSR_DSAT_SUP (1<<5) /* Supervisory Mode */ +#define TSI148_LCSR_DSAT_PGM (1<<4) /* Program Mode */ + +#define TSI148_LCSR_DSAT_AMODE_M (0xf<<0) /* Address Space Mask */ +#define TSI148_LCSR_DSAT_AMODE_A16 (0<<0) /* A16 */ +#define TSI148_LCSR_DSAT_AMODE_A24 (1<<0) /* A24 */ +#define TSI148_LCSR_DSAT_AMODE_A32 (2<<0) /* A32 */ +#define TSI148_LCSR_DSAT_AMODE_A64 (4<<0) /* A64 */ +#define TSI148_LCSR_DSAT_AMODE_CRCSR (5<<0) /* CR/CSR */ +#define TSI148_LCSR_DSAT_AMODE_USER1 (8<<0) /* User1 */ +#define TSI148_LCSR_DSAT_AMODE_USER2 (9<<0) /* User2 */ +#define TSI148_LCSR_DSAT_AMODE_USER3 (0xa<<0) /* User3 */ +#define TSI148_LCSR_DSAT_AMODE_USER4 (0xb<<0) /* User4 */ + +/* + * DMA Destination Attribute Registers (0-1) + */ +#define TSI148_LCSR_DDAT_TYP_PCI (0<<28) /* Destination PCI Bus */ +#define TSI148_LCSR_DDAT_TYP_VME (1<<28) /* Destination VMEbus */ + +#define TSI148_LCSR_DDAT_2eSSTM_M (3<<11) /* 2eSST Transfer Rate Mask */ +#define TSI148_LCSR_DDAT_2eSSTM_160 (0<<11) /* 160 MB/s */ +#define TSI148_LCSR_DDAT_2eSSTM_267 (1<<11) /* 267 MB/s */ +#define TSI148_LCSR_DDAT_2eSSTM_320 (2<<11) /* 320 MB/s */ + +#define TSI148_LCSR_DDAT_TM_M (7<<8) /* Bus Transfer Protocol Mask */ +#define TSI148_LCSR_DDAT_TM_SCT (0<<8) /* SCT */ +#define TSI148_LCSR_DDAT_TM_BLT (1<<8) /* BLT */ +#define TSI148_LCSR_DDAT_TM_MBLT (2<<8) /* MBLT */ +#define TSI148_LCSR_DDAT_TM_2eVME (3<<8) /* 2eVME */ +#define TSI148_LCSR_DDAT_TM_2eSST (4<<8) /* 2eSST */ +#define TSI148_LCSR_DDAT_TM_2eSSTB (5<<8) /* 2eSST Broadcast */ + +#define TSI148_LCSR_DDAT_DBW_M (3<<6) /* Max Data Width MASK */ +#define TSI148_LCSR_DDAT_DBW_16 (0<<6) /* 16 Bits */ +#define TSI148_LCSR_DDAT_DBW_32 (1<<6) /* 32 Bits */ + +#define TSI148_LCSR_DDAT_SUP (1<<5) /* Supervisory/User Access */ +#define TSI148_LCSR_DDAT_PGM (1<<4) /* Program/Data Access */ + +#define TSI148_LCSR_DDAT_AMODE_M (0xf<<0) /* Address Space Mask */ +#define TSI148_LCSR_DDAT_AMODE_A16 (0<<0) /* A16 */ +#define TSI148_LCSR_DDAT_AMODE_A24 (1<<0) /* A24 */ +#define TSI148_LCSR_DDAT_AMODE_A32 (2<<0) /* A32 */ +#define TSI148_LCSR_DDAT_AMODE_A64 (4<<0) /* A64 */ +#define TSI148_LCSR_DDAT_AMODE_CRCSR (5<<0) /* CRC/SR */ +#define TSI148_LCSR_DDAT_AMODE_USER1 (8<<0) /* User1 */ +#define TSI148_LCSR_DDAT_AMODE_USER2 (9<<0) /* User2 */ +#define TSI148_LCSR_DDAT_AMODE_USER3 (0xa<<0) /* User3 */ +#define TSI148_LCSR_DDAT_AMODE_USER4 (0xb<<0) /* User4 */ + +/* + * DMA Next Link Address Lower + */ +#define TSI148_LCSR_DNLAL_DNLAL_M (0x3FFFFFF<<6) /* Address Mask */ +#define TSI148_LCSR_DNLAL_LLA (1<<0) /* Last Link Address Indicator */ + +/* + * DMA 2eSST Broadcast Select + */ +#define TSI148_LCSR_DBS_M (0x1FFFFF<<0) /* Mask */ + +/* + * GCSR Register Group + */ + +/* + * GCSR Control and Status Register CRG + $604 + */ +#define TSI148_GCSR_GCTRL_LRST (1<<15) /* Local Reset */ +#define TSI148_GCSR_GCTRL_SFAILEN (1<<14) /* System Fail enable */ +#define TSI148_GCSR_GCTRL_BDFAILS (1<<13) /* Board Fail Status */ +#define TSI148_GCSR_GCTRL_SCON (1<<12) /* System Copntroller */ +#define TSI148_GCSR_GCTRL_MEN (1<<11) /* Module Enable (READY) */ + +#define TSI148_GCSR_GCTRL_LMI3S (1<<7) /* Loc Monitor 3 Int Status */ +#define TSI148_GCSR_GCTRL_LMI2S (1<<6) /* Loc Monitor 2 Int Status */ +#define TSI148_GCSR_GCTRL_LMI1S (1<<5) /* Loc Monitor 1 Int Status */ +#define TSI148_GCSR_GCTRL_LMI0S (1<<4) /* Loc Monitor 0 Int Status */ +#define TSI148_GCSR_GCTRL_MBI3S (1<<3) /* Mail box 3 Int Status */ +#define TSI148_GCSR_GCTRL_MBI2S (1<<2) /* Mail box 2 Int Status */ +#define TSI148_GCSR_GCTRL_MBI1S (1<<1) /* Mail box 1 Int Status */ +#define TSI148_GCSR_GCTRL_MBI0S (1<<0) /* Mail box 0 Int Status */ + +#define TSI148_GCSR_GAP (1<<5) /* Geographic Addr Parity */ +#define TSI148_GCSR_GA_M (0x1F<<0) /* Geographic Address Mask */ + +/* + * CR/CSR Register Group + */ + +/* + * CR/CSR Bit Clear Register CRG + $FF4 + */ +#define TSI148_CRCSR_CSRBCR_LRSTC (1<<7) /* Local Reset Clear */ +#define TSI148_CRCSR_CSRBCR_SFAILC (1<<6) /* System Fail Enable Clear */ +#define TSI148_CRCSR_CSRBCR_BDFAILS (1<<5) /* Board Fail Status */ +#define TSI148_CRCSR_CSRBCR_MENC (1<<4) /* Module Enable Clear */ +#define TSI148_CRCSR_CSRBCR_BERRSC (1<<3) /* Bus Error Status Clear */ + +/* + * CR/CSR Bit Set Register CRG+$FF8 + */ +#define TSI148_CRCSR_CSRBSR_LISTS (1<<7) /* Local Reset Clear */ +#define TSI148_CRCSR_CSRBSR_SFAILS (1<<6) /* System Fail Enable Clear */ +#define TSI148_CRCSR_CSRBSR_BDFAILS (1<<5) /* Board Fail Status */ +#define TSI148_CRCSR_CSRBSR_MENS (1<<4) /* Module Enable Clear */ +#define TSI148_CRCSR_CSRBSR_BERRS (1<<3) /* Bus Error Status Clear */ + +/* + * CR/CSR Base Address Register CRG + FFC + */ +#define TSI148_CRCSR_CBAR_M (0x1F<<3) /* Mask */ + +#endif /* TSI148_H */ diff --git a/drivers/vme/vme.c b/drivers/vme/vme.c new file mode 100644 index 0000000..95a9f71 --- /dev/null +++ b/drivers/vme/vme.c @@ -0,0 +1,1517 @@ +/* + * VME Bridge Framework + * + * Author: Martyn Welch + * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. + * + * Based on work by Tom Armistead and Ajit Prem + * Copyright 2004 Motorola 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vme_bridge.h" + +/* Bitmask and list of registered buses both protected by common mutex */ +static unsigned int vme_bus_numbers; +static LIST_HEAD(vme_bus_list); +static DEFINE_MUTEX(vme_buses_lock); + +static void __exit vme_exit(void); +static int __init vme_init(void); + +static struct vme_dev *dev_to_vme_dev(struct device *dev) +{ + return container_of(dev, struct vme_dev, dev); +} + +/* + * Find the bridge that the resource is associated with. + */ +static struct vme_bridge *find_bridge(struct vme_resource *resource) +{ + /* Get list to search */ + switch (resource->type) { + case VME_MASTER: + return list_entry(resource->entry, struct vme_master_resource, + list)->parent; + break; + case VME_SLAVE: + return list_entry(resource->entry, struct vme_slave_resource, + list)->parent; + break; + case VME_DMA: + return list_entry(resource->entry, struct vme_dma_resource, + list)->parent; + break; + case VME_LM: + return list_entry(resource->entry, struct vme_lm_resource, + list)->parent; + break; + default: + printk(KERN_ERR "Unknown resource type\n"); + return NULL; + break; + } +} + +/* + * Allocate a contiguous block of memory for use by the driver. This is used to + * create the buffers for the slave windows. + */ +void *vme_alloc_consistent(struct vme_resource *resource, size_t size, + dma_addr_t *dma) +{ + struct vme_bridge *bridge; + + if (resource == NULL) { + printk(KERN_ERR "No resource\n"); + return NULL; + } + + bridge = find_bridge(resource); + if (bridge == NULL) { + printk(KERN_ERR "Can't find bridge\n"); + return NULL; + } + + if (bridge->parent == NULL) { + printk(KERN_ERR "Dev entry NULL for bridge %s\n", bridge->name); + return NULL; + } + + if (bridge->alloc_consistent == NULL) { + printk(KERN_ERR "alloc_consistent not supported by bridge %s\n", + bridge->name); + return NULL; + } + + return bridge->alloc_consistent(bridge->parent, size, dma); +} +EXPORT_SYMBOL(vme_alloc_consistent); + +/* + * Free previously allocated contiguous block of memory. + */ +void vme_free_consistent(struct vme_resource *resource, size_t size, + void *vaddr, dma_addr_t dma) +{ + struct vme_bridge *bridge; + + if (resource == NULL) { + printk(KERN_ERR "No resource\n"); + return; + } + + bridge = find_bridge(resource); + if (bridge == NULL) { + printk(KERN_ERR "Can't find bridge\n"); + return; + } + + if (bridge->parent == NULL) { + printk(KERN_ERR "Dev entry NULL for bridge %s\n", bridge->name); + return; + } + + if (bridge->free_consistent == NULL) { + printk(KERN_ERR "free_consistent not supported by bridge %s\n", + bridge->name); + return; + } + + bridge->free_consistent(bridge->parent, size, vaddr, dma); +} +EXPORT_SYMBOL(vme_free_consistent); + +size_t vme_get_size(struct vme_resource *resource) +{ + int enabled, retval; + unsigned long long base, size; + dma_addr_t buf_base; + u32 aspace, cycle, dwidth; + + switch (resource->type) { + case VME_MASTER: + retval = vme_master_get(resource, &enabled, &base, &size, + &aspace, &cycle, &dwidth); + + return size; + break; + case VME_SLAVE: + retval = vme_slave_get(resource, &enabled, &base, &size, + &buf_base, &aspace, &cycle); + + return size; + break; + case VME_DMA: + return 0; + break; + default: + printk(KERN_ERR "Unknown resource type\n"); + return 0; + break; + } +} +EXPORT_SYMBOL(vme_get_size); + +static int vme_check_window(u32 aspace, unsigned long long vme_base, + unsigned long long size) +{ + int retval = 0; + + switch (aspace) { + case VME_A16: + if (((vme_base + size) > VME_A16_MAX) || + (vme_base > VME_A16_MAX)) + retval = -EFAULT; + break; + case VME_A24: + if (((vme_base + size) > VME_A24_MAX) || + (vme_base > VME_A24_MAX)) + retval = -EFAULT; + break; + case VME_A32: + if (((vme_base + size) > VME_A32_MAX) || + (vme_base > VME_A32_MAX)) + retval = -EFAULT; + break; + case VME_A64: + /* + * Any value held in an unsigned long long can be used as the + * base + */ + break; + case VME_CRCSR: + if (((vme_base + size) > VME_CRCSR_MAX) || + (vme_base > VME_CRCSR_MAX)) + retval = -EFAULT; + break; + case VME_USER1: + case VME_USER2: + case VME_USER3: + case VME_USER4: + /* User Defined */ + break; + default: + printk(KERN_ERR "Invalid address space\n"); + retval = -EINVAL; + break; + } + + return retval; +} + +/* + * Request a slave image with specific attributes, return some unique + * identifier. + */ +struct vme_resource *vme_slave_request(struct vme_dev *vdev, u32 address, + u32 cycle) +{ + struct vme_bridge *bridge; + struct list_head *slave_pos = NULL; + struct vme_slave_resource *allocated_image = NULL; + struct vme_slave_resource *slave_image = NULL; + struct vme_resource *resource = NULL; + + bridge = vdev->bridge; + if (bridge == NULL) { + printk(KERN_ERR "Can't find VME bus\n"); + goto err_bus; + } + + /* Loop through slave resources */ + list_for_each(slave_pos, &bridge->slave_resources) { + slave_image = list_entry(slave_pos, + struct vme_slave_resource, list); + + if (slave_image == NULL) { + printk(KERN_ERR "Registered NULL Slave resource\n"); + continue; + } + + /* Find an unlocked and compatible image */ + mutex_lock(&slave_image->mtx); + if (((slave_image->address_attr & address) == address) && + ((slave_image->cycle_attr & cycle) == cycle) && + (slave_image->locked == 0)) { + + slave_image->locked = 1; + mutex_unlock(&slave_image->mtx); + allocated_image = slave_image; + break; + } + mutex_unlock(&slave_image->mtx); + } + + /* No free image */ + if (allocated_image == NULL) + goto err_image; + + resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL); + if (resource == NULL) { + printk(KERN_WARNING "Unable to allocate resource structure\n"); + goto err_alloc; + } + resource->type = VME_SLAVE; + resource->entry = &allocated_image->list; + + return resource; + +err_alloc: + /* Unlock image */ + mutex_lock(&slave_image->mtx); + slave_image->locked = 0; + mutex_unlock(&slave_image->mtx); +err_image: +err_bus: + return NULL; +} +EXPORT_SYMBOL(vme_slave_request); + +int vme_slave_set(struct vme_resource *resource, int enabled, + unsigned long long vme_base, unsigned long long size, + dma_addr_t buf_base, u32 aspace, u32 cycle) +{ + struct vme_bridge *bridge = find_bridge(resource); + struct vme_slave_resource *image; + int retval; + + if (resource->type != VME_SLAVE) { + printk(KERN_ERR "Not a slave resource\n"); + return -EINVAL; + } + + image = list_entry(resource->entry, struct vme_slave_resource, list); + + if (bridge->slave_set == NULL) { + printk(KERN_ERR "Function not supported\n"); + return -ENOSYS; + } + + if (!(((image->address_attr & aspace) == aspace) && + ((image->cycle_attr & cycle) == cycle))) { + printk(KERN_ERR "Invalid attributes\n"); + return -EINVAL; + } + + retval = vme_check_window(aspace, vme_base, size); + if (retval) + return retval; + + return bridge->slave_set(image, enabled, vme_base, size, buf_base, + aspace, cycle); +} +EXPORT_SYMBOL(vme_slave_set); + +int vme_slave_get(struct vme_resource *resource, int *enabled, + unsigned long long *vme_base, unsigned long long *size, + dma_addr_t *buf_base, u32 *aspace, u32 *cycle) +{ + struct vme_bridge *bridge = find_bridge(resource); + struct vme_slave_resource *image; + + if (resource->type != VME_SLAVE) { + printk(KERN_ERR "Not a slave resource\n"); + return -EINVAL; + } + + image = list_entry(resource->entry, struct vme_slave_resource, list); + + if (bridge->slave_get == NULL) { + printk(KERN_ERR "vme_slave_get not supported\n"); + return -EINVAL; + } + + return bridge->slave_get(image, enabled, vme_base, size, buf_base, + aspace, cycle); +} +EXPORT_SYMBOL(vme_slave_get); + +void vme_slave_free(struct vme_resource *resource) +{ + struct vme_slave_resource *slave_image; + + if (resource->type != VME_SLAVE) { + printk(KERN_ERR "Not a slave resource\n"); + return; + } + + slave_image = list_entry(resource->entry, struct vme_slave_resource, + list); + if (slave_image == NULL) { + printk(KERN_ERR "Can't find slave resource\n"); + return; + } + + /* Unlock image */ + mutex_lock(&slave_image->mtx); + if (slave_image->locked == 0) + printk(KERN_ERR "Image is already free\n"); + + slave_image->locked = 0; + mutex_unlock(&slave_image->mtx); + + /* Free up resource memory */ + kfree(resource); +} +EXPORT_SYMBOL(vme_slave_free); + +/* + * Request a master image with specific attributes, return some unique + * identifier. + */ +struct vme_resource *vme_master_request(struct vme_dev *vdev, u32 address, + u32 cycle, u32 dwidth) +{ + struct vme_bridge *bridge; + struct list_head *master_pos = NULL; + struct vme_master_resource *allocated_image = NULL; + struct vme_master_resource *master_image = NULL; + struct vme_resource *resource = NULL; + + bridge = vdev->bridge; + if (bridge == NULL) { + printk(KERN_ERR "Can't find VME bus\n"); + goto err_bus; + } + + /* Loop through master resources */ + list_for_each(master_pos, &bridge->master_resources) { + master_image = list_entry(master_pos, + struct vme_master_resource, list); + + if (master_image == NULL) { + printk(KERN_WARNING "Registered NULL master resource\n"); + continue; + } + + /* Find an unlocked and compatible image */ + spin_lock(&master_image->lock); + if (((master_image->address_attr & address) == address) && + ((master_image->cycle_attr & cycle) == cycle) && + ((master_image->width_attr & dwidth) == dwidth) && + (master_image->locked == 0)) { + + master_image->locked = 1; + spin_unlock(&master_image->lock); + allocated_image = master_image; + break; + } + spin_unlock(&master_image->lock); + } + + /* Check to see if we found a resource */ + if (allocated_image == NULL) { + printk(KERN_ERR "Can't find a suitable resource\n"); + goto err_image; + } + + resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL); + if (resource == NULL) { + printk(KERN_ERR "Unable to allocate resource structure\n"); + goto err_alloc; + } + resource->type = VME_MASTER; + resource->entry = &allocated_image->list; + + return resource; + +err_alloc: + /* Unlock image */ + spin_lock(&master_image->lock); + master_image->locked = 0; + spin_unlock(&master_image->lock); +err_image: +err_bus: + return NULL; +} +EXPORT_SYMBOL(vme_master_request); + +int vme_master_set(struct vme_resource *resource, int enabled, + unsigned long long vme_base, unsigned long long size, u32 aspace, + u32 cycle, u32 dwidth) +{ + struct vme_bridge *bridge = find_bridge(resource); + struct vme_master_resource *image; + int retval; + + if (resource->type != VME_MASTER) { + printk(KERN_ERR "Not a master resource\n"); + return -EINVAL; + } + + image = list_entry(resource->entry, struct vme_master_resource, list); + + if (bridge->master_set == NULL) { + printk(KERN_WARNING "vme_master_set not supported\n"); + return -EINVAL; + } + + if (!(((image->address_attr & aspace) == aspace) && + ((image->cycle_attr & cycle) == cycle) && + ((image->width_attr & dwidth) == dwidth))) { + printk(KERN_WARNING "Invalid attributes\n"); + return -EINVAL; + } + + retval = vme_check_window(aspace, vme_base, size); + if (retval) + return retval; + + return bridge->master_set(image, enabled, vme_base, size, aspace, + cycle, dwidth); +} +EXPORT_SYMBOL(vme_master_set); + +int vme_master_get(struct vme_resource *resource, int *enabled, + unsigned long long *vme_base, unsigned long long *size, u32 *aspace, + u32 *cycle, u32 *dwidth) +{ + struct vme_bridge *bridge = find_bridge(resource); + struct vme_master_resource *image; + + if (resource->type != VME_MASTER) { + printk(KERN_ERR "Not a master resource\n"); + return -EINVAL; + } + + image = list_entry(resource->entry, struct vme_master_resource, list); + + if (bridge->master_get == NULL) { + printk(KERN_WARNING "vme_master_set not supported\n"); + return -EINVAL; + } + + return bridge->master_get(image, enabled, vme_base, size, aspace, + cycle, dwidth); +} +EXPORT_SYMBOL(vme_master_get); + +/* + * Read data out of VME space into a buffer. + */ +ssize_t vme_master_read(struct vme_resource *resource, void *buf, size_t count, + loff_t offset) +{ + struct vme_bridge *bridge = find_bridge(resource); + struct vme_master_resource *image; + size_t length; + + if (bridge->master_read == NULL) { + printk(KERN_WARNING "Reading from resource not supported\n"); + return -EINVAL; + } + + if (resource->type != VME_MASTER) { + printk(KERN_ERR "Not a master resource\n"); + return -EINVAL; + } + + image = list_entry(resource->entry, struct vme_master_resource, list); + + length = vme_get_size(resource); + + if (offset > length) { + printk(KERN_WARNING "Invalid Offset\n"); + return -EFAULT; + } + + if ((offset + count) > length) + count = length - offset; + + return bridge->master_read(image, buf, count, offset); + +} +EXPORT_SYMBOL(vme_master_read); + +/* + * Write data out to VME space from a buffer. + */ +ssize_t vme_master_write(struct vme_resource *resource, void *buf, + size_t count, loff_t offset) +{ + struct vme_bridge *bridge = find_bridge(resource); + struct vme_master_resource *image; + size_t length; + + if (bridge->master_write == NULL) { + printk(KERN_WARNING "Writing to resource not supported\n"); + return -EINVAL; + } + + if (resource->type != VME_MASTER) { + printk(KERN_ERR "Not a master resource\n"); + return -EINVAL; + } + + image = list_entry(resource->entry, struct vme_master_resource, list); + + length = vme_get_size(resource); + + if (offset > length) { + printk(KERN_WARNING "Invalid Offset\n"); + return -EFAULT; + } + + if ((offset + count) > length) + count = length - offset; + + return bridge->master_write(image, buf, count, offset); +} +EXPORT_SYMBOL(vme_master_write); + +/* + * Perform RMW cycle to provided location. + */ +unsigned int vme_master_rmw(struct vme_resource *resource, unsigned int mask, + unsigned int compare, unsigned int swap, loff_t offset) +{ + struct vme_bridge *bridge = find_bridge(resource); + struct vme_master_resource *image; + + if (bridge->master_rmw == NULL) { + printk(KERN_WARNING "Writing to resource not supported\n"); + return -EINVAL; + } + + if (resource->type != VME_MASTER) { + printk(KERN_ERR "Not a master resource\n"); + return -EINVAL; + } + + image = list_entry(resource->entry, struct vme_master_resource, list); + + return bridge->master_rmw(image, mask, compare, swap, offset); +} +EXPORT_SYMBOL(vme_master_rmw); + +void vme_master_free(struct vme_resource *resource) +{ + struct vme_master_resource *master_image; + + if (resource->type != VME_MASTER) { + printk(KERN_ERR "Not a master resource\n"); + return; + } + + master_image = list_entry(resource->entry, struct vme_master_resource, + list); + if (master_image == NULL) { + printk(KERN_ERR "Can't find master resource\n"); + return; + } + + /* Unlock image */ + spin_lock(&master_image->lock); + if (master_image->locked == 0) + printk(KERN_ERR "Image is already free\n"); + + master_image->locked = 0; + spin_unlock(&master_image->lock); + + /* Free up resource memory */ + kfree(resource); +} +EXPORT_SYMBOL(vme_master_free); + +/* + * Request a DMA controller with specific attributes, return some unique + * identifier. + */ +struct vme_resource *vme_dma_request(struct vme_dev *vdev, u32 route) +{ + struct vme_bridge *bridge; + struct list_head *dma_pos = NULL; + struct vme_dma_resource *allocated_ctrlr = NULL; + struct vme_dma_resource *dma_ctrlr = NULL; + struct vme_resource *resource = NULL; + + /* XXX Not checking resource attributes */ + printk(KERN_ERR "No VME resource Attribute tests done\n"); + + bridge = vdev->bridge; + if (bridge == NULL) { + printk(KERN_ERR "Can't find VME bus\n"); + goto err_bus; + } + + /* Loop through DMA resources */ + list_for_each(dma_pos, &bridge->dma_resources) { + dma_ctrlr = list_entry(dma_pos, + struct vme_dma_resource, list); + + if (dma_ctrlr == NULL) { + printk(KERN_ERR "Registered NULL DMA resource\n"); + continue; + } + + /* Find an unlocked and compatible controller */ + mutex_lock(&dma_ctrlr->mtx); + if (((dma_ctrlr->route_attr & route) == route) && + (dma_ctrlr->locked == 0)) { + + dma_ctrlr->locked = 1; + mutex_unlock(&dma_ctrlr->mtx); + allocated_ctrlr = dma_ctrlr; + break; + } + mutex_unlock(&dma_ctrlr->mtx); + } + + /* Check to see if we found a resource */ + if (allocated_ctrlr == NULL) + goto err_ctrlr; + + resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL); + if (resource == NULL) { + printk(KERN_WARNING "Unable to allocate resource structure\n"); + goto err_alloc; + } + resource->type = VME_DMA; + resource->entry = &allocated_ctrlr->list; + + return resource; + +err_alloc: + /* Unlock image */ + mutex_lock(&dma_ctrlr->mtx); + dma_ctrlr->locked = 0; + mutex_unlock(&dma_ctrlr->mtx); +err_ctrlr: +err_bus: + return NULL; +} +EXPORT_SYMBOL(vme_dma_request); + +/* + * Start new list + */ +struct vme_dma_list *vme_new_dma_list(struct vme_resource *resource) +{ + struct vme_dma_resource *ctrlr; + struct vme_dma_list *dma_list; + + if (resource->type != VME_DMA) { + printk(KERN_ERR "Not a DMA resource\n"); + return NULL; + } + + ctrlr = list_entry(resource->entry, struct vme_dma_resource, list); + + dma_list = kmalloc(sizeof(struct vme_dma_list), GFP_KERNEL); + if (dma_list == NULL) { + printk(KERN_ERR "Unable to allocate memory for new dma list\n"); + return NULL; + } + INIT_LIST_HEAD(&dma_list->entries); + dma_list->parent = ctrlr; + mutex_init(&dma_list->mtx); + + return dma_list; +} +EXPORT_SYMBOL(vme_new_dma_list); + +/* + * Create "Pattern" type attributes + */ +struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, u32 type) +{ + struct vme_dma_attr *attributes; + struct vme_dma_pattern *pattern_attr; + + attributes = kmalloc(sizeof(struct vme_dma_attr), GFP_KERNEL); + if (attributes == NULL) { + printk(KERN_ERR "Unable to allocate memory for attributes structure\n"); + goto err_attr; + } + + pattern_attr = kmalloc(sizeof(struct vme_dma_pattern), GFP_KERNEL); + if (pattern_attr == NULL) { + printk(KERN_ERR "Unable to allocate memory for pattern attributes\n"); + goto err_pat; + } + + attributes->type = VME_DMA_PATTERN; + attributes->private = (void *)pattern_attr; + + pattern_attr->pattern = pattern; + pattern_attr->type = type; + + return attributes; + +err_pat: + kfree(attributes); +err_attr: + return NULL; +} +EXPORT_SYMBOL(vme_dma_pattern_attribute); + +/* + * Create "PCI" type attributes + */ +struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t address) +{ + struct vme_dma_attr *attributes; + struct vme_dma_pci *pci_attr; + + /* XXX Run some sanity checks here */ + + attributes = kmalloc(sizeof(struct vme_dma_attr), GFP_KERNEL); + if (attributes == NULL) { + printk(KERN_ERR "Unable to allocate memory for attributes structure\n"); + goto err_attr; + } + + pci_attr = kmalloc(sizeof(struct vme_dma_pci), GFP_KERNEL); + if (pci_attr == NULL) { + printk(KERN_ERR "Unable to allocate memory for pci attributes\n"); + goto err_pci; + } + + + + attributes->type = VME_DMA_PCI; + attributes->private = (void *)pci_attr; + + pci_attr->address = address; + + return attributes; + +err_pci: + kfree(attributes); +err_attr: + return NULL; +} +EXPORT_SYMBOL(vme_dma_pci_attribute); + +/* + * Create "VME" type attributes + */ +struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long address, + u32 aspace, u32 cycle, u32 dwidth) +{ + struct vme_dma_attr *attributes; + struct vme_dma_vme *vme_attr; + + attributes = kmalloc( + sizeof(struct vme_dma_attr), GFP_KERNEL); + if (attributes == NULL) { + printk(KERN_ERR "Unable to allocate memory for attributes structure\n"); + goto err_attr; + } + + vme_attr = kmalloc(sizeof(struct vme_dma_vme), GFP_KERNEL); + if (vme_attr == NULL) { + printk(KERN_ERR "Unable to allocate memory for vme attributes\n"); + goto err_vme; + } + + attributes->type = VME_DMA_VME; + attributes->private = (void *)vme_attr; + + vme_attr->address = address; + vme_attr->aspace = aspace; + vme_attr->cycle = cycle; + vme_attr->dwidth = dwidth; + + return attributes; + +err_vme: + kfree(attributes); +err_attr: + return NULL; +} +EXPORT_SYMBOL(vme_dma_vme_attribute); + +/* + * Free attribute + */ +void vme_dma_free_attribute(struct vme_dma_attr *attributes) +{ + kfree(attributes->private); + kfree(attributes); +} +EXPORT_SYMBOL(vme_dma_free_attribute); + +int vme_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, + struct vme_dma_attr *dest, size_t count) +{ + struct vme_bridge *bridge = list->parent->parent; + int retval; + + if (bridge->dma_list_add == NULL) { + printk(KERN_WARNING "Link List DMA generation not supported\n"); + return -EINVAL; + } + + if (!mutex_trylock(&list->mtx)) { + printk(KERN_ERR "Link List already submitted\n"); + return -EINVAL; + } + + retval = bridge->dma_list_add(list, src, dest, count); + + mutex_unlock(&list->mtx); + + return retval; +} +EXPORT_SYMBOL(vme_dma_list_add); + +int vme_dma_list_exec(struct vme_dma_list *list) +{ + struct vme_bridge *bridge = list->parent->parent; + int retval; + + if (bridge->dma_list_exec == NULL) { + printk(KERN_ERR "Link List DMA execution not supported\n"); + return -EINVAL; + } + + mutex_lock(&list->mtx); + + retval = bridge->dma_list_exec(list); + + mutex_unlock(&list->mtx); + + return retval; +} +EXPORT_SYMBOL(vme_dma_list_exec); + +int vme_dma_list_free(struct vme_dma_list *list) +{ + struct vme_bridge *bridge = list->parent->parent; + int retval; + + if (bridge->dma_list_empty == NULL) { + printk(KERN_WARNING "Emptying of Link Lists not supported\n"); + return -EINVAL; + } + + if (!mutex_trylock(&list->mtx)) { + printk(KERN_ERR "Link List in use\n"); + return -EINVAL; + } + + /* + * Empty out all of the entries from the dma list. We need to go to the + * low level driver as dma entries are driver specific. + */ + retval = bridge->dma_list_empty(list); + if (retval) { + printk(KERN_ERR "Unable to empty link-list entries\n"); + mutex_unlock(&list->mtx); + return retval; + } + mutex_unlock(&list->mtx); + kfree(list); + + return retval; +} +EXPORT_SYMBOL(vme_dma_list_free); + +int vme_dma_free(struct vme_resource *resource) +{ + struct vme_dma_resource *ctrlr; + + if (resource->type != VME_DMA) { + printk(KERN_ERR "Not a DMA resource\n"); + return -EINVAL; + } + + ctrlr = list_entry(resource->entry, struct vme_dma_resource, list); + + if (!mutex_trylock(&ctrlr->mtx)) { + printk(KERN_ERR "Resource busy, can't free\n"); + return -EBUSY; + } + + if (!(list_empty(&ctrlr->pending) && list_empty(&ctrlr->running))) { + printk(KERN_WARNING "Resource still processing transfers\n"); + mutex_unlock(&ctrlr->mtx); + return -EBUSY; + } + + ctrlr->locked = 0; + + mutex_unlock(&ctrlr->mtx); + + return 0; +} +EXPORT_SYMBOL(vme_dma_free); + +void vme_irq_handler(struct vme_bridge *bridge, int level, int statid) +{ + void (*call)(int, int, void *); + void *priv_data; + + call = bridge->irq[level - 1].callback[statid].func; + priv_data = bridge->irq[level - 1].callback[statid].priv_data; + + if (call != NULL) + call(level, statid, priv_data); + else + printk(KERN_WARNING "Spurilous VME interrupt, level:%x, vector:%x\n", + level, statid); +} +EXPORT_SYMBOL(vme_irq_handler); + +int vme_irq_request(struct vme_dev *vdev, int level, int statid, + void (*callback)(int, int, void *), + void *priv_data) +{ + struct vme_bridge *bridge; + + bridge = vdev->bridge; + if (bridge == NULL) { + printk(KERN_ERR "Can't find VME bus\n"); + return -EINVAL; + } + + if ((level < 1) || (level > 7)) { + printk(KERN_ERR "Invalid interrupt level\n"); + return -EINVAL; + } + + if (bridge->irq_set == NULL) { + printk(KERN_ERR "Configuring interrupts not supported\n"); + return -EINVAL; + } + + mutex_lock(&bridge->irq_mtx); + + if (bridge->irq[level - 1].callback[statid].func) { + mutex_unlock(&bridge->irq_mtx); + printk(KERN_WARNING "VME Interrupt already taken\n"); + return -EBUSY; + } + + bridge->irq[level - 1].count++; + bridge->irq[level - 1].callback[statid].priv_data = priv_data; + bridge->irq[level - 1].callback[statid].func = callback; + + /* Enable IRQ level */ + bridge->irq_set(bridge, level, 1, 1); + + mutex_unlock(&bridge->irq_mtx); + + return 0; +} +EXPORT_SYMBOL(vme_irq_request); + +void vme_irq_free(struct vme_dev *vdev, int level, int statid) +{ + struct vme_bridge *bridge; + + bridge = vdev->bridge; + if (bridge == NULL) { + printk(KERN_ERR "Can't find VME bus\n"); + return; + } + + if ((level < 1) || (level > 7)) { + printk(KERN_ERR "Invalid interrupt level\n"); + return; + } + + if (bridge->irq_set == NULL) { + printk(KERN_ERR "Configuring interrupts not supported\n"); + return; + } + + mutex_lock(&bridge->irq_mtx); + + bridge->irq[level - 1].count--; + + /* Disable IRQ level if no more interrupts attached at this level*/ + if (bridge->irq[level - 1].count == 0) + bridge->irq_set(bridge, level, 0, 1); + + bridge->irq[level - 1].callback[statid].func = NULL; + bridge->irq[level - 1].callback[statid].priv_data = NULL; + + mutex_unlock(&bridge->irq_mtx); +} +EXPORT_SYMBOL(vme_irq_free); + +int vme_irq_generate(struct vme_dev *vdev, int level, int statid) +{ + struct vme_bridge *bridge; + + bridge = vdev->bridge; + if (bridge == NULL) { + printk(KERN_ERR "Can't find VME bus\n"); + return -EINVAL; + } + + if ((level < 1) || (level > 7)) { + printk(KERN_WARNING "Invalid interrupt level\n"); + return -EINVAL; + } + + if (bridge->irq_generate == NULL) { + printk(KERN_WARNING "Interrupt generation not supported\n"); + return -EINVAL; + } + + return bridge->irq_generate(bridge, level, statid); +} +EXPORT_SYMBOL(vme_irq_generate); + +/* + * Request the location monitor, return resource or NULL + */ +struct vme_resource *vme_lm_request(struct vme_dev *vdev) +{ + struct vme_bridge *bridge; + struct list_head *lm_pos = NULL; + struct vme_lm_resource *allocated_lm = NULL; + struct vme_lm_resource *lm = NULL; + struct vme_resource *resource = NULL; + + bridge = vdev->bridge; + if (bridge == NULL) { + printk(KERN_ERR "Can't find VME bus\n"); + goto err_bus; + } + + /* Loop through DMA resources */ + list_for_each(lm_pos, &bridge->lm_resources) { + lm = list_entry(lm_pos, + struct vme_lm_resource, list); + + if (lm == NULL) { + printk(KERN_ERR "Registered NULL Location Monitor resource\n"); + continue; + } + + /* Find an unlocked controller */ + mutex_lock(&lm->mtx); + if (lm->locked == 0) { + lm->locked = 1; + mutex_unlock(&lm->mtx); + allocated_lm = lm; + break; + } + mutex_unlock(&lm->mtx); + } + + /* Check to see if we found a resource */ + if (allocated_lm == NULL) + goto err_lm; + + resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL); + if (resource == NULL) { + printk(KERN_ERR "Unable to allocate resource structure\n"); + goto err_alloc; + } + resource->type = VME_LM; + resource->entry = &allocated_lm->list; + + return resource; + +err_alloc: + /* Unlock image */ + mutex_lock(&lm->mtx); + lm->locked = 0; + mutex_unlock(&lm->mtx); +err_lm: +err_bus: + return NULL; +} +EXPORT_SYMBOL(vme_lm_request); + +int vme_lm_count(struct vme_resource *resource) +{ + struct vme_lm_resource *lm; + + if (resource->type != VME_LM) { + printk(KERN_ERR "Not a Location Monitor resource\n"); + return -EINVAL; + } + + lm = list_entry(resource->entry, struct vme_lm_resource, list); + + return lm->monitors; +} +EXPORT_SYMBOL(vme_lm_count); + +int vme_lm_set(struct vme_resource *resource, unsigned long long lm_base, + u32 aspace, u32 cycle) +{ + struct vme_bridge *bridge = find_bridge(resource); + struct vme_lm_resource *lm; + + if (resource->type != VME_LM) { + printk(KERN_ERR "Not a Location Monitor resource\n"); + return -EINVAL; + } + + lm = list_entry(resource->entry, struct vme_lm_resource, list); + + if (bridge->lm_set == NULL) { + printk(KERN_ERR "vme_lm_set not supported\n"); + return -EINVAL; + } + + return bridge->lm_set(lm, lm_base, aspace, cycle); +} +EXPORT_SYMBOL(vme_lm_set); + +int vme_lm_get(struct vme_resource *resource, unsigned long long *lm_base, + u32 *aspace, u32 *cycle) +{ + struct vme_bridge *bridge = find_bridge(resource); + struct vme_lm_resource *lm; + + if (resource->type != VME_LM) { + printk(KERN_ERR "Not a Location Monitor resource\n"); + return -EINVAL; + } + + lm = list_entry(resource->entry, struct vme_lm_resource, list); + + if (bridge->lm_get == NULL) { + printk(KERN_ERR "vme_lm_get not supported\n"); + return -EINVAL; + } + + return bridge->lm_get(lm, lm_base, aspace, cycle); +} +EXPORT_SYMBOL(vme_lm_get); + +int vme_lm_attach(struct vme_resource *resource, int monitor, + void (*callback)(int)) +{ + struct vme_bridge *bridge = find_bridge(resource); + struct vme_lm_resource *lm; + + if (resource->type != VME_LM) { + printk(KERN_ERR "Not a Location Monitor resource\n"); + return -EINVAL; + } + + lm = list_entry(resource->entry, struct vme_lm_resource, list); + + if (bridge->lm_attach == NULL) { + printk(KERN_ERR "vme_lm_attach not supported\n"); + return -EINVAL; + } + + return bridge->lm_attach(lm, monitor, callback); +} +EXPORT_SYMBOL(vme_lm_attach); + +int vme_lm_detach(struct vme_resource *resource, int monitor) +{ + struct vme_bridge *bridge = find_bridge(resource); + struct vme_lm_resource *lm; + + if (resource->type != VME_LM) { + printk(KERN_ERR "Not a Location Monitor resource\n"); + return -EINVAL; + } + + lm = list_entry(resource->entry, struct vme_lm_resource, list); + + if (bridge->lm_detach == NULL) { + printk(KERN_ERR "vme_lm_detach not supported\n"); + return -EINVAL; + } + + return bridge->lm_detach(lm, monitor); +} +EXPORT_SYMBOL(vme_lm_detach); + +void vme_lm_free(struct vme_resource *resource) +{ + struct vme_lm_resource *lm; + + if (resource->type != VME_LM) { + printk(KERN_ERR "Not a Location Monitor resource\n"); + return; + } + + lm = list_entry(resource->entry, struct vme_lm_resource, list); + + mutex_lock(&lm->mtx); + + /* XXX + * Check to see that there aren't any callbacks still attached, if + * there are we should probably be detaching them! + */ + + lm->locked = 0; + + mutex_unlock(&lm->mtx); + + kfree(resource); +} +EXPORT_SYMBOL(vme_lm_free); + +int vme_slot_get(struct vme_dev *vdev) +{ + struct vme_bridge *bridge; + + bridge = vdev->bridge; + if (bridge == NULL) { + printk(KERN_ERR "Can't find VME bus\n"); + return -EINVAL; + } + + if (bridge->slot_get == NULL) { + printk(KERN_WARNING "vme_slot_get not supported\n"); + return -EINVAL; + } + + return bridge->slot_get(bridge); +} +EXPORT_SYMBOL(vme_slot_get); + + +/* - Bridge Registration --------------------------------------------------- */ + +static void vme_dev_release(struct device *dev) +{ + kfree(dev_to_vme_dev(dev)); +} + +int vme_register_bridge(struct vme_bridge *bridge) +{ + int i; + int ret = -1; + + mutex_lock(&vme_buses_lock); + for (i = 0; i < sizeof(vme_bus_numbers) * 8; i++) { + if ((vme_bus_numbers & (1 << i)) == 0) { + vme_bus_numbers |= (1 << i); + bridge->num = i; + INIT_LIST_HEAD(&bridge->devices); + list_add_tail(&bridge->bus_list, &vme_bus_list); + ret = 0; + break; + } + } + mutex_unlock(&vme_buses_lock); + + return ret; +} +EXPORT_SYMBOL(vme_register_bridge); + +void vme_unregister_bridge(struct vme_bridge *bridge) +{ + struct vme_dev *vdev; + struct vme_dev *tmp; + + mutex_lock(&vme_buses_lock); + vme_bus_numbers &= ~(1 << bridge->num); + list_for_each_entry_safe(vdev, tmp, &bridge->devices, bridge_list) { + list_del(&vdev->drv_list); + list_del(&vdev->bridge_list); + device_unregister(&vdev->dev); + } + list_del(&bridge->bus_list); + mutex_unlock(&vme_buses_lock); +} +EXPORT_SYMBOL(vme_unregister_bridge); + +/* - Driver Registration --------------------------------------------------- */ + +static int __vme_register_driver_bus(struct vme_driver *drv, + struct vme_bridge *bridge, unsigned int ndevs) +{ + int err; + unsigned int i; + struct vme_dev *vdev; + struct vme_dev *tmp; + + for (i = 0; i < ndevs; i++) { + vdev = kzalloc(sizeof(struct vme_dev), GFP_KERNEL); + if (!vdev) { + err = -ENOMEM; + goto err_devalloc; + } + vdev->num = i; + vdev->bridge = bridge; + vdev->dev.platform_data = drv; + vdev->dev.release = vme_dev_release; + vdev->dev.parent = bridge->parent; + vdev->dev.bus = &vme_bus_type; + dev_set_name(&vdev->dev, "%s.%u-%u", drv->name, bridge->num, + vdev->num); + + err = device_register(&vdev->dev); + if (err) + goto err_reg; + + if (vdev->dev.platform_data) { + list_add_tail(&vdev->drv_list, &drv->devices); + list_add_tail(&vdev->bridge_list, &bridge->devices); + } else + device_unregister(&vdev->dev); + } + return 0; + +err_reg: + kfree(vdev); +err_devalloc: + list_for_each_entry_safe(vdev, tmp, &drv->devices, drv_list) { + list_del(&vdev->drv_list); + list_del(&vdev->bridge_list); + device_unregister(&vdev->dev); + } + return err; +} + +static int __vme_register_driver(struct vme_driver *drv, unsigned int ndevs) +{ + struct vme_bridge *bridge; + int err = 0; + + mutex_lock(&vme_buses_lock); + list_for_each_entry(bridge, &vme_bus_list, bus_list) { + /* + * This cannot cause trouble as we already have vme_buses_lock + * and if the bridge is removed, it will have to go through + * vme_unregister_bridge() to do it (which calls remove() on + * the bridge which in turn tries to acquire vme_buses_lock and + * will have to wait). + */ + err = __vme_register_driver_bus(drv, bridge, ndevs); + if (err) + break; + } + mutex_unlock(&vme_buses_lock); + return err; +} + +int vme_register_driver(struct vme_driver *drv, unsigned int ndevs) +{ + int err; + + drv->driver.name = drv->name; + drv->driver.bus = &vme_bus_type; + INIT_LIST_HEAD(&drv->devices); + + err = driver_register(&drv->driver); + if (err) + return err; + + err = __vme_register_driver(drv, ndevs); + if (err) + driver_unregister(&drv->driver); + + return err; +} +EXPORT_SYMBOL(vme_register_driver); + +void vme_unregister_driver(struct vme_driver *drv) +{ + struct vme_dev *dev, *dev_tmp; + + mutex_lock(&vme_buses_lock); + list_for_each_entry_safe(dev, dev_tmp, &drv->devices, drv_list) { + list_del(&dev->drv_list); + list_del(&dev->bridge_list); + device_unregister(&dev->dev); + } + mutex_unlock(&vme_buses_lock); + + driver_unregister(&drv->driver); +} +EXPORT_SYMBOL(vme_unregister_driver); + +/* - Bus Registration ------------------------------------------------------ */ + +static int vme_bus_match(struct device *dev, struct device_driver *drv) +{ + struct vme_driver *vme_drv; + + vme_drv = container_of(drv, struct vme_driver, driver); + + if (dev->platform_data == vme_drv) { + struct vme_dev *vdev = dev_to_vme_dev(dev); + + if (vme_drv->match && vme_drv->match(vdev)) + return 1; + + dev->platform_data = NULL; + } + return 0; +} + +static int vme_bus_probe(struct device *dev) +{ + int retval = -ENODEV; + struct vme_driver *driver; + struct vme_dev *vdev = dev_to_vme_dev(dev); + + driver = dev->platform_data; + + if (driver->probe != NULL) + retval = driver->probe(vdev); + + return retval; +} + +static int vme_bus_remove(struct device *dev) +{ + int retval = -ENODEV; + struct vme_driver *driver; + struct vme_dev *vdev = dev_to_vme_dev(dev); + + driver = dev->platform_data; + + if (driver->remove != NULL) + retval = driver->remove(vdev); + + return retval; +} + +struct bus_type vme_bus_type = { + .name = "vme", + .match = vme_bus_match, + .probe = vme_bus_probe, + .remove = vme_bus_remove, +}; +EXPORT_SYMBOL(vme_bus_type); + +static int __init vme_init(void) +{ + return bus_register(&vme_bus_type); +} + +static void __exit vme_exit(void) +{ + bus_unregister(&vme_bus_type); +} + +MODULE_DESCRIPTION("VME bridge driver framework"); +MODULE_AUTHOR("Martyn Welch id.num >= USER_BUS_MAX) + return 0; + return 1; + } + +The '.probe' element should contain a pointer to the probe routine. The +probe routine is passed a 'struct vme_dev' pointer as an argument. The +'struct vme_dev' structure looks like the following: + + struct vme_dev { + int num; + struct vme_bridge *bridge; + struct device dev; + struct list_head drv_list; + struct list_head bridge_list; + }; + +Here, the 'num' field refers to the sequential device ID for this specific +driver. The bridge number (or bus number) can be accessed using +dev->bridge->num. + +A function is also provided to unregister the driver from the VME core and is +usually called from the device driver's exit routine: + + void vme_unregister_driver (struct vme_driver *driver); + + +Resource management +=================== + +Once a driver has registered with the VME core the provided match routine will +be called the number of times specified during the registration. If a match +succeeds, a non-zero value should be returned. A zero return value indicates +failure. For all successful matches, the probe routine of the corresponding +driver is called. The probe routine is passed a pointer to the devices +device structure. This pointer should be saved, it will be required for +requesting VME resources. + +The driver can request ownership of one or more master windows, slave windows +and/or dma channels. Rather than allowing the device driver to request a +specific window or DMA channel (which may be used by a different driver) this +driver allows a resource to be assigned based on the required attributes of the +driver in question: + + struct vme_resource * vme_master_request(struct vme_dev *dev, + u32 aspace, u32 cycle, u32 width); + + struct vme_resource * vme_slave_request(struct vme_dev *dev, u32 aspace, + u32 cycle); + + struct vme_resource *vme_dma_request(struct vme_dev *dev, u32 route); + +For slave windows these attributes are split into the VME address spaces that +need to be accessed in 'aspace' and VME bus cycle types required in 'cycle'. +Master windows add a further set of attributes in 'width' specifying the +required data transfer widths. These attributes are defined as bitmasks and as +such any combination of the attributes can be requested for a single window, +the core will assign a window that meets the requirements, returning a pointer +of type vme_resource that should be used to identify the allocated resource +when it is used. For DMA controllers, the request function requires the +potential direction of any transfers to be provided in the route attributes. +This is typically VME-to-MEM and/or MEM-to-VME, though some hardware can +support VME-to-VME and MEM-to-MEM transfers as well as test pattern generation. +If an unallocated window fitting the requirements can not be found a NULL +pointer will be returned. + +Functions are also provided to free window allocations once they are no longer +required. These functions should be passed the pointer to the resource provided +during resource allocation: + + void vme_master_free(struct vme_resource *res); + + void vme_slave_free(struct vme_resource *res); + + void vme_dma_free(struct vme_resource *res); + + +Master windows +============== + +Master windows provide access from the local processor[s] out onto the VME bus. +The number of windows available and the available access modes is dependent on +the underlying chipset. A window must be configured before it can be used. + + +Master window configuration +--------------------------- + +Once a master window has been assigned the following functions can be used to +configure it and retrieve the current settings: + + int vme_master_set (struct vme_resource *res, int enabled, + unsigned long long base, unsigned long long size, u32 aspace, + u32 cycle, u32 width); + + int vme_master_get (struct vme_resource *res, int *enabled, + unsigned long long *base, unsigned long long *size, u32 *aspace, + u32 *cycle, u32 *width); + +The address spaces, transfer widths and cycle types are the same as described +under resource management, however some of the options are mutually exclusive. +For example, only one address space may be specified. + +These functions return 0 on success or an error code should the call fail. + + +Master window access +-------------------- + +The following functions can be used to read from and write to configured master +windows. These functions return the number of bytes copied: + + ssize_t vme_master_read(struct vme_resource *res, void *buf, + size_t count, loff_t offset); + + ssize_t vme_master_write(struct vme_resource *res, void *buf, + size_t count, loff_t offset); + +In addition to simple reads and writes, a function is provided to do a +read-modify-write transaction. This function returns the original value of the +VME bus location : + + unsigned int vme_master_rmw (struct vme_resource *res, + unsigned int mask, unsigned int compare, unsigned int swap, + loff_t offset); + +This functions by reading the offset, applying the mask. If the bits selected in +the mask match with the values of the corresponding bits in the compare field, +the value of swap is written the specified offset. + + +Slave windows +============= + +Slave windows provide devices on the VME bus access into mapped portions of the +local memory. The number of windows available and the access modes that can be +used is dependent on the underlying chipset. A window must be configured before +it can be used. + + +Slave window configuration +-------------------------- + +Once a slave window has been assigned the following functions can be used to +configure it and retrieve the current settings: + + int vme_slave_set (struct vme_resource *res, int enabled, + unsigned long long base, unsigned long long size, + dma_addr_t mem, u32 aspace, u32 cycle); + + int vme_slave_get (struct vme_resource *res, int *enabled, + unsigned long long *base, unsigned long long *size, + dma_addr_t *mem, u32 *aspace, u32 *cycle); + +The address spaces, transfer widths and cycle types are the same as described +under resource management, however some of the options are mutually exclusive. +For example, only one address space may be specified. + +These functions return 0 on success or an error code should the call fail. + + +Slave window buffer allocation +------------------------------ + +Functions are provided to allow the user to allocate and free a contiguous +buffers which will be accessible by the VME bridge. These functions do not have +to be used, other methods can be used to allocate a buffer, though care must be +taken to ensure that they are contiguous and accessible by the VME bridge: + + void * vme_alloc_consistent(struct vme_resource *res, size_t size, + dma_addr_t *mem); + + void vme_free_consistent(struct vme_resource *res, size_t size, + void *virt, dma_addr_t mem); + + +Slave window access +------------------- + +Slave windows map local memory onto the VME bus, the standard methods for +accessing memory should be used. + + +DMA channels +============ + +The VME DMA transfer provides the ability to run link-list DMA transfers. The +API introduces the concept of DMA lists. Each DMA list is a link-list which can +be passed to a DMA controller. Multiple lists can be created, extended, +executed, reused and destroyed. + + +List Management +--------------- + +The following functions are provided to create and destroy DMA lists. Execution +of a list will not automatically destroy the list, thus enabling a list to be +reused for repetitive tasks: + + struct vme_dma_list *vme_new_dma_list(struct vme_resource *res); + + int vme_dma_list_free(struct vme_dma_list *list); + + +List Population +--------------- + +An item can be added to a list using the following function ( the source and +destination attributes need to be created before calling this function, this is +covered under "Transfer Attributes"): + + int vme_dma_list_add(struct vme_dma_list *list, + struct vme_dma_attr *src, struct vme_dma_attr *dest, + size_t count); + +NOTE: The detailed attributes of the transfers source and destination + are not checked until an entry is added to a DMA list, the request + for a DMA channel purely checks the directions in which the + controller is expected to transfer data. As a result it is + possible for this call to return an error, for example if the + source or destination is in an unsupported VME address space. + +Transfer Attributes +------------------- + +The attributes for the source and destination are handled separately from adding +an item to a list. This is due to the diverse attributes required for each type +of source and destination. There are functions to create attributes for PCI, VME +and pattern sources and destinations (where appropriate): + +Pattern source: + + struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, u32 type); + +PCI source or destination: + + struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t mem); + +VME source or destination: + + struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long base, + u32 aspace, u32 cycle, u32 width); + +The following function should be used to free an attribute: + + void vme_dma_free_attribute(struct vme_dma_attr *attr); + + +List Execution +-------------- + +The following function queues a list for execution. The function will return +once the list has been executed: + + int vme_dma_list_exec(struct vme_dma_list *list); + + +Interrupts +========== + +The VME API provides functions to attach and detach callbacks to specific VME +level and status ID combinations and for the generation of VME interrupts with +specific VME level and status IDs. + + +Attaching Interrupt Handlers +---------------------------- + +The following functions can be used to attach and free a specific VME level and +status ID combination. Any given combination can only be assigned a single +callback function. A void pointer parameter is provided, the value of which is +passed to the callback function, the use of this pointer is user undefined: + + int vme_irq_request(struct vme_dev *dev, int level, int statid, + void (*callback)(int, int, void *), void *priv); + + void vme_irq_free(struct vme_dev *dev, int level, int statid); + +The callback parameters are as follows. Care must be taken in writing a callback +function, callback functions run in interrupt context: + + void callback(int level, int statid, void *priv); + + +Interrupt Generation +-------------------- + +The following function can be used to generate a VME interrupt at a given VME +level and VME status ID: + + int vme_irq_generate(struct vme_dev *dev, int level, int statid); + + +Location monitors +================= + +The VME API provides the following functionality to configure the location +monitor. + + +Location Monitor Management +--------------------------- + +The following functions are provided to request the use of a block of location +monitors and to free them after they are no longer required: + + struct vme_resource * vme_lm_request(struct vme_dev *dev); + + void vme_lm_free(struct vme_resource * res); + +Each block may provide a number of location monitors, monitoring adjacent +locations. The following function can be used to determine how many locations +are provided: + + int vme_lm_count(struct vme_resource * res); + + +Location Monitor Configuration +------------------------------ + +Once a bank of location monitors has been allocated, the following functions +are provided to configure the location and mode of the location monitor: + + int vme_lm_set(struct vme_resource *res, unsigned long long base, + u32 aspace, u32 cycle); + + int vme_lm_get(struct vme_resource *res, unsigned long long *base, + u32 *aspace, u32 *cycle); + + +Location Monitor Use +-------------------- + +The following functions allow a callback to be attached and detached from each +location monitor location. Each location monitor can monitor a number of +adjacent locations: + + int vme_lm_attach(struct vme_resource *res, int num, + void (*callback)(int)); + + int vme_lm_detach(struct vme_resource *res, int num); + +The callback function is declared as follows. + + void callback(int num); + + +Slot Detection +============== + +This function returns the slot ID of the provided bridge. + + int vme_slot_get(struct vme_dev *dev); diff --git a/drivers/vme/vme_bridge.h b/drivers/vme/vme_bridge.h new file mode 100644 index 0000000..934949a --- /dev/null +++ b/drivers/vme/vme_bridge.h @@ -0,0 +1,174 @@ +#ifndef _VME_BRIDGE_H_ +#define _VME_BRIDGE_H_ + +#define VME_CRCSR_BUF_SIZE (508*1024) +/* + * Resource structures + */ +struct vme_master_resource { + struct list_head list; + struct vme_bridge *parent; + /* + * We are likely to need to access the VME bus in interrupt context, so + * protect master routines with a spinlock rather than a mutex. + */ + spinlock_t lock; + int locked; + int number; + u32 address_attr; + u32 cycle_attr; + u32 width_attr; + struct resource bus_resource; + void __iomem *kern_base; +}; + +struct vme_slave_resource { + struct list_head list; + struct vme_bridge *parent; + struct mutex mtx; + int locked; + int number; + u32 address_attr; + u32 cycle_attr; +}; + +struct vme_dma_pattern { + u32 pattern; + u32 type; +}; + +struct vme_dma_pci { + dma_addr_t address; +}; + +struct vme_dma_vme { + unsigned long long address; + u32 aspace; + u32 cycle; + u32 dwidth; +}; + +struct vme_dma_list { + struct list_head list; + struct vme_dma_resource *parent; + struct list_head entries; + struct mutex mtx; +}; + +struct vme_dma_resource { + struct list_head list; + struct vme_bridge *parent; + struct mutex mtx; + int locked; + int number; + struct list_head pending; + struct list_head running; + u32 route_attr; +}; + +struct vme_lm_resource { + struct list_head list; + struct vme_bridge *parent; + struct mutex mtx; + int locked; + int number; + int monitors; +}; + +struct vme_bus_error { + struct list_head list; + unsigned long long address; + u32 attributes; +}; + +struct vme_callback { + void (*func)(int, int, void*); + void *priv_data; +}; + +struct vme_irq { + int count; + struct vme_callback callback[255]; +}; + +/* Allow 16 characters for name (including null character) */ +#define VMENAMSIZ 16 + +/* This structure stores all the information about one bridge + * The structure should be dynamically allocated by the driver and one instance + * of the structure should be present for each VME chip present in the system. + */ +struct vme_bridge { + char name[VMENAMSIZ]; + int num; + struct list_head master_resources; + struct list_head slave_resources; + struct list_head dma_resources; + struct list_head lm_resources; + + struct list_head vme_errors; /* List for errors generated on VME */ + struct list_head devices; /* List of devices on this bridge */ + + /* Bridge Info - XXX Move to private structure? */ + struct device *parent; /* Parent device (eg. pdev->dev for PCI) */ + void *driver_priv; /* Private pointer for the bridge driver */ + struct list_head bus_list; /* list of VME buses */ + + /* Interrupt callbacks */ + struct vme_irq irq[7]; + /* Locking for VME irq callback configuration */ + struct mutex irq_mtx; + + /* Slave Functions */ + int (*slave_get) (struct vme_slave_resource *, int *, + unsigned long long *, unsigned long long *, dma_addr_t *, + u32 *, u32 *); + int (*slave_set) (struct vme_slave_resource *, int, unsigned long long, + unsigned long long, dma_addr_t, u32, u32); + + /* Master Functions */ + int (*master_get) (struct vme_master_resource *, int *, + unsigned long long *, unsigned long long *, u32 *, u32 *, + u32 *); + int (*master_set) (struct vme_master_resource *, int, + unsigned long long, unsigned long long, u32, u32, u32); + ssize_t (*master_read) (struct vme_master_resource *, void *, size_t, + loff_t); + ssize_t (*master_write) (struct vme_master_resource *, void *, size_t, + loff_t); + unsigned int (*master_rmw) (struct vme_master_resource *, unsigned int, + unsigned int, unsigned int, loff_t); + + /* DMA Functions */ + int (*dma_list_add) (struct vme_dma_list *, struct vme_dma_attr *, + struct vme_dma_attr *, size_t); + int (*dma_list_exec) (struct vme_dma_list *); + int (*dma_list_empty) (struct vme_dma_list *); + + /* Interrupt Functions */ + void (*irq_set) (struct vme_bridge *, int, int, int); + int (*irq_generate) (struct vme_bridge *, int, int); + + /* Location monitor functions */ + int (*lm_set) (struct vme_lm_resource *, unsigned long long, u32, u32); + int (*lm_get) (struct vme_lm_resource *, unsigned long long *, u32 *, + u32 *); + int (*lm_attach) (struct vme_lm_resource *, int, void (*callback)(int)); + int (*lm_detach) (struct vme_lm_resource *, int); + + /* CR/CSR space functions */ + int (*slot_get) (struct vme_bridge *); + + /* Bridge parent interface */ + void *(*alloc_consistent)(struct device *dev, size_t size, + dma_addr_t *dma); + void (*free_consistent)(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma); +}; + +void vme_irq_handler(struct vme_bridge *, int, int); + +int vme_register_bridge(struct vme_bridge *); +void vme_unregister_bridge(struct vme_bridge *); + +#endif /* _VME_BRIDGE_H_ */ diff --git a/include/linux/vme.h b/include/linux/vme.h new file mode 100644 index 0000000..c9d65bf --- /dev/null +++ b/include/linux/vme.h @@ -0,0 +1,174 @@ +#ifndef _VME_H_ +#define _VME_H_ + +/* Resource Type */ +enum vme_resource_type { + VME_MASTER, + VME_SLAVE, + VME_DMA, + VME_LM +}; + +/* VME Address Spaces */ +#define VME_A16 0x1 +#define VME_A24 0x2 +#define VME_A32 0x4 +#define VME_A64 0x8 +#define VME_CRCSR 0x10 +#define VME_USER1 0x20 +#define VME_USER2 0x40 +#define VME_USER3 0x80 +#define VME_USER4 0x100 + +#define VME_A16_MAX 0x10000ULL +#define VME_A24_MAX 0x1000000ULL +#define VME_A32_MAX 0x100000000ULL +#define VME_A64_MAX 0x10000000000000000ULL +#define VME_CRCSR_MAX 0x1000000ULL + + +/* VME Cycle Types */ +#define VME_SCT 0x1 +#define VME_BLT 0x2 +#define VME_MBLT 0x4 +#define VME_2eVME 0x8 +#define VME_2eSST 0x10 +#define VME_2eSSTB 0x20 + +#define VME_2eSST160 0x100 +#define VME_2eSST267 0x200 +#define VME_2eSST320 0x400 + +#define VME_SUPER 0x1000 +#define VME_USER 0x2000 +#define VME_PROG 0x4000 +#define VME_DATA 0x8000 + +/* VME Data Widths */ +#define VME_D8 0x1 +#define VME_D16 0x2 +#define VME_D32 0x4 +#define VME_D64 0x8 + +/* Arbitration Scheduling Modes */ +#define VME_R_ROBIN_MODE 0x1 +#define VME_PRIORITY_MODE 0x2 + +#define VME_DMA_PATTERN (1<<0) +#define VME_DMA_PCI (1<<1) +#define VME_DMA_VME (1<<2) + +#define VME_DMA_PATTERN_BYTE (1<<0) +#define VME_DMA_PATTERN_WORD (1<<1) +#define VME_DMA_PATTERN_INCREMENT (1<<2) + +#define VME_DMA_VME_TO_MEM (1<<0) +#define VME_DMA_MEM_TO_VME (1<<1) +#define VME_DMA_VME_TO_VME (1<<2) +#define VME_DMA_MEM_TO_MEM (1<<3) +#define VME_DMA_PATTERN_TO_VME (1<<4) +#define VME_DMA_PATTERN_TO_MEM (1<<5) + +struct vme_dma_attr { + u32 type; + void *private; +}; + +struct vme_resource { + enum vme_resource_type type; + struct list_head *entry; +}; + +extern struct bus_type vme_bus_type; + +/* VME_MAX_BRIDGES comes from the type of vme_bus_numbers */ +#define VME_MAX_BRIDGES (sizeof(unsigned int)*8) +#define VME_MAX_SLOTS 32 + +#define VME_SLOT_CURRENT -1 +#define VME_SLOT_ALL -2 + +/** + * Structure representing a VME device + * @num: The device number + * @bridge: Pointer to the bridge device this device is on + * @dev: Internal device structure + * @drv_list: List of devices (per driver) + * @bridge_list: List of devices (per bridge) + */ +struct vme_dev { + int num; + struct vme_bridge *bridge; + struct device dev; + struct list_head drv_list; + struct list_head bridge_list; +}; + +struct vme_driver { + struct list_head node; + const char *name; + int (*match)(struct vme_dev *); + int (*probe)(struct vme_dev *); + int (*remove)(struct vme_dev *); + void (*shutdown)(void); + struct device_driver driver; + struct list_head devices; +}; + +void *vme_alloc_consistent(struct vme_resource *, size_t, dma_addr_t *); +void vme_free_consistent(struct vme_resource *, size_t, void *, + dma_addr_t); + +size_t vme_get_size(struct vme_resource *); + +struct vme_resource *vme_slave_request(struct vme_dev *, u32, u32); +int vme_slave_set(struct vme_resource *, int, unsigned long long, + unsigned long long, dma_addr_t, u32, u32); +int vme_slave_get(struct vme_resource *, int *, unsigned long long *, + unsigned long long *, dma_addr_t *, u32 *, u32 *); +void vme_slave_free(struct vme_resource *); + +struct vme_resource *vme_master_request(struct vme_dev *, u32, u32, u32); +int vme_master_set(struct vme_resource *, int, unsigned long long, + unsigned long long, u32, u32, u32); +int vme_master_get(struct vme_resource *, int *, unsigned long long *, + unsigned long long *, u32 *, u32 *, u32 *); +ssize_t vme_master_read(struct vme_resource *, void *, size_t, loff_t); +ssize_t vme_master_write(struct vme_resource *, void *, size_t, loff_t); +unsigned int vme_master_rmw(struct vme_resource *, unsigned int, unsigned int, + unsigned int, loff_t); +void vme_master_free(struct vme_resource *); + +struct vme_resource *vme_dma_request(struct vme_dev *, u32); +struct vme_dma_list *vme_new_dma_list(struct vme_resource *); +struct vme_dma_attr *vme_dma_pattern_attribute(u32, u32); +struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t); +struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long, u32, u32, u32); +void vme_dma_free_attribute(struct vme_dma_attr *); +int vme_dma_list_add(struct vme_dma_list *, struct vme_dma_attr *, + struct vme_dma_attr *, size_t); +int vme_dma_list_exec(struct vme_dma_list *); +int vme_dma_list_free(struct vme_dma_list *); +int vme_dma_free(struct vme_resource *); + +int vme_irq_request(struct vme_dev *, int, int, + void (*callback)(int, int, void *), void *); +void vme_irq_free(struct vme_dev *, int, int); +int vme_irq_generate(struct vme_dev *, int, int); + +struct vme_resource *vme_lm_request(struct vme_dev *); +int vme_lm_count(struct vme_resource *); +int vme_lm_set(struct vme_resource *, unsigned long long, u32, u32); +int vme_lm_get(struct vme_resource *, unsigned long long *, u32 *, u32 *); +int vme_lm_attach(struct vme_resource *, int, void (*callback)(int)); +int vme_lm_detach(struct vme_resource *, int); +void vme_lm_free(struct vme_resource *); + +int vme_slot_get(struct vme_dev *); + +int vme_register_driver(struct vme_driver *, unsigned int); +void vme_unregister_driver(struct vme_driver *); + + +#endif /* _VME_H_ */ + -- cgit v0.10.2 From 5d4a6789d5957a6388ea86c811d7c09bbe5f8ebd Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Thu, 26 Apr 2012 22:10:51 +0200 Subject: staging: iio: lpc32xx-adc: Remove driver conflict due to device tree Previously, the touchscreen and ADC drivers of the LPC32xx SoC had a Kconfig conflict declared because they use the same hardware. Upon the introduction of device tree support in both drivers, the conflict must be removed to enable the same kernel to support different hardware (configured via the device tree). Signed-off-by: Roland Stigge Acked-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index ec006e7..9ae5467 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -195,12 +195,14 @@ config MAX1363_RING_BUFFER config LPC32XX_ADC tristate "NXP LPC32XX ADC" - depends on ARCH_LPC32XX && !TOUCHSCREEN_LPC32XX + depends on ARCH_LPC32XX help Say yes here to build support for the integrated ADC inside the LPC32XX SoC. Note that this feature uses the same hardware as the - touchscreen driver, so you can only select one of the two drivers - (lpc32xx_adc or lpc32xx_ts). Provides direct access via sysfs. + touchscreen driver, so you should either select only one of the two + drivers (lpc32xx_adc or lpc32xx_ts) or, in the OpenFirmware case, + activate only one via device tree selection. Provides direct access + via sysfs. config SPEAR_ADC tristate "ST SPEAr ADC" -- cgit v0.10.2 From 7cbb753701d11f3c71e8543e1ae0fc0772edac06 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 26 Apr 2012 13:35:01 +0200 Subject: staging:iio: Streamline API function naming Currently we use two different naming schemes in the IIO API, iio_verb_object and iio_object_verb. E.g iio_device_register and iio_allocate_device. This patches renames instances of the later to the former. The patch also renames allocate to alloc as this seems to be the preferred form throughout the kernel. In particular the following renames are performed by the patch: iio_put_device -> iio_device_put iio_allocate_device -> iio_device_alloc iio_free_device -> iio_device_free iio_get_trigger -> iio_trigger_get iio_put_trigger -> iio_trigger_put iio_allocate_trigger -> iio_trigger_alloc iio_free_trigger -> iio_trigger_free The conversion was done with the following coccinelle patch with manual fixes to comments and documentation. @@ @@ -iio_put_device +iio_device_put @@ @@ -iio_allocate_device +iio_device_alloc @@ @@ -iio_free_device +iio_device_free @@ @@ -iio_get_trigger +iio_trigger_get @@ @@ -iio_put_trigger +iio_trigger_put @@ @@ -iio_allocate_trigger +iio_trigger_alloc @@ @@ -iio_free_trigger +iio_trigger_free Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index dd1a6a2..e8e280d 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -737,7 +737,7 @@ static struct device_type iio_dev_type = { .release = iio_dev_release, }; -struct iio_dev *iio_allocate_device(int sizeof_priv) +struct iio_dev *iio_device_alloc(int sizeof_priv) { struct iio_dev *dev; size_t alloc_size; @@ -773,16 +773,16 @@ struct iio_dev *iio_allocate_device(int sizeof_priv) return dev; } -EXPORT_SYMBOL(iio_allocate_device); +EXPORT_SYMBOL(iio_device_alloc); -void iio_free_device(struct iio_dev *dev) +void iio_device_free(struct iio_dev *dev) { if (dev) { ida_simple_remove(&iio_ida, dev->id); kfree(dev); } } -EXPORT_SYMBOL(iio_free_device); +EXPORT_SYMBOL(iio_device_free); /** * iio_chrdev_open() - chrdev file open for buffer access and ioctls diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index 03fee2e..1dbd7b8 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -360,9 +360,9 @@ static ssize_t iio_trigger_write_current(struct device *dev, indio_dev->trig = trig; if (oldtrig && indio_dev->trig != oldtrig) - iio_put_trigger(oldtrig); + iio_trigger_put(oldtrig); if (indio_dev->trig) - iio_get_trigger(indio_dev->trig); + iio_trigger_get(indio_dev->trig); return len; } @@ -426,7 +426,7 @@ static void iio_trig_subirqunmask(struct irq_data *d) trig->subirqs[d->irq - trig->subirq_base].enabled = true; } -struct iio_trigger *iio_allocate_trigger(const char *fmt, ...) +struct iio_trigger *iio_trigger_alloc(const char *fmt, ...) { va_list vargs; struct iio_trigger *trig; @@ -472,14 +472,14 @@ struct iio_trigger *iio_allocate_trigger(const char *fmt, ...) } return trig; } -EXPORT_SYMBOL(iio_allocate_trigger); +EXPORT_SYMBOL(iio_trigger_alloc); -void iio_free_trigger(struct iio_trigger *trig) +void iio_trigger_free(struct iio_trigger *trig) { if (trig) put_device(&trig->dev); } -EXPORT_SYMBOL(iio_free_trigger); +EXPORT_SYMBOL(iio_trigger_free); void iio_device_register_trigger_consumer(struct iio_dev *indio_dev) { @@ -491,7 +491,7 @@ void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev) { /* Clean up and associated but not attached triggers references */ if (indio_dev->trig) - iio_put_trigger(indio_dev->trig); + iio_trigger_put(indio_dev->trig); } int iio_triggered_buffer_postenable(struct iio_dev *indio_dev) diff --git a/drivers/staging/iio/Documentation/device.txt b/drivers/staging/iio/Documentation/device.txt index 8926f24..0338c7c 100644 --- a/drivers/staging/iio/Documentation/device.txt +++ b/drivers/staging/iio/Documentation/device.txt @@ -8,7 +8,7 @@ The crucial structure for device drivers in iio is iio_dev. First allocate one using: -struct iio_dev *indio_dev = iio_allocate_device(sizeof(struct chip_state)); +struct iio_dev *indio_dev = iio_device_alloc(sizeof(struct chip_state)); where chip_state is a structure of local state data for this instance of the chip. @@ -78,4 +78,4 @@ be registered afterwards (otherwise the whole parentage of devices gets confused) On remove, iio_device_unregister(indio_dev) will remove the device from -the core, and iio_free_device will clean up. +the core, and iio_device_free will clean up. diff --git a/drivers/staging/iio/Documentation/trigger.txt b/drivers/staging/iio/Documentation/trigger.txt index fc2012e..75cc37f 100644 --- a/drivers/staging/iio/Documentation/trigger.txt +++ b/drivers/staging/iio/Documentation/trigger.txt @@ -5,7 +5,7 @@ an IIO device. Whilst this can create device specific complexities such triggers are registered with the core in the same way as stand-alone triggers. -struct iio_trig *trig = iio_allocate_trigger("", ...); +struct iio_trig *trig = iio_trigger_alloc("", ...); allocates a trigger structure. The key elements to then fill in within a driver are: diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c index 9dce7b8..6266780 100644 --- a/drivers/staging/iio/accel/adis16201_core.c +++ b/drivers/staging/iio/accel/adis16201_core.c @@ -532,7 +532,7 @@ static int __devinit adis16201_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -587,7 +587,7 @@ error_uninitialize_ring: error_unreg_ring_funcs: adis16201_unconfigure_ring(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -600,7 +600,7 @@ static int adis16201_remove(struct spi_device *spi) adis16201_remove_trigger(indio_dev); iio_buffer_unregister(indio_dev); adis16201_unconfigure_ring(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/accel/adis16201_trigger.c b/drivers/staging/iio/accel/adis16201_trigger.c index da687e0..96fdabb 100644 --- a/drivers/staging/iio/accel/adis16201_trigger.c +++ b/drivers/staging/iio/accel/adis16201_trigger.c @@ -29,7 +29,7 @@ int adis16201_probe_trigger(struct iio_dev *indio_dev) int ret; struct adis16201_state *st = iio_priv(indio_dev); - st->trig = iio_allocate_trigger("adis16201-dev%d", indio_dev->id); + st->trig = iio_trigger_alloc("adis16201-dev%d", indio_dev->id); if (st->trig == NULL) { ret = -ENOMEM; goto error_ret; @@ -56,7 +56,7 @@ int adis16201_probe_trigger(struct iio_dev *indio_dev) error_free_irq: free_irq(st->us->irq, st->trig); error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -67,5 +67,5 @@ void adis16201_remove_trigger(struct iio_dev *indio_dev) iio_trigger_unregister(state->trig); free_irq(state->us->irq, state->trig); - iio_free_trigger(state->trig); + iio_trigger_free(state->trig); } diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c index cf1a0e5..42d7eea 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_core.c @@ -469,7 +469,7 @@ static int __devinit adis16203_probe(struct spi_device *spi) struct adis16203_state *st; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -523,7 +523,7 @@ error_uninitialize_ring: error_unreg_ring_funcs: adis16203_unconfigure_ring(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -536,7 +536,7 @@ static int adis16203_remove(struct spi_device *spi) adis16203_remove_trigger(indio_dev); iio_buffer_unregister(indio_dev); adis16203_unconfigure_ring(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/accel/adis16203_trigger.c b/drivers/staging/iio/accel/adis16203_trigger.c index 1e1b981e..b8a0407 100644 --- a/drivers/staging/iio/accel/adis16203_trigger.c +++ b/drivers/staging/iio/accel/adis16203_trigger.c @@ -29,7 +29,7 @@ int adis16203_probe_trigger(struct iio_dev *indio_dev) int ret; struct adis16203_state *st = iio_priv(indio_dev); - st->trig = iio_allocate_trigger("adis16203-dev%d", indio_dev->id); + st->trig = iio_trigger_alloc("adis16203-dev%d", indio_dev->id); if (st->trig == NULL) { ret = -ENOMEM; goto error_ret; @@ -58,7 +58,7 @@ int adis16203_probe_trigger(struct iio_dev *indio_dev) error_free_irq: free_irq(st->us->irq, st->trig); error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -69,5 +69,5 @@ void adis16203_remove_trigger(struct iio_dev *indio_dev) iio_trigger_unregister(st->trig); free_irq(st->us->irq, st->trig); - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); } diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index 2a15d71..eacda58 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -545,7 +545,7 @@ static int __devinit adis16204_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -598,7 +598,7 @@ error_uninitialize_ring: error_unreg_ring_funcs: adis16204_unconfigure_ring(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -611,7 +611,7 @@ static int adis16204_remove(struct spi_device *spi) adis16204_remove_trigger(indio_dev); iio_buffer_unregister(indio_dev); adis16204_unconfigure_ring(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/accel/adis16204_trigger.c b/drivers/staging/iio/accel/adis16204_trigger.c index e6f2937..408a168 100644 --- a/drivers/staging/iio/accel/adis16204_trigger.c +++ b/drivers/staging/iio/accel/adis16204_trigger.c @@ -29,7 +29,7 @@ int adis16204_probe_trigger(struct iio_dev *indio_dev) int ret; struct adis16204_state *st = iio_priv(indio_dev); - st->trig = iio_allocate_trigger("adis16204-dev%d", indio_dev->id); + st->trig = iio_trigger_alloc("adis16204-dev%d", indio_dev->id); if (st->trig == NULL) { ret = -ENOMEM; goto error_ret; @@ -58,7 +58,7 @@ int adis16204_probe_trigger(struct iio_dev *indio_dev) error_free_irq: free_irq(st->us->irq, st->trig); error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -69,5 +69,5 @@ void adis16204_remove_trigger(struct iio_dev *indio_dev) iio_trigger_unregister(state->trig); free_irq(state->us->irq, state->trig); - iio_free_trigger(state->trig); + iio_trigger_free(state->trig); } diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index cad4113..8e8dbe6 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -544,7 +544,7 @@ static int __devinit adis16209_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -597,7 +597,7 @@ error_uninitialize_ring: error_unreg_ring_funcs: adis16209_unconfigure_ring(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -612,7 +612,7 @@ static int adis16209_remove(struct spi_device *spi) adis16209_remove_trigger(indio_dev); iio_buffer_unregister(indio_dev); adis16209_unconfigure_ring(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/accel/adis16209_trigger.c b/drivers/staging/iio/accel/adis16209_trigger.c index 5f5dbed..2ad93dc 100644 --- a/drivers/staging/iio/accel/adis16209_trigger.c +++ b/drivers/staging/iio/accel/adis16209_trigger.c @@ -38,7 +38,7 @@ int adis16209_probe_trigger(struct iio_dev *indio_dev) int ret; struct adis16209_state *st = iio_priv(indio_dev); - st->trig = iio_allocate_trigger("adis16209-dev%d", indio_dev->id); + st->trig = iio_trigger_alloc("adis16209-dev%d", indio_dev->id); if (st->trig == NULL) { ret = -ENOMEM; goto error_ret; @@ -66,7 +66,7 @@ int adis16209_probe_trigger(struct iio_dev *indio_dev) error_free_irq: free_irq(st->us->irq, st->trig); error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -77,5 +77,5 @@ void adis16209_remove_trigger(struct iio_dev *indio_dev) iio_trigger_unregister(st->trig); free_irq(st->us->irq, st->trig); - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); } diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index c86a3db..e8c513d 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -634,7 +634,7 @@ static int __devinit adis16220_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -685,7 +685,7 @@ error_rm_accel_bin: error_unregister_dev: iio_device_unregister(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -700,7 +700,7 @@ static int adis16220_remove(struct spi_device *spi) sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc1_bin); sysfs_remove_bin_file(&indio_dev->dev.kobj, &accel_bin); iio_device_unregister(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index fcc2c19..f043bbd 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -578,7 +578,7 @@ static int __devinit adis16240_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -631,7 +631,7 @@ error_uninitialize_ring: error_unreg_ring_funcs: adis16240_unconfigure_ring(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -647,7 +647,7 @@ static int adis16240_remove(struct spi_device *spi) adis16240_remove_trigger(indio_dev); iio_buffer_unregister(indio_dev); adis16240_unconfigure_ring(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/accel/adis16240_trigger.c b/drivers/staging/iio/accel/adis16240_trigger.c index 53eda35..fa90a22 100644 --- a/drivers/staging/iio/accel/adis16240_trigger.c +++ b/drivers/staging/iio/accel/adis16240_trigger.c @@ -38,7 +38,7 @@ int adis16240_probe_trigger(struct iio_dev *indio_dev) int ret; struct adis16240_state *st = iio_priv(indio_dev); - st->trig = iio_allocate_trigger("adis16240-dev%d", indio_dev->id); + st->trig = iio_trigger_alloc("adis16240-dev%d", indio_dev->id); if (st->trig == NULL) { ret = -ENOMEM; goto error_ret; @@ -67,7 +67,7 @@ int adis16240_probe_trigger(struct iio_dev *indio_dev) error_free_irq: free_irq(st->us->irq, st->trig); error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -78,5 +78,5 @@ void adis16240_remove_trigger(struct iio_dev *indio_dev) iio_trigger_unregister(st->trig); free_irq(st->us->irq, st->trig); - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); } diff --git a/drivers/staging/iio/accel/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c index 3292390..8cf7cd9 100644 --- a/drivers/staging/iio/accel/kxsd9.c +++ b/drivers/staging/iio/accel/kxsd9.c @@ -228,7 +228,7 @@ static int __devinit kxsd9_probe(struct spi_device *spi) struct kxsd9_state *st; int ret = 0; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -256,7 +256,7 @@ static int __devinit kxsd9_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -264,7 +264,7 @@ error_ret: static int __devexit kxsd9_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index bbef0be..a778043 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -680,7 +680,7 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi) struct lis3l02dq_state *st; struct iio_dev *indio_dev; - indio_dev = iio_allocate_device(sizeof *st); + indio_dev = iio_device_alloc(sizeof *st); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -748,7 +748,7 @@ error_uninitialize_buffer: error_unreg_buffer_funcs: lis3l02dq_unconfigure_buffer(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -803,7 +803,7 @@ static int lis3l02dq_remove(struct spi_device *spi) iio_buffer_unregister(indio_dev); lis3l02dq_unconfigure_buffer(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); err_ret: return ret; } diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index c8b8164..9306f93 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -286,7 +286,7 @@ int lis3l02dq_probe_trigger(struct iio_dev *indio_dev) int ret; struct lis3l02dq_state *st = iio_priv(indio_dev); - st->trig = iio_allocate_trigger("lis3l02dq-dev%d", indio_dev->id); + st->trig = iio_trigger_alloc("lis3l02dq-dev%d", indio_dev->id); if (!st->trig) { ret = -ENOMEM; goto error_ret; @@ -302,7 +302,7 @@ int lis3l02dq_probe_trigger(struct iio_dev *indio_dev) return 0; error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -312,7 +312,7 @@ void lis3l02dq_remove_trigger(struct iio_dev *indio_dev) struct lis3l02dq_state *st = iio_priv(indio_dev); iio_trigger_unregister(st->trig); - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); } void lis3l02dq_unconfigure_buffer(struct iio_dev *indio_dev) diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index 2ee5eb0..3c5aea5 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -1145,7 +1145,7 @@ static int __devinit sca3000_probe(struct spi_device *spi) struct sca3000_state *st; struct iio_dev *indio_dev; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -1209,7 +1209,7 @@ error_unregister_ring: error_unregister_dev: iio_device_unregister(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; @@ -1247,7 +1247,7 @@ static int sca3000_remove(struct spi_device *spi) iio_device_unregister(indio_dev); iio_buffer_unregister(indio_dev); sca3000_unconfigure_ring(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 14f9834..7b44705 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -604,7 +604,7 @@ static int ad7192_probe_trigger(struct iio_dev *indio_dev) struct ad7192_state *st = iio_priv(indio_dev); int ret; - st->trig = iio_allocate_trigger("%s-dev%d", + st->trig = iio_trigger_alloc("%s-dev%d", spi_get_device_id(st->spi)->name, indio_dev->id); if (st->trig == NULL) { @@ -637,7 +637,7 @@ static int ad7192_probe_trigger(struct iio_dev *indio_dev) error_free_irq: free_irq(st->spi->irq, indio_dev); error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -648,7 +648,7 @@ static void ad7192_remove_trigger(struct iio_dev *indio_dev) iio_trigger_unregister(st->trig); free_irq(st->spi->irq, indio_dev); - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); } static ssize_t ad7192_read_frequency(struct device *dev, @@ -1024,7 +1024,7 @@ static int __devinit ad7192_probe(struct spi_device *spi) return -ENODEV; } - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -1105,7 +1105,7 @@ error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c index d72780f..9c3b66f 100644 --- a/drivers/staging/iio/adc/ad7280a.c +++ b/drivers/staging/iio/adc/ad7280a.c @@ -839,7 +839,7 @@ static int __devinit ad7280_probe(struct spi_device *spi) int ret; const unsigned short tACQ_ns[4] = {465, 1010, 1460, 1890}; const unsigned short nAVG[4] = {1, 2, 4, 8}; - struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); + struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -945,7 +945,7 @@ error_free_channels: kfree(st->channels); error_free_device: - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -964,7 +964,7 @@ static int __devexit ad7280_remove(struct spi_device *spi) kfree(st->channels); kfree(st->iio_attr); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c index b8e4fe6..a987c20 100644 --- a/drivers/staging/iio/adc/ad7291.c +++ b/drivers/staging/iio/adc/ad7291.c @@ -587,7 +587,7 @@ static int __devinit ad7291_probe(struct i2c_client *client, struct iio_dev *indio_dev; int ret = 0, voltage_uv = 0; - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -669,7 +669,7 @@ error_put_reg: if (!IS_ERR(chip->reg)) regulator_put(chip->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -689,7 +689,7 @@ static int __devexit ad7291_remove(struct i2c_client *client) regulator_put(chip->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c index 974a8e3..c90f2b3 100644 --- a/drivers/staging/iio/adc/ad7298_core.c +++ b/drivers/staging/iio/adc/ad7298_core.c @@ -179,7 +179,7 @@ static int __devinit ad7298_probe(struct spi_device *spi) struct ad7298_platform_data *pdata = spi->dev.platform_data; struct ad7298_state *st; int ret; - struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); + struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -252,7 +252,7 @@ error_disable_reg: error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -269,7 +269,7 @@ static int __devexit ad7298_remove(struct spi_device *spi) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c index 1241b9f..be1c260 100644 --- a/drivers/staging/iio/adc/ad7476_core.c +++ b/drivers/staging/iio/adc/ad7476_core.c @@ -128,7 +128,7 @@ static int __devinit ad7476_probe(struct spi_device *spi) struct iio_dev *indio_dev; int ret, voltage_uv = 0; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -198,7 +198,7 @@ error_disable_reg: error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; @@ -216,7 +216,7 @@ static int ad7476_remove(struct spi_device *spi) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c index 9c54064..f82d36c 100644 --- a/drivers/staging/iio/adc/ad7606_core.c +++ b/drivers/staging/iio/adc/ad7606_core.c @@ -461,7 +461,7 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq, struct ad7606_platform_data *pdata = dev->platform_data; struct ad7606_state *st; int ret; - struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); + struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; @@ -560,7 +560,7 @@ error_disable_reg: error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ERR_PTR(ret); } @@ -580,7 +580,7 @@ int ad7606_remove(struct iio_dev *indio_dev, int irq) } ad7606_free_gpios(st); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c index a8e661e..1ece2ac 100644 --- a/drivers/staging/iio/adc/ad7780.c +++ b/drivers/staging/iio/adc/ad7780.c @@ -187,7 +187,7 @@ static int __devinit ad7780_probe(struct spi_device *spi) return -ENODEV; } - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -265,7 +265,7 @@ error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -282,7 +282,7 @@ static int ad7780_remove(struct spi_device *spi) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index 3a7d1a7..8ffdd80 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -469,7 +469,7 @@ static int ad7793_probe_trigger(struct iio_dev *indio_dev) struct ad7793_state *st = iio_priv(indio_dev); int ret; - st->trig = iio_allocate_trigger("%s-dev%d", + st->trig = iio_trigger_alloc("%s-dev%d", spi_get_device_id(st->spi)->name, indio_dev->id); if (st->trig == NULL) { @@ -503,7 +503,7 @@ static int ad7793_probe_trigger(struct iio_dev *indio_dev) error_free_irq: free_irq(st->spi->irq, indio_dev); error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -514,7 +514,7 @@ static void ad7793_remove_trigger(struct iio_dev *indio_dev) iio_trigger_unregister(st->trig); free_irq(st->spi->irq, indio_dev); - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); } static const u16 sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39, 33, 19, @@ -904,7 +904,7 @@ static int __devinit ad7793_probe(struct spi_device *spi) return -ENODEV; } - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -988,7 +988,7 @@ error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -1008,7 +1008,7 @@ static int ad7793_remove(struct spi_device *spi) regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c index 586f6c2..c97da5b 100644 --- a/drivers/staging/iio/adc/ad7816.c +++ b/drivers/staging/iio/adc/ad7816.c @@ -354,7 +354,7 @@ static int __devinit ad7816_probe(struct spi_device *spi_dev) return -EINVAL; } - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -426,7 +426,7 @@ error_free_gpio_convert: error_free_gpio_rdwr: gpio_free(chip->rdwr_pin); error_free_device: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -443,7 +443,7 @@ static int __devexit ad7816_remove(struct spi_device *spi_dev) gpio_free(chip->busy_pin); gpio_free(chip->convert_pin); gpio_free(chip->rdwr_pin); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c index fef9169..7186074 100644 --- a/drivers/staging/iio/adc/ad7887_core.c +++ b/drivers/staging/iio/adc/ad7887_core.c @@ -106,7 +106,7 @@ static int __devinit ad7887_probe(struct spi_device *spi) struct ad7887_platform_data *pdata = spi->dev.platform_data; struct ad7887_state *st; int ret, voltage_uv = 0; - struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); + struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -222,7 +222,7 @@ error_disable_reg: error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -239,7 +239,7 @@ static int ad7887_remove(struct spi_device *spi) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c index 561ae17..cc637b5 100644 --- a/drivers/staging/iio/adc/ad799x_core.c +++ b/drivers/staging/iio/adc/ad799x_core.c @@ -847,7 +847,7 @@ static int __devinit ad799x_probe(struct i2c_client *client, int ret; struct ad799x_platform_data *pdata = client->dev.platform_data; struct ad799x_state *st; - struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); + struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -920,7 +920,7 @@ error_disable_reg: error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -940,7 +940,7 @@ static __devexit int ad799x_remove(struct i2c_client *client) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/adt7310.c b/drivers/staging/iio/adc/adt7310.c index 223aea5..ba4e571 100644 --- a/drivers/staging/iio/adc/adt7310.c +++ b/drivers/staging/iio/adc/adt7310.c @@ -753,7 +753,7 @@ static int __devinit adt7310_probe(struct spi_device *spi_dev) unsigned long *adt7310_platform_data = spi_dev->dev.platform_data; unsigned long irq_flags; - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -833,7 +833,7 @@ error_unreg_int_irq: error_unreg_ct_irq: free_irq(spi_dev->irq, indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -849,7 +849,7 @@ static int __devexit adt7310_remove(struct spi_device *spi_dev) free_irq(adt7310_platform_data[0], indio_dev); if (spi_dev->irq) free_irq(spi_dev->irq, indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c index dab4a5a..2d4b5c6 100644 --- a/drivers/staging/iio/adc/adt7410.c +++ b/drivers/staging/iio/adc/adt7410.c @@ -721,7 +721,7 @@ static int __devinit adt7410_probe(struct i2c_client *client, int ret = 0; unsigned long *adt7410_platform_data = client->dev.platform_data; - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -797,7 +797,7 @@ error_unreg_int_irq: error_unreg_ct_irq: free_irq(client->irq, indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -812,7 +812,7 @@ static int __devexit adt7410_remove(struct i2c_client *client) free_irq(adt7410_platform_data[0], indio_dev); if (client->irq) free_irq(client->irq, indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/lpc32xx_adc.c b/drivers/staging/iio/adc/lpc32xx_adc.c index 0ddd917..9690306 100644 --- a/drivers/staging/iio/adc/lpc32xx_adc.c +++ b/drivers/staging/iio/adc/lpc32xx_adc.c @@ -141,7 +141,7 @@ static int __devinit lpc32xx_adc_probe(struct platform_device *pdev) goto errout1; } - iodev = iio_allocate_device(sizeof(struct lpc32xx_adc_info)); + iodev = iio_device_alloc(sizeof(struct lpc32xx_adc_info)); if (!iodev) { dev_err(&pdev->dev, "failed allocating iio device\n"); retval = -ENOMEM; @@ -202,7 +202,7 @@ errout4: errout3: iounmap(info->adc_base); errout2: - iio_free_device(iodev); + iio_device_free(iodev); errout1: return retval; } @@ -218,7 +218,7 @@ static int __devexit lpc32xx_adc_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); clk_put(info->clk); iounmap(info->adc_base); - iio_free_device(iodev); + iio_device_free(iodev); return 0; } diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index 7ab871c..572a500 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -1287,7 +1287,7 @@ static int __devinit max1363_probe(struct i2c_client *client, if (ret) goto error_put_reg; - indio_dev = iio_allocate_device(sizeof(struct max1363_state)); + indio_dev = iio_device_alloc(sizeof(struct max1363_state)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_disable_reg; @@ -1358,7 +1358,7 @@ error_free_available_scan_masks: error_unregister_map: iio_map_array_unregister(indio_dev, client->dev.platform_data); error_free_device: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_disable_reg: regulator_disable(reg); error_put_reg: @@ -1384,7 +1384,7 @@ static int max1363_remove(struct i2c_client *client) regulator_put(reg); } iio_map_array_unregister(indio_dev, client->dev.platform_data); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c index 2b4e1eb..8c6013f 100644 --- a/drivers/staging/iio/adc/spear_adc.c +++ b/drivers/staging/iio/adc/spear_adc.c @@ -300,7 +300,7 @@ static int __devinit spear_adc_probe(struct platform_device *pdev) int ret = -ENODEV; int irq; - iodev = iio_allocate_device(sizeof(struct spear_adc_info)); + iodev = iio_device_alloc(sizeof(struct spear_adc_info)); if (!iodev) { dev_err(dev, "failed allocating iio device\n"); ret = -ENOMEM; @@ -404,7 +404,7 @@ errout4: errout3: iounmap(info->adc_base_spear6xx); errout2: - iio_free_device(iodev); + iio_device_free(iodev); errout1: return ret; } @@ -420,7 +420,7 @@ static int __devexit spear_adc_remove(struct platform_device *pdev) clk_unprepare(info->clk); clk_put(info->clk); iounmap(info->adc_base_spear6xx); - iio_free_device(iodev); + iio_device_free(iodev); return 0; } diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c index f469ab3..5aba804 100644 --- a/drivers/staging/iio/addac/adt7316.c +++ b/drivers/staging/iio/addac/adt7316.c @@ -2133,7 +2133,7 @@ int __devinit adt7316_probe(struct device *dev, struct adt7316_bus *bus, unsigned short *adt7316_platform_data = dev->platform_data; int ret = 0; - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -2210,7 +2210,7 @@ int __devinit adt7316_probe(struct device *dev, struct adt7316_bus *bus, error_unreg_irq: free_irq(chip->bus.irq, indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -2224,7 +2224,7 @@ int __devexit adt7316_remove(struct device *dev) iio_device_unregister(indio_dev); if (chip->bus.irq) free_irq(chip->bus.irq, indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/cdc/ad7150.c b/drivers/staging/iio/cdc/ad7150.c index c0ccbc5..1447076 100644 --- a/drivers/staging/iio/cdc/ad7150.c +++ b/drivers/staging/iio/cdc/ad7150.c @@ -558,7 +558,7 @@ static int __devinit ad7150_probe(struct i2c_client *client, struct ad7150_chip_info *chip; struct iio_dev *indio_dev; - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -621,7 +621,7 @@ error_free_irq: if (client->irq) free_irq(client->irq, indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -637,7 +637,7 @@ static int __devexit ad7150_remove(struct i2c_client *client) if (client->dev.platform_data) free_irq(*(unsigned int *)client->dev.platform_data, indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/cdc/ad7152.c b/drivers/staging/iio/cdc/ad7152.c index ea40359..195d907 100644 --- a/drivers/staging/iio/cdc/ad7152.c +++ b/drivers/staging/iio/cdc/ad7152.c @@ -481,7 +481,7 @@ static int __devinit ad7152_probe(struct i2c_client *client, struct ad7152_chip_info *chip; struct iio_dev *indio_dev; - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -513,7 +513,7 @@ static int __devinit ad7152_probe(struct i2c_client *client, return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -523,7 +523,7 @@ static int __devexit ad7152_remove(struct i2c_client *client) struct iio_dev *indio_dev = i2c_get_clientdata(client); iio_device_unregister(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c index 74a889a..e936831 100644 --- a/drivers/staging/iio/cdc/ad7746.c +++ b/drivers/staging/iio/cdc/ad7746.c @@ -703,7 +703,7 @@ static int __devinit ad7746_probe(struct i2c_client *client, int ret = 0; unsigned char regval = 0; - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -763,7 +763,7 @@ static int __devinit ad7746_probe(struct i2c_client *client, return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -773,7 +773,7 @@ static int __devexit ad7746_remove(struct i2c_client *client) struct iio_dev *indio_dev = i2c_get_clientdata(client); iio_device_unregister(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dac/ad5064.c b/drivers/staging/iio/dac/ad5064.c index c0fad4f..bce641a 100644 --- a/drivers/staging/iio/dac/ad5064.c +++ b/drivers/staging/iio/dac/ad5064.c @@ -443,7 +443,7 @@ static int __devinit ad5064_probe(struct spi_device *spi) unsigned int i; int ret; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -500,7 +500,7 @@ error_free_reg: if (!st->use_internal_vref) regulator_bulk_free(ad5064_num_vref(st), st->vref_reg); error_free: - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -518,7 +518,7 @@ static int __devexit ad5064_remove(struct spi_device *spi) regulator_bulk_free(ad5064_num_vref(st), st->vref_reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dac/ad5360.c b/drivers/staging/iio/dac/ad5360.c index 0978dd2..26cac42 100644 --- a/drivers/staging/iio/dac/ad5360.c +++ b/drivers/staging/iio/dac/ad5360.c @@ -465,7 +465,7 @@ static int __devinit ad5360_probe(struct spi_device *spi) unsigned int i; int ret; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { dev_err(&spi->dev, "Failed to allocate iio device\n"); return -ENOMEM; @@ -520,7 +520,7 @@ error_free_reg: error_free_channels: kfree(indio_dev->channels); error_free: - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -537,7 +537,7 @@ static int __devexit ad5360_remove(struct spi_device *spi) regulator_bulk_disable(st->chip_info->num_vrefs, st->vref_reg); regulator_bulk_free(st->chip_info->num_vrefs, st->vref_reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dac/ad5380.c b/drivers/staging/iio/dac/ad5380.c index aa077e6..4afb099 100644 --- a/drivers/staging/iio/dac/ad5380.c +++ b/drivers/staging/iio/dac/ad5380.c @@ -389,7 +389,7 @@ static int __devinit ad5380_probe(struct device *dev, struct regmap *regmap, unsigned int ctrl = 0; int ret; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { dev_err(dev, "Failed to allocate iio device\n"); ret = -ENOMEM; @@ -455,7 +455,7 @@ error_free_reg: kfree(indio_dev->channels); error_free: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_regmap_exit: regmap_exit(regmap); @@ -477,7 +477,7 @@ static int __devexit ad5380_remove(struct device *dev) } regmap_exit(st->regmap); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dac/ad5421.c b/drivers/staging/iio/dac/ad5421.c index b1a893c..ffbd4c2 100644 --- a/drivers/staging/iio/dac/ad5421.c +++ b/drivers/staging/iio/dac/ad5421.c @@ -457,7 +457,7 @@ static int __devinit ad5421_probe(struct spi_device *spi) struct ad5421_state *st; int ret; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { dev_err(&spi->dev, "Failed to allocate iio device\n"); return -ENOMEM; @@ -512,7 +512,7 @@ error_free_irq: if (spi->irq) free_irq(spi->irq, indio_dev); error_free: - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -524,7 +524,7 @@ static int __devexit ad5421_remove(struct spi_device *spi) iio_device_unregister(indio_dev); if (spi->irq) free_irq(spi->irq, indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index 62ad1d5..3b2551f 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -296,7 +296,7 @@ static int __devinit ad5446_probe(struct spi_device *spi) voltage_uv = regulator_get_voltage(reg); } - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_disable_reg; @@ -331,7 +331,7 @@ static int __devinit ad5446_probe(struct spi_device *spi) return 0; error_free_device: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_disable_reg: if (!IS_ERR(reg)) regulator_disable(reg); @@ -352,7 +352,7 @@ static int ad5446_remove(struct spi_device *spi) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dac/ad5504.c b/drivers/staging/iio/dac/ad5504.c index 18fc391..e47f4d0 100644 --- a/drivers/staging/iio/dac/ad5504.c +++ b/drivers/staging/iio/dac/ad5504.c @@ -288,7 +288,7 @@ static int __devinit ad5504_probe(struct spi_device *spi) struct regulator *reg; int ret, voltage_uv = 0; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -351,7 +351,7 @@ error_put_reg: if (!IS_ERR(reg)) regulator_put(reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -369,7 +369,7 @@ static int __devexit ad5504_remove(struct spi_device *spi) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c index c7786c1..cde4a9f 100644 --- a/drivers/staging/iio/dac/ad5624r_spi.c +++ b/drivers/staging/iio/dac/ad5624r_spi.c @@ -256,7 +256,7 @@ static int __devinit ad5624r_probe(struct spi_device *spi) struct iio_dev *indio_dev; int ret, voltage_uv = 0; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -306,7 +306,7 @@ error_disable_reg: error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; @@ -322,7 +322,7 @@ static int __devexit ad5624r_remove(struct spi_device *spi) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dac/ad5686.c b/drivers/staging/iio/dac/ad5686.c index 86c8691..6a74436 100644 --- a/drivers/staging/iio/dac/ad5686.c +++ b/drivers/staging/iio/dac/ad5686.c @@ -359,7 +359,7 @@ static int __devinit ad5686_probe(struct spi_device *spi) struct iio_dev *indio_dev; int ret, regdone = 0, voltage_uv = 0; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -411,7 +411,7 @@ error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -426,7 +426,7 @@ static int __devexit ad5686_remove(struct spi_device *spi) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dac/ad5764.c b/drivers/staging/iio/dac/ad5764.c index b01d7ee..03dbd93 100644 --- a/drivers/staging/iio/dac/ad5764.c +++ b/drivers/staging/iio/dac/ad5764.c @@ -281,7 +281,7 @@ static int __devinit ad5764_probe(struct spi_device *spi) struct ad5764_state *st; int ret; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { dev_err(&spi->dev, "Failed to allocate iio device\n"); return -ENOMEM; @@ -336,7 +336,7 @@ error_free_reg: if (st->chip_info->int_vref == 0) regulator_bulk_free(ARRAY_SIZE(st->vref_reg), st->vref_reg); error_free: - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -353,7 +353,7 @@ static int __devexit ad5764_remove(struct spi_device *spi) regulator_bulk_free(ARRAY_SIZE(st->vref_reg), st->vref_reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dac/ad5791.c b/drivers/staging/iio/dac/ad5791.c index c013868..1cc75e6 100644 --- a/drivers/staging/iio/dac/ad5791.c +++ b/drivers/staging/iio/dac/ad5791.c @@ -289,7 +289,7 @@ static int __devinit ad5791_probe(struct spi_device *spi) struct ad5791_state *st; int ret, pos_voltage_uv = 0, neg_voltage_uv = 0; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -369,7 +369,7 @@ error_put_reg_neg: error_put_reg_pos: if (!IS_ERR(st->reg_vdd)) regulator_put(st->reg_vdd); - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; @@ -390,7 +390,7 @@ static int __devexit ad5791_remove(struct spi_device *spi) regulator_disable(st->reg_vss); regulator_put(st->reg_vss); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dac/max517.c b/drivers/staging/iio/dac/max517.c index 373127c..a3f588df 100644 --- a/drivers/staging/iio/dac/max517.c +++ b/drivers/staging/iio/dac/max517.c @@ -218,7 +218,7 @@ static int max517_probe(struct i2c_client *client, struct max517_platform_data *platform_data = client->dev.platform_data; int err; - indio_dev = iio_allocate_device(sizeof(*data)); + indio_dev = iio_device_alloc(sizeof(*data)); if (indio_dev == NULL) { err = -ENOMEM; goto exit; @@ -257,14 +257,14 @@ static int max517_probe(struct i2c_client *client, return 0; exit_free_device: - iio_free_device(indio_dev); + iio_device_free(indio_dev); exit: return err; } static int max517_remove(struct i2c_client *client) { - iio_free_device(i2c_get_clientdata(client)); + iio_device_free(i2c_get_clientdata(client)); return 0; } diff --git a/drivers/staging/iio/dds/ad5930.c b/drivers/staging/iio/dds/ad5930.c index 6df4d86..97542fc 100644 --- a/drivers/staging/iio/dds/ad5930.c +++ b/drivers/staging/iio/dds/ad5930.c @@ -97,7 +97,7 @@ static int __devinit ad5930_probe(struct spi_device *spi) struct iio_dev *idev; int ret = 0; - idev = iio_allocate_device(sizeof(*st)); + idev = iio_device_alloc(sizeof(*st)); if (idev == NULL) { ret = -ENOMEM; goto error_ret; @@ -122,7 +122,7 @@ static int __devinit ad5930_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(idev); + iio_device_free(idev); error_ret: return ret; } @@ -130,7 +130,7 @@ error_ret: static int __devexit ad5930_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/dds/ad9832.c b/drivers/staging/iio/dds/ad9832.c index 57627ff..7a9b723 100644 --- a/drivers/staging/iio/dds/ad9832.c +++ b/drivers/staging/iio/dds/ad9832.c @@ -221,7 +221,7 @@ static int __devinit ad9832_probe(struct spi_device *spi) goto error_put_reg; } - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_disable_reg; @@ -313,7 +313,7 @@ static int __devinit ad9832_probe(struct spi_device *spi) return 0; error_free_device: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_disable_reg: if (!IS_ERR(reg)) regulator_disable(reg); @@ -334,7 +334,7 @@ static int __devexit ad9832_remove(struct spi_device *spi) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dds/ad9834.c b/drivers/staging/iio/dds/ad9834.c index 9b2c879..b8ef8d9 100644 --- a/drivers/staging/iio/dds/ad9834.c +++ b/drivers/staging/iio/dds/ad9834.c @@ -334,7 +334,7 @@ static int __devinit ad9834_probe(struct spi_device *spi) goto error_put_reg; } - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_disable_reg; @@ -414,7 +414,7 @@ static int __devinit ad9834_probe(struct spi_device *spi) return 0; error_free_device: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_disable_reg: if (!IS_ERR(reg)) regulator_disable(reg); @@ -434,7 +434,7 @@ static int __devexit ad9834_remove(struct spi_device *spi) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dds/ad9850.c b/drivers/staging/iio/dds/ad9850.c index cc7a87d..39f12a6 100644 --- a/drivers/staging/iio/dds/ad9850.c +++ b/drivers/staging/iio/dds/ad9850.c @@ -83,7 +83,7 @@ static int __devinit ad9850_probe(struct spi_device *spi) struct iio_dev *idev; int ret = 0; - idev = iio_allocate_device(sizeof(*st)); + idev = iio_device_alloc(sizeof(*st)); if (idev == NULL) { ret = -ENOMEM; goto error_ret; @@ -108,7 +108,7 @@ static int __devinit ad9850_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(idev); + iio_device_free(idev); error_ret: return ret; } @@ -116,7 +116,7 @@ error_ret: static int __devexit ad9850_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/dds/ad9852.c b/drivers/staging/iio/dds/ad9852.c index 2f8df7b..58d4bf8 100644 --- a/drivers/staging/iio/dds/ad9852.c +++ b/drivers/staging/iio/dds/ad9852.c @@ -232,7 +232,7 @@ static int __devinit ad9852_probe(struct spi_device *spi) struct iio_dev *idev; int ret = 0; - idev = iio_allocate_device(sizeof(*st)); + idev = iio_device_alloc(sizeof(*st)); if (idev == NULL) { ret = -ENOMEM; goto error_ret; @@ -258,7 +258,7 @@ static int __devinit ad9852_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(idev); + iio_device_free(idev); error_ret: return ret; @@ -267,7 +267,7 @@ error_ret: static int __devexit ad9852_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/dds/ad9910.c b/drivers/staging/iio/dds/ad9910.c index e91efc5..6e7a97e 100644 --- a/drivers/staging/iio/dds/ad9910.c +++ b/drivers/staging/iio/dds/ad9910.c @@ -367,7 +367,7 @@ static int __devinit ad9910_probe(struct spi_device *spi) struct iio_dev *idev; int ret = 0; - idev = iio_allocate_device(sizeof(*st)); + idev = iio_device_alloc(sizeof(*st)); if (idev == NULL) { ret = -ENOMEM; goto error_ret; @@ -392,7 +392,7 @@ static int __devinit ad9910_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(idev); + iio_device_free(idev); error_ret: return ret; } @@ -400,7 +400,7 @@ error_ret: static int __devexit ad9910_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/dds/ad9951.c b/drivers/staging/iio/dds/ad9951.c index ca1d311..19ba721 100644 --- a/drivers/staging/iio/dds/ad9951.c +++ b/drivers/staging/iio/dds/ad9951.c @@ -176,7 +176,7 @@ static int __devinit ad9951_probe(struct spi_device *spi) struct iio_dev *idev; int ret = 0; - idev = iio_allocate_device(sizeof(*st)); + idev = iio_device_alloc(sizeof(*st)); if (idev == NULL) { ret = -ENOMEM; goto error_ret; @@ -202,7 +202,7 @@ static int __devinit ad9951_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(idev); + iio_device_free(idev); error_ret: return ret; @@ -211,7 +211,7 @@ error_ret: static int __devexit ad9951_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c index 08aaf27..9931e20 100644 --- a/drivers/staging/iio/gyro/adis16060_core.c +++ b/drivers/staging/iio/gyro/adis16060_core.c @@ -152,7 +152,7 @@ static int __devinit adis16060_r_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -178,7 +178,7 @@ static int __devinit adis16060_r_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -187,7 +187,7 @@ error_ret: static int adis16060_r_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c index 7e3695b..11f1dcc 100644 --- a/drivers/staging/iio/gyro/adis16080_core.c +++ b/drivers/staging/iio/gyro/adis16080_core.c @@ -145,7 +145,7 @@ static int __devinit adis16080_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -171,7 +171,7 @@ static int __devinit adis16080_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -180,7 +180,7 @@ error_ret: static int adis16080_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/gyro/adis16130_core.c b/drivers/staging/iio/gyro/adis16130_core.c index 98aa1b9..bf61cd0 100644 --- a/drivers/staging/iio/gyro/adis16130_core.c +++ b/drivers/staging/iio/gyro/adis16130_core.c @@ -123,7 +123,7 @@ static int __devinit adis16130_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -147,7 +147,7 @@ static int __devinit adis16130_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; @@ -157,7 +157,7 @@ error_ret: static int adis16130_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index 15253be..d7979cf 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -627,7 +627,7 @@ static int __devinit adis16260_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -712,7 +712,7 @@ error_uninitialize_ring: error_unreg_ring_funcs: adis16260_unconfigure_ring(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -733,7 +733,7 @@ static int adis16260_remove(struct spi_device *spi) adis16260_remove_trigger(indio_dev); iio_buffer_unregister(indio_dev); adis16260_unconfigure_ring(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); err_ret: return ret; diff --git a/drivers/staging/iio/gyro/adis16260_trigger.c b/drivers/staging/iio/gyro/adis16260_trigger.c index dc56f32..034559e 100644 --- a/drivers/staging/iio/gyro/adis16260_trigger.c +++ b/drivers/staging/iio/gyro/adis16260_trigger.c @@ -29,7 +29,7 @@ int adis16260_probe_trigger(struct iio_dev *indio_dev) int ret; struct adis16260_state *st = iio_priv(indio_dev); - st->trig = iio_allocate_trigger("%s-dev%d", + st->trig = iio_trigger_alloc("%s-dev%d", spi_get_device_id(st->us)->name, indio_dev->id); if (st->trig == NULL) { @@ -60,7 +60,7 @@ int adis16260_probe_trigger(struct iio_dev *indio_dev) error_free_irq: free_irq(st->us->irq, st->trig); error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -71,5 +71,5 @@ void adis16260_remove_trigger(struct iio_dev *indio_dev) iio_trigger_unregister(st->trig); free_irq(st->us->irq, st->trig); - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); } diff --git a/drivers/staging/iio/gyro/adxrs450_core.c b/drivers/staging/iio/gyro/adxrs450_core.c index 06a9e97..6513119 100644 --- a/drivers/staging/iio/gyro/adxrs450_core.c +++ b/drivers/staging/iio/gyro/adxrs450_core.c @@ -372,7 +372,7 @@ static int __devinit adxrs450_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -403,7 +403,7 @@ static int __devinit adxrs450_probe(struct spi_device *spi) error_initial: iio_device_unregister(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; @@ -412,7 +412,7 @@ error_ret: static int adxrs450_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c index fa4a653..3b4513c 100644 --- a/drivers/staging/iio/iio_simple_dummy.c +++ b/drivers/staging/iio/iio_simple_dummy.c @@ -392,7 +392,7 @@ static int __devinit iio_dummy_probe(int index) * It also has a region (accessed by iio_priv() * for chip specific state information. */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -472,7 +472,7 @@ error_unregister_events: error_free_device: /* Note free device should only be called, before registration * has succeeded. */ - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -509,7 +509,7 @@ static int iio_dummy_remove(int index) goto error_ret; /* Free all structures */ - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 9d99a7f..359a794 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -705,7 +705,7 @@ static int __devinit ad5933_probe(struct i2c_client *client, int ret, voltage_uv = 0; struct ad5933_platform_data *pdata = client->dev.platform_data; struct ad5933_state *st; - struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); + struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -784,7 +784,7 @@ error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -801,7 +801,7 @@ static __devexit int ad5933_remove(struct i2c_client *client) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index 68ecc15..5015f82 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -1161,7 +1161,7 @@ static int __devinit adis16400_probe(struct spi_device *spi) { int ret; struct adis16400_state *st; - struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); + struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -1218,7 +1218,7 @@ error_uninitialize_ring: error_unreg_ring_funcs: adis16400_unconfigure_ring(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -1237,7 +1237,7 @@ static int adis16400_remove(struct spi_device *spi) adis16400_remove_trigger(indio_dev); iio_buffer_unregister(indio_dev); adis16400_unconfigure_ring(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; diff --git a/drivers/staging/iio/imu/adis16400_trigger.c b/drivers/staging/iio/imu/adis16400_trigger.c index bd22e6c..42a678e 100644 --- a/drivers/staging/iio/imu/adis16400_trigger.c +++ b/drivers/staging/iio/imu/adis16400_trigger.c @@ -29,7 +29,7 @@ int adis16400_probe_trigger(struct iio_dev *indio_dev) int ret; struct adis16400_state *st = iio_priv(indio_dev); - st->trig = iio_allocate_trigger("%s-dev%d", + st->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name, indio_dev->id); if (st->trig == NULL) { @@ -59,7 +59,7 @@ int adis16400_probe_trigger(struct iio_dev *indio_dev) error_free_irq: free_irq(st->us->irq, st->trig); error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -70,5 +70,5 @@ void adis16400_remove_trigger(struct iio_dev *indio_dev) iio_trigger_unregister(st->trig); free_irq(st->us->irq, st->trig); - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); } diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index 92283eb..2d23c6a 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -532,7 +532,7 @@ static int __devinit isl29018_probe(struct i2c_client *client, struct iio_dev *indio_dev; int err; - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { dev_err(&client->dev, "iio allocation fails\n"); err = -ENOMEM; @@ -574,7 +574,7 @@ static int __devinit isl29018_probe(struct i2c_client *client, return 0; exit_iio_free: - iio_free_device(indio_dev); + iio_device_free(indio_dev); exit: return err; } @@ -585,7 +585,7 @@ static int __devexit isl29018_remove(struct i2c_client *client) dev_dbg(&client->dev, "%s()\n", __func__); iio_device_unregister(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c index 2ada20e..33a4c3f 100644 --- a/drivers/staging/iio/light/isl29028.c +++ b/drivers/staging/iio/light/isl29028.c @@ -482,7 +482,7 @@ static int __devinit isl29028_probe(struct i2c_client *client, struct iio_dev *indio_dev; int ret; - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (!indio_dev) { dev_err(&client->dev, "iio allocation fails\n"); return -ENOMEM; @@ -522,7 +522,7 @@ static int __devinit isl29028_probe(struct i2c_client *client, return 0; exit_iio_free: - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -531,7 +531,7 @@ static int __devexit isl29028_remove(struct i2c_client *client) struct iio_dev *indio_dev = i2c_get_clientdata(client); iio_device_unregister(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c index 6351360..9d740be 100644 --- a/drivers/staging/iio/light/tsl2563.c +++ b/drivers/staging/iio/light/tsl2563.c @@ -714,7 +714,7 @@ static int __devinit tsl2563_probe(struct i2c_client *client, int err = 0; u8 id = 0; - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (!indio_dev) return -ENOMEM; @@ -801,7 +801,7 @@ fail2: if (client->irq) free_irq(client->irq, indio_dev); fail1: - iio_free_device(indio_dev); + iio_device_free(indio_dev); return err; } @@ -822,7 +822,7 @@ static int tsl2563_remove(struct i2c_client *client) if (client->irq) free_irq(client->irq, indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/light/tsl2583.c b/drivers/staging/iio/light/tsl2583.c index 51b6362..5ff391e 100644 --- a/drivers/staging/iio/light/tsl2583.c +++ b/drivers/staging/iio/light/tsl2583.c @@ -815,7 +815,7 @@ static int __devinit taos_probe(struct i2c_client *clientp, return -EOPNOTSUPP; } - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { ret = -ENOMEM; dev_err(&clientp->dev, "iio allocation failed\n"); @@ -879,7 +879,7 @@ static int __devinit taos_probe(struct i2c_client *clientp, dev_info(&clientp->dev, "Light sensor found.\n"); return 0; fail1: - iio_free_device(indio_dev); + iio_device_free(indio_dev); fail2: return ret; } @@ -926,7 +926,7 @@ static SIMPLE_DEV_PM_OPS(taos_pm_ops, taos_suspend, taos_resume); static int __devexit taos_remove(struct i2c_client *client) { iio_device_unregister(i2c_get_clientdata(client)); - iio_free_device(i2c_get_clientdata(client)); + iio_device_free(i2c_get_clientdata(client)); return 0; } diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c index dfc3da6..efbc4d2 100755 --- a/drivers/staging/iio/light/tsl2x7x_core.c +++ b/drivers/staging/iio/light/tsl2x7x_core.c @@ -1906,7 +1906,7 @@ static int __devinit tsl2x7x_probe(struct i2c_client *clientp, struct iio_dev *indio_dev; struct tsl2X7X_chip *chip; - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (!indio_dev) return -ENOMEM; @@ -1986,7 +1986,7 @@ fail1: if (clientp->irq) free_irq(clientp->irq, indio_dev); fail2: - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -2038,7 +2038,7 @@ static int __devexit tsl2x7x_remove(struct i2c_client *client) if (client->irq) free_irq(client->irq, chip->client->name); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c index d088548c..ea2f918 100644 --- a/drivers/staging/iio/magnetometer/ak8975.c +++ b/drivers/staging/iio/magnetometer/ak8975.c @@ -504,7 +504,7 @@ static int ak8975_probe(struct i2c_client *client, } /* Register with IIO */ - indio_dev = iio_allocate_device(sizeof(*data)); + indio_dev = iio_device_alloc(sizeof(*data)); if (indio_dev == NULL) { err = -ENOMEM; goto exit_gpio; @@ -535,7 +535,7 @@ static int ak8975_probe(struct i2c_client *client, return 0; exit_free_iio: - iio_free_device(indio_dev); + iio_device_free(indio_dev); exit_gpio: if (gpio_is_valid(eoc_gpio)) gpio_free(eoc_gpio); @@ -553,7 +553,7 @@ static int ak8975_remove(struct i2c_client *client) if (gpio_is_valid(data->eoc_gpio)) gpio_free(data->eoc_gpio); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c index 3433c41..e7cc9e0 100644 --- a/drivers/staging/iio/magnetometer/hmc5843.c +++ b/drivers/staging/iio/magnetometer/hmc5843.c @@ -544,7 +544,7 @@ static int hmc5843_probe(struct i2c_client *client, struct iio_dev *indio_dev; int err = 0; - indio_dev = iio_allocate_device(sizeof(*data)); + indio_dev = iio_device_alloc(sizeof(*data)); if (indio_dev == NULL) { err = -ENOMEM; goto exit; @@ -572,7 +572,7 @@ static int hmc5843_probe(struct i2c_client *client, goto exit_free2; return 0; exit_free2: - iio_free_device(indio_dev); + iio_device_free(indio_dev); exit: return err; } @@ -584,7 +584,7 @@ static int hmc5843_remove(struct i2c_client *client) iio_device_unregister(indio_dev); /* sleep mode to save power */ hmc5843_configure(client, MODE_SLEEP); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c index 9b26ae1..280331b 100644 --- a/drivers/staging/iio/meter/ade7753.c +++ b/drivers/staging/iio/meter/ade7753.c @@ -517,7 +517,7 @@ static int __devinit ade7753_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -546,7 +546,7 @@ static int __devinit ade7753_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; @@ -564,7 +564,7 @@ static int ade7753_remove(struct spi_device *spi) if (ret) goto err_ret; - iio_free_device(indio_dev); + iio_device_free(indio_dev); err_ret: return ret; } diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index 02d10df..59a2e3e 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c @@ -540,7 +540,7 @@ static int __devinit ade7754_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -568,7 +568,7 @@ static int __devinit ade7754_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; @@ -585,7 +585,7 @@ static int ade7754_remove(struct spi_device *spi) if (ret) goto err_ret; - iio_free_device(indio_dev); + iio_device_free(indio_dev); err_ret: return ret; diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c index 4a3b429..1a5c9c4 100644 --- a/drivers/staging/iio/meter/ade7758_core.c +++ b/drivers/staging/iio/meter/ade7758_core.c @@ -885,7 +885,7 @@ static int __devinit ade7758_probe(struct spi_device *spi) { int i, ret; struct ade7758_state *st; - struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); + struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; @@ -962,7 +962,7 @@ error_free_tx: error_free_rx: kfree(st->rx); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -984,7 +984,7 @@ static int ade7758_remove(struct spi_device *spi) kfree(st->tx); kfree(st->rx); - iio_free_device(indio_dev); + iio_device_free(indio_dev); err_ret: return ret; diff --git a/drivers/staging/iio/meter/ade7758_trigger.c b/drivers/staging/iio/meter/ade7758_trigger.c index 5c48d38..f9c6a34 100644 --- a/drivers/staging/iio/meter/ade7758_trigger.c +++ b/drivers/staging/iio/meter/ade7758_trigger.c @@ -63,7 +63,7 @@ int ade7758_probe_trigger(struct iio_dev *indio_dev) struct ade7758_state *st = iio_priv(indio_dev); int ret; - st->trig = iio_allocate_trigger("%s-dev%d", + st->trig = iio_trigger_alloc("%s-dev%d", spi_get_device_id(st->us)->name, indio_dev->id); if (st->trig == NULL) { @@ -94,7 +94,7 @@ int ade7758_probe_trigger(struct iio_dev *indio_dev) error_free_irq: free_irq(st->us->irq, st->trig); error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -105,5 +105,5 @@ void ade7758_remove_trigger(struct iio_dev *indio_dev) iio_trigger_unregister(st->trig); free_irq(st->us->irq, st->trig); - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); } diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index 1f2b74a..91add54 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c @@ -463,7 +463,7 @@ static int __devinit ade7759_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -491,7 +491,7 @@ static int __devinit ade7759_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -507,7 +507,7 @@ static int ade7759_remove(struct spi_device *spi) if (ret) goto err_ret; - iio_free_device(indio_dev); + iio_device_free(indio_dev); err_ret: return ret; diff --git a/drivers/staging/iio/meter/ade7854-i2c.c b/drivers/staging/iio/meter/ade7854-i2c.c index c87c86b..527aa97 100644 --- a/drivers/staging/iio/meter/ade7854-i2c.c +++ b/drivers/staging/iio/meter/ade7854-i2c.c @@ -208,7 +208,7 @@ static int __devinit ade7854_i2c_probe(struct i2c_client *client, struct ade7854_state *st; struct iio_dev *indio_dev; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; st = iio_priv(indio_dev); @@ -226,7 +226,7 @@ static int __devinit ade7854_i2c_probe(struct i2c_client *client, ret = ade7854_probe(indio_dev, &client->dev); if (ret) - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } diff --git a/drivers/staging/iio/meter/ade7854-spi.c b/drivers/staging/iio/meter/ade7854-spi.c index 11c2cef..eaafaef 100644 --- a/drivers/staging/iio/meter/ade7854-spi.c +++ b/drivers/staging/iio/meter/ade7854-spi.c @@ -306,7 +306,7 @@ static int __devinit ade7854_spi_probe(struct spi_device *spi) struct ade7854_state *st; struct iio_dev *indio_dev; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; st = iio_priv(indio_dev); @@ -325,7 +325,7 @@ static int __devinit ade7854_spi_probe(struct spi_device *spi) ret = ade7854_probe(indio_dev, &spi->dev); if (ret) - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/meter/ade7854.c b/drivers/staging/iio/meter/ade7854.c index 2f3c1e2..fa3ba01 100644 --- a/drivers/staging/iio/meter/ade7854.c +++ b/drivers/staging/iio/meter/ade7854.c @@ -581,7 +581,7 @@ int ade7854_probe(struct iio_dev *indio_dev, struct device *dev) error_unreg_dev: iio_device_unregister(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -590,7 +590,7 @@ EXPORT_SYMBOL(ade7854_probe); int ade7854_remove(struct iio_dev *indio_dev) { iio_device_unregister(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index 48e70e9..8b71eb0 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -112,7 +112,7 @@ static int __devinit ad2s1200_probe(struct spi_device *spi) DRV_NAME, pins[pn]); goto error_ret; } - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -142,7 +142,7 @@ static int __devinit ad2s1200_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: for (--pn; pn >= 0; pn--) gpio_free(pins[pn]); @@ -152,7 +152,7 @@ error_ret: static int __devexit ad2s1200_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c index 4d580e2..a236ddb 100644 --- a/drivers/staging/iio/resolver/ad2s1210.c +++ b/drivers/staging/iio/resolver/ad2s1210.c @@ -690,7 +690,7 @@ static int __devinit ad2s1210_probe(struct spi_device *spi) if (spi->dev.platform_data == NULL) return -EINVAL; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -731,7 +731,7 @@ static int __devinit ad2s1210_probe(struct spi_device *spi) error_free_gpios: ad2s1210_free_gpios(st); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -742,7 +742,7 @@ static int __devexit ad2s1210_remove(struct spi_device *spi) iio_device_unregister(indio_dev); ad2s1210_free_gpios(iio_priv(indio_dev)); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/resolver/ad2s90.c b/drivers/staging/iio/resolver/ad2s90.c index cb68910..a805722 100644 --- a/drivers/staging/iio/resolver/ad2s90.c +++ b/drivers/staging/iio/resolver/ad2s90.c @@ -64,7 +64,7 @@ static int __devinit ad2s90_probe(struct spi_device *spi) struct ad2s90_state *st; int ret = 0; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -93,7 +93,7 @@ static int __devinit ad2s90_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -101,7 +101,7 @@ error_ret: static int __devexit ad2s90_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c index 999fd2e..f85734d 100644 --- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c +++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c @@ -172,7 +172,7 @@ static int __devinit iio_bfin_tmr_trigger_probe(struct platform_device *pdev) st->timer_num = ret; st->t = &iio_bfin_timer_code[st->timer_num]; - st->trig = iio_allocate_trigger("bfintmr%d", st->timer_num); + st->trig = iio_trigger_alloc("bfintmr%d", st->timer_num); if (!st->trig) { ret = -ENOMEM; goto out1; @@ -203,7 +203,7 @@ static int __devinit iio_bfin_tmr_trigger_probe(struct platform_device *pdev) out4: iio_trigger_unregister(st->trig); out2: - iio_put_trigger(st->trig); + iio_trigger_put(st->trig); out1: kfree(st); out: @@ -217,7 +217,7 @@ static int __devexit iio_bfin_tmr_trigger_remove(struct platform_device *pdev) disable_gptimers(st->t->bit); free_irq(st->irq, st); iio_trigger_unregister(st->trig); - iio_put_trigger(st->trig); + iio_trigger_put(st->trig); kfree(st); return 0; diff --git a/drivers/staging/iio/trigger/iio-trig-gpio.c b/drivers/staging/iio/trigger/iio-trig-gpio.c index 95fd2f7..90b2684 100644 --- a/drivers/staging/iio/trigger/iio-trig-gpio.c +++ b/drivers/staging/iio/trigger/iio-trig-gpio.c @@ -72,7 +72,7 @@ static int iio_gpio_trigger_probe(struct platform_device *pdev) for (irq = irq_res->start; irq <= irq_res->end; irq++) { - trig = iio_allocate_trigger("irqtrig%d", irq); + trig = iio_trigger_alloc("irqtrig%d", irq); if (!trig) { ret = -ENOMEM; goto error_free_completed_registrations; @@ -114,7 +114,7 @@ error_release_irq: error_free_trig_info: kfree(trig_info); error_put_trigger: - iio_put_trigger(trig); + iio_trigger_put(trig); error_free_completed_registrations: /* The rest should have been added to the iio_gpio_trigger_list */ list_for_each_entry_safe(trig, @@ -144,7 +144,7 @@ static int iio_gpio_trigger_remove(struct platform_device *pdev) iio_trigger_unregister(trig); free_irq(trig_info->irq, trig); kfree(trig_info); - iio_put_trigger(trig); + iio_trigger_put(trig); } mutex_unlock(&iio_gpio_trigger_list_lock); diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c index 2c3ccda..9f2d055 100644 --- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c +++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c @@ -112,7 +112,7 @@ static int iio_trig_periodic_rtc_probe(struct platform_device *dev) for (i = 0;; i++) { if (pdata[i] == NULL) break; - trig = iio_allocate_trigger("periodic%s", pdata[i]); + trig = iio_trigger_alloc("periodic%s", pdata[i]); if (!trig) { ret = -ENOMEM; goto error_free_completed_registrations; @@ -152,7 +152,7 @@ error_free_trig_info: kfree(trig_info); error_put_trigger_and_remove_from_list: list_del(&trig->alloc_list); - iio_put_trigger(trig); + iio_trigger_put(trig); error_free_completed_registrations: list_for_each_entry_safe(trig, trig2, diff --git a/drivers/staging/iio/trigger/iio-trig-sysfs.c b/drivers/staging/iio/trigger/iio-trig-sysfs.c index 404ef19..552763b 100644 --- a/drivers/staging/iio/trigger/iio-trig-sysfs.c +++ b/drivers/staging/iio/trigger/iio-trig-sysfs.c @@ -139,7 +139,7 @@ static int iio_sysfs_trigger_probe(int id) goto out1; } t->id = id; - t->trig = iio_allocate_trigger("sysfstrig%d", id); + t->trig = iio_trigger_alloc("sysfstrig%d", id); if (!t->trig) { ret = -ENOMEM; goto free_t; @@ -158,7 +158,7 @@ static int iio_sysfs_trigger_probe(int id) return 0; out2: - iio_put_trigger(t->trig); + iio_trigger_put(t->trig); free_t: kfree(t); out1: @@ -182,7 +182,7 @@ static int iio_sysfs_trigger_remove(int id) } iio_trigger_unregister(t->trig); - iio_free_trigger(t->trig); + iio_trigger_free(t->trig); list_del(&t->l); kfree(t); diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 9c0908a..d218339 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -400,10 +400,10 @@ int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp); extern struct bus_type iio_bus_type; /** - * iio_put_device() - reference counted deallocation of struct device + * iio_device_put() - reference counted deallocation of struct device * @dev: the iio_device containing the device **/ -static inline void iio_put_device(struct iio_dev *indio_dev) +static inline void iio_device_put(struct iio_dev *indio_dev) { if (indio_dev) put_device(&indio_dev->dev); @@ -412,10 +412,10 @@ static inline void iio_put_device(struct iio_dev *indio_dev) /* Can we make this smaller? */ #define IIO_ALIGN L1_CACHE_BYTES /** - * iio_allocate_device() - allocate an iio_dev from a driver + * iio_device_alloc() - allocate an iio_dev from a driver * @sizeof_priv: Space to allocate for private structure. **/ -struct iio_dev *iio_allocate_device(int sizeof_priv); +struct iio_dev *iio_device_alloc(int sizeof_priv); static inline void *iio_priv(const struct iio_dev *indio_dev) { @@ -429,10 +429,10 @@ static inline struct iio_dev *iio_priv_to_dev(void *priv) } /** - * iio_free_device() - free an iio_dev from a driver + * iio_device_free() - free an iio_dev from a driver * @dev: the iio_dev associated with the device **/ -void iio_free_device(struct iio_dev *indio_dev); +void iio_device_free(struct iio_dev *indio_dev); /** * iio_buffer_enabled() - helper function to test if the buffer is enabled diff --git a/include/linux/iio/trigger.h b/include/linux/iio/trigger.h index 1cfca23..a981994 100644 --- a/include/linux/iio/trigger.h +++ b/include/linux/iio/trigger.h @@ -78,13 +78,13 @@ static inline struct iio_trigger *to_iio_trigger(struct device *d) return container_of(d, struct iio_trigger, dev); }; -static inline void iio_put_trigger(struct iio_trigger *trig) +static inline void iio_trigger_put(struct iio_trigger *trig) { module_put(trig->ops->owner); put_device(&trig->dev); }; -static inline void iio_get_trigger(struct iio_trigger *trig) +static inline void iio_trigger_get(struct iio_trigger *trig) { get_device(&trig->dev); __module_get(trig->ops->owner); @@ -113,7 +113,7 @@ void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time); irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private); -__printf(1, 2) struct iio_trigger *iio_allocate_trigger(const char *fmt, ...); -void iio_free_trigger(struct iio_trigger *trig); +__printf(1, 2) struct iio_trigger *iio_trigger_alloc(const char *fmt, ...); +void iio_trigger_free(struct iio_trigger *trig); #endif /* _IIO_TRIGGER_H_ */ -- cgit v0.10.2 From e4e8d1ce81bad2c39cf738186ec559b0bebbbdde Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 27 Apr 2012 10:58:33 +0200 Subject: iio: Rename iio/dds to iio/frequency Generalize naming to allow other frequency synthesis techniques as well. No functional changes. Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index c1054a1..3c8e5ec 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig @@ -30,7 +30,7 @@ source "drivers/staging/iio/adc/Kconfig" source "drivers/staging/iio/addac/Kconfig" source "drivers/staging/iio/cdc/Kconfig" source "drivers/staging/iio/dac/Kconfig" -source "drivers/staging/iio/dds/Kconfig" +source "drivers/staging/iio/frequency/Kconfig" source "drivers/staging/iio/gyro/Kconfig" source "drivers/staging/iio/impedance-analyzer/Kconfig" source "drivers/staging/iio/imu/Kconfig" diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile index 2acd42f..6a46d5a 100644 --- a/drivers/staging/iio/Makefile +++ b/drivers/staging/iio/Makefile @@ -18,7 +18,7 @@ obj-y += adc/ obj-y += addac/ obj-y += cdc/ obj-y += dac/ -obj-y += dds/ +obj-y += frequency/ obj-y += gyro/ obj-y += impedance-analyzer/ obj-y += imu/ diff --git a/drivers/staging/iio/dds/Kconfig b/drivers/staging/iio/dds/Kconfig deleted file mode 100644 index 93b7141..0000000 --- a/drivers/staging/iio/dds/Kconfig +++ /dev/null @@ -1,61 +0,0 @@ -# -# Direct Digital Synthesis drivers -# -menu "Direct Digital Synthesis" - -config AD5930 - tristate "Analog Devices ad5930/5932 driver" - depends on SPI - help - Say yes here to build support for Analog Devices DDS chip - ad5930/ad5932, provides direct access via sysfs. - -config AD9832 - tristate "Analog Devices ad9832/5 driver" - depends on SPI - help - Say yes here to build support for Analog Devices DDS chip - AD9832 and AD9835, provides direct access via sysfs. - - To compile this driver as a module, choose M here: the - module will be called ad9832. - -config AD9834 - tristate "Analog Devices AD9833/4/7/8 driver" - depends on SPI - help - Say yes here to build support for Analog Devices DDS chip - AD9833, AD9834, AD9837 and AD9838, provides direct access via sysfs. - - To compile this driver as a module, choose M here: the - module will be called ad9834. - -config AD9850 - tristate "Analog Devices ad9850/1 driver" - depends on SPI - help - Say yes here to build support for Analog Devices DDS chip - ad9850/1, provides direct access via sysfs. - -config AD9852 - tristate "Analog Devices ad9852/4 driver" - depends on SPI - help - Say yes here to build support for Analog Devices DDS chip - ad9852/4, provides direct access via sysfs. - -config AD9910 - tristate "Analog Devices ad9910 driver" - depends on SPI - help - Say yes here to build support for Analog Devices DDS chip - ad9910, provides direct access via sysfs. - -config AD9951 - tristate "Analog Devices ad9951 driver" - depends on SPI - help - Say yes here to build support for Analog Devices DDS chip - ad9951, provides direct access via sysfs. - -endmenu diff --git a/drivers/staging/iio/dds/Makefile b/drivers/staging/iio/dds/Makefile deleted file mode 100644 index 1477461..0000000 --- a/drivers/staging/iio/dds/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for Direct Digital Synthesis drivers -# - -obj-$(CONFIG_AD5930) += ad5930.o -obj-$(CONFIG_AD9832) += ad9832.o -obj-$(CONFIG_AD9834) += ad9834.o -obj-$(CONFIG_AD9850) += ad9850.o -obj-$(CONFIG_AD9852) += ad9852.o -obj-$(CONFIG_AD9910) += ad9910.o -obj-$(CONFIG_AD9951) += ad9951.o diff --git a/drivers/staging/iio/dds/ad5930.c b/drivers/staging/iio/dds/ad5930.c deleted file mode 100644 index 97542fc..0000000 --- a/drivers/staging/iio/dds/ad5930.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Driver for ADI Direct Digital Synthesis ad5930 - * - * Copyright (c) 2010-2010 Analog Devices Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define DRV_NAME "ad5930" - -#define value_mask (u16)0xf000 -#define addr_shift 12 - -/* Register format: 4 bits addr + 12 bits value */ -struct ad5903_config { - u16 control; - u16 incnum; - u16 frqdelt[2]; - u16 incitvl; - u16 buritvl; - u16 strtfrq[2]; -}; - -struct ad5930_state { - struct mutex lock; - struct spi_device *sdev; -}; - -static ssize_t ad5930_set_parameter(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct spi_message msg; - struct spi_transfer xfer; - int ret; - struct ad5903_config *config = (struct ad5903_config *)buf; - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad5930_state *st = iio_priv(idev); - - config->control = (config->control & ~value_mask); - config->incnum = (config->control & ~value_mask) | (1 << addr_shift); - config->frqdelt[0] = (config->control & ~value_mask) | (2 << addr_shift); - config->frqdelt[1] = (config->control & ~value_mask) | 3 << addr_shift; - config->incitvl = (config->control & ~value_mask) | 4 << addr_shift; - config->buritvl = (config->control & ~value_mask) | 8 << addr_shift; - config->strtfrq[0] = (config->control & ~value_mask) | 0xc << addr_shift; - config->strtfrq[1] = (config->control & ~value_mask) | 0xd << addr_shift; - - xfer.len = len; - xfer.tx_buf = config; - mutex_lock(&st->lock); - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; -error_ret: - mutex_unlock(&st->lock); - - return ret ? ret : len; -} - -static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad5930_set_parameter, 0); - -static struct attribute *ad5930_attributes[] = { - &iio_dev_attr_dds.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad5930_attribute_group = { - .attrs = ad5930_attributes, -}; - -static const struct iio_info ad5930_info = { - .attrs = &ad5930_attribute_group, - .driver_module = THIS_MODULE, -}; - -static int __devinit ad5930_probe(struct spi_device *spi) -{ - struct ad5930_state *st; - struct iio_dev *idev; - int ret = 0; - - idev = iio_device_alloc(sizeof(*st)); - if (idev == NULL) { - ret = -ENOMEM; - goto error_ret; - } - spi_set_drvdata(spi, idev); - st = iio_priv(idev); - - mutex_init(&st->lock); - st->sdev = spi; - idev->dev.parent = &spi->dev; - idev->info = &ad5930_info; - idev->modes = INDIO_DIRECT_MODE; - - ret = iio_device_register(idev); - if (ret) - goto error_free_dev; - spi->max_speed_hz = 2000000; - spi->mode = SPI_MODE_3; - spi->bits_per_word = 16; - spi_setup(spi); - - return 0; - -error_free_dev: - iio_device_free(idev); -error_ret: - return ret; -} - -static int __devexit ad5930_remove(struct spi_device *spi) -{ - iio_device_unregister(spi_get_drvdata(spi)); - iio_device_free(spi_get_drvdata(spi)); - - return 0; -} - -static struct spi_driver ad5930_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .probe = ad5930_probe, - .remove = __devexit_p(ad5930_remove), -}; -module_spi_driver(ad5930_driver); - -MODULE_AUTHOR("Cliff Cai"); -MODULE_DESCRIPTION("Analog Devices ad5930 driver"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("spi:" DRV_NAME); diff --git a/drivers/staging/iio/dds/ad9832.c b/drivers/staging/iio/dds/ad9832.c deleted file mode 100644 index 7a9b723..0000000 --- a/drivers/staging/iio/dds/ad9832.c +++ /dev/null @@ -1,362 +0,0 @@ -/* - * AD9832 SPI DDS driver - * - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "dds.h" - -#include "ad9832.h" - -static unsigned long ad9832_calc_freqreg(unsigned long mclk, unsigned long fout) -{ - unsigned long long freqreg = (u64) fout * - (u64) ((u64) 1L << AD9832_FREQ_BITS); - do_div(freqreg, mclk); - return freqreg; -} - -static int ad9832_write_frequency(struct ad9832_state *st, - unsigned addr, unsigned long fout) -{ - unsigned long regval; - - if (fout > (st->mclk / 2)) - return -EINVAL; - - regval = ad9832_calc_freqreg(st->mclk, fout); - - st->freq_data[0] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) | - (addr << ADD_SHIFT) | - ((regval >> 24) & 0xFF)); - st->freq_data[1] = cpu_to_be16((AD9832_CMD_FRE16BITSW << CMD_SHIFT) | - ((addr - 1) << ADD_SHIFT) | - ((regval >> 16) & 0xFF)); - st->freq_data[2] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) | - ((addr - 2) << ADD_SHIFT) | - ((regval >> 8) & 0xFF)); - st->freq_data[3] = cpu_to_be16((AD9832_CMD_FRE16BITSW << CMD_SHIFT) | - ((addr - 3) << ADD_SHIFT) | - ((regval >> 0) & 0xFF)); - - return spi_sync(st->spi, &st->freq_msg); -} - -static int ad9832_write_phase(struct ad9832_state *st, - unsigned long addr, unsigned long phase) -{ - if (phase > (1 << AD9832_PHASE_BITS)) - return -EINVAL; - - st->phase_data[0] = cpu_to_be16((AD9832_CMD_PHA8BITSW << CMD_SHIFT) | - (addr << ADD_SHIFT) | - ((phase >> 8) & 0xFF)); - st->phase_data[1] = cpu_to_be16((AD9832_CMD_PHA16BITSW << CMD_SHIFT) | - ((addr - 1) << ADD_SHIFT) | - (phase & 0xFF)); - - return spi_sync(st->spi, &st->phase_msg); -} - -static ssize_t ad9832_write(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad9832_state *st = iio_priv(indio_dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int ret; - long val; - - ret = strict_strtoul(buf, 10, &val); - if (ret) - goto error_ret; - - mutex_lock(&indio_dev->mlock); - switch ((u32) this_attr->address) { - case AD9832_FREQ0HM: - case AD9832_FREQ1HM: - ret = ad9832_write_frequency(st, this_attr->address, val); - break; - case AD9832_PHASE0H: - case AD9832_PHASE1H: - case AD9832_PHASE2H: - case AD9832_PHASE3H: - ret = ad9832_write_phase(st, this_attr->address, val); - break; - case AD9832_PINCTRL_EN: - if (val) - st->ctrl_ss &= ~AD9832_SELSRC; - else - st->ctrl_ss |= AD9832_SELSRC; - st->data = cpu_to_be16((AD9832_CMD_SYNCSELSRC << CMD_SHIFT) | - st->ctrl_ss); - ret = spi_sync(st->spi, &st->msg); - break; - case AD9832_FREQ_SYM: - if (val == 1) - st->ctrl_fp |= AD9832_FREQ; - else if (val == 0) - st->ctrl_fp &= ~AD9832_FREQ; - else { - ret = -EINVAL; - break; - } - st->data = cpu_to_be16((AD9832_CMD_FPSELECT << CMD_SHIFT) | - st->ctrl_fp); - ret = spi_sync(st->spi, &st->msg); - break; - case AD9832_PHASE_SYM: - if (val < 0 || val > 3) { - ret = -EINVAL; - break; - } - - st->ctrl_fp &= ~AD9832_PHASE(3); - st->ctrl_fp |= AD9832_PHASE(val); - - st->data = cpu_to_be16((AD9832_CMD_FPSELECT << CMD_SHIFT) | - st->ctrl_fp); - ret = spi_sync(st->spi, &st->msg); - break; - case AD9832_OUTPUT_EN: - if (val) - st->ctrl_src &= ~(AD9832_RESET | AD9832_SLEEP | - AD9832_CLR); - else - st->ctrl_src |= AD9832_RESET; - - st->data = cpu_to_be16((AD9832_CMD_SLEEPRESCLR << CMD_SHIFT) | - st->ctrl_src); - ret = spi_sync(st->spi, &st->msg); - break; - default: - ret = -ENODEV; - } - mutex_unlock(&indio_dev->mlock); - -error_ret: - return ret ? ret : len; -} - -/** - * see dds.h for further information - */ - -static IIO_DEV_ATTR_FREQ(0, 0, S_IWUSR, NULL, ad9832_write, AD9832_FREQ0HM); -static IIO_DEV_ATTR_FREQ(0, 1, S_IWUSR, NULL, ad9832_write, AD9832_FREQ1HM); -static IIO_DEV_ATTR_FREQSYMBOL(0, S_IWUSR, NULL, ad9832_write, AD9832_FREQ_SYM); -static IIO_CONST_ATTR_FREQ_SCALE(0, "1"); /* 1Hz */ - -static IIO_DEV_ATTR_PHASE(0, 0, S_IWUSR, NULL, ad9832_write, AD9832_PHASE0H); -static IIO_DEV_ATTR_PHASE(0, 1, S_IWUSR, NULL, ad9832_write, AD9832_PHASE1H); -static IIO_DEV_ATTR_PHASE(0, 2, S_IWUSR, NULL, ad9832_write, AD9832_PHASE2H); -static IIO_DEV_ATTR_PHASE(0, 3, S_IWUSR, NULL, ad9832_write, AD9832_PHASE3H); -static IIO_DEV_ATTR_PHASESYMBOL(0, S_IWUSR, NULL, - ad9832_write, AD9832_PHASE_SYM); -static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808"); /* 2PI/2^12 rad*/ - -static IIO_DEV_ATTR_PINCONTROL_EN(0, S_IWUSR, NULL, - ad9832_write, AD9832_PINCTRL_EN); -static IIO_DEV_ATTR_OUT_ENABLE(0, S_IWUSR, NULL, - ad9832_write, AD9832_OUTPUT_EN); - -static struct attribute *ad9832_attributes[] = { - &iio_dev_attr_dds0_freq0.dev_attr.attr, - &iio_dev_attr_dds0_freq1.dev_attr.attr, - &iio_const_attr_dds0_freq_scale.dev_attr.attr, - &iio_dev_attr_dds0_phase0.dev_attr.attr, - &iio_dev_attr_dds0_phase1.dev_attr.attr, - &iio_dev_attr_dds0_phase2.dev_attr.attr, - &iio_dev_attr_dds0_phase3.dev_attr.attr, - &iio_const_attr_dds0_phase_scale.dev_attr.attr, - &iio_dev_attr_dds0_pincontrol_en.dev_attr.attr, - &iio_dev_attr_dds0_freqsymbol.dev_attr.attr, - &iio_dev_attr_dds0_phasesymbol.dev_attr.attr, - &iio_dev_attr_dds0_out_enable.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad9832_attribute_group = { - .attrs = ad9832_attributes, -}; - -static const struct iio_info ad9832_info = { - .attrs = &ad9832_attribute_group, - .driver_module = THIS_MODULE, -}; - -static int __devinit ad9832_probe(struct spi_device *spi) -{ - struct ad9832_platform_data *pdata = spi->dev.platform_data; - struct iio_dev *indio_dev; - struct ad9832_state *st; - struct regulator *reg; - int ret; - - if (!pdata) { - dev_dbg(&spi->dev, "no platform data?\n"); - return -ENODEV; - } - - reg = regulator_get(&spi->dev, "vcc"); - if (!IS_ERR(reg)) { - ret = regulator_enable(reg); - if (ret) - goto error_put_reg; - } - - indio_dev = iio_device_alloc(sizeof(*st)); - if (indio_dev == NULL) { - ret = -ENOMEM; - goto error_disable_reg; - } - spi_set_drvdata(spi, indio_dev); - st = iio_priv(indio_dev); - st->reg = reg; - st->mclk = pdata->mclk; - st->spi = spi; - - indio_dev->dev.parent = &spi->dev; - indio_dev->name = spi_get_device_id(spi)->name; - indio_dev->info = &ad9832_info; - indio_dev->modes = INDIO_DIRECT_MODE; - - /* Setup default messages */ - - st->xfer.tx_buf = &st->data; - st->xfer.len = 2; - - spi_message_init(&st->msg); - spi_message_add_tail(&st->xfer, &st->msg); - - st->freq_xfer[0].tx_buf = &st->freq_data[0]; - st->freq_xfer[0].len = 2; - st->freq_xfer[0].cs_change = 1; - st->freq_xfer[1].tx_buf = &st->freq_data[1]; - st->freq_xfer[1].len = 2; - st->freq_xfer[1].cs_change = 1; - st->freq_xfer[2].tx_buf = &st->freq_data[2]; - st->freq_xfer[2].len = 2; - st->freq_xfer[2].cs_change = 1; - st->freq_xfer[3].tx_buf = &st->freq_data[3]; - st->freq_xfer[3].len = 2; - - spi_message_init(&st->freq_msg); - spi_message_add_tail(&st->freq_xfer[0], &st->freq_msg); - spi_message_add_tail(&st->freq_xfer[1], &st->freq_msg); - spi_message_add_tail(&st->freq_xfer[2], &st->freq_msg); - spi_message_add_tail(&st->freq_xfer[3], &st->freq_msg); - - st->phase_xfer[0].tx_buf = &st->phase_data[0]; - st->phase_xfer[0].len = 2; - st->phase_xfer[0].cs_change = 1; - st->phase_xfer[1].tx_buf = &st->phase_data[1]; - st->phase_xfer[1].len = 2; - - spi_message_init(&st->phase_msg); - spi_message_add_tail(&st->phase_xfer[0], &st->phase_msg); - spi_message_add_tail(&st->phase_xfer[1], &st->phase_msg); - - st->ctrl_src = AD9832_SLEEP | AD9832_RESET | AD9832_CLR; - st->data = cpu_to_be16((AD9832_CMD_SLEEPRESCLR << CMD_SHIFT) | - st->ctrl_src); - ret = spi_sync(st->spi, &st->msg); - if (ret) { - dev_err(&spi->dev, "device init failed\n"); - goto error_free_device; - } - - ret = ad9832_write_frequency(st, AD9832_FREQ0HM, pdata->freq0); - if (ret) - goto error_free_device; - - ret = ad9832_write_frequency(st, AD9832_FREQ1HM, pdata->freq1); - if (ret) - goto error_free_device; - - ret = ad9832_write_phase(st, AD9832_PHASE0H, pdata->phase0); - if (ret) - goto error_free_device; - - ret = ad9832_write_phase(st, AD9832_PHASE1H, pdata->phase1); - if (ret) - goto error_free_device; - - ret = ad9832_write_phase(st, AD9832_PHASE2H, pdata->phase2); - if (ret) - goto error_free_device; - - ret = ad9832_write_phase(st, AD9832_PHASE3H, pdata->phase3); - if (ret) - goto error_free_device; - - ret = iio_device_register(indio_dev); - if (ret) - goto error_free_device; - - return 0; - -error_free_device: - iio_device_free(indio_dev); -error_disable_reg: - if (!IS_ERR(reg)) - regulator_disable(reg); -error_put_reg: - if (!IS_ERR(reg)) - regulator_put(reg); - - return ret; -} - -static int __devexit ad9832_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct ad9832_state *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - if (!IS_ERR(st->reg)) { - regulator_disable(st->reg); - regulator_put(st->reg); - } - iio_device_free(indio_dev); - - return 0; -} - -static const struct spi_device_id ad9832_id[] = { - {"ad9832", 0}, - {"ad9835", 0}, - {} -}; -MODULE_DEVICE_TABLE(spi, ad9832_id); - -static struct spi_driver ad9832_driver = { - .driver = { - .name = "ad9832", - .owner = THIS_MODULE, - }, - .probe = ad9832_probe, - .remove = __devexit_p(ad9832_remove), - .id_table = ad9832_id, -}; -module_spi_driver(ad9832_driver); - -MODULE_AUTHOR("Michael Hennerich "); -MODULE_DESCRIPTION("Analog Devices AD9832/AD9835 DDS"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/dds/ad9832.h b/drivers/staging/iio/dds/ad9832.h deleted file mode 100644 index c5b701f..0000000 --- a/drivers/staging/iio/dds/ad9832.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * AD9832 SPI DDS driver - * - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ -#ifndef IIO_DDS_AD9832_H_ -#define IIO_DDS_AD9832_H_ - -/* Registers */ - -#define AD9832_FREQ0LL 0x0 -#define AD9832_FREQ0HL 0x1 -#define AD9832_FREQ0LM 0x2 -#define AD9832_FREQ0HM 0x3 -#define AD9832_FREQ1LL 0x4 -#define AD9832_FREQ1HL 0x5 -#define AD9832_FREQ1LM 0x6 -#define AD9832_FREQ1HM 0x7 -#define AD9832_PHASE0L 0x8 -#define AD9832_PHASE0H 0x9 -#define AD9832_PHASE1L 0xA -#define AD9832_PHASE1H 0xB -#define AD9832_PHASE2L 0xC -#define AD9832_PHASE2H 0xD -#define AD9832_PHASE3L 0xE -#define AD9832_PHASE3H 0xF - -#define AD9832_PHASE_SYM 0x10 -#define AD9832_FREQ_SYM 0x11 -#define AD9832_PINCTRL_EN 0x12 -#define AD9832_OUTPUT_EN 0x13 - -/* Command Control Bits */ - -#define AD9832_CMD_PHA8BITSW 0x1 -#define AD9832_CMD_PHA16BITSW 0x0 -#define AD9832_CMD_FRE8BITSW 0x3 -#define AD9832_CMD_FRE16BITSW 0x2 -#define AD9832_CMD_FPSELECT 0x6 -#define AD9832_CMD_SYNCSELSRC 0x8 -#define AD9832_CMD_SLEEPRESCLR 0xC - -#define AD9832_FREQ (1 << 11) -#define AD9832_PHASE(x) (((x) & 3) << 9) -#define AD9832_SYNC (1 << 13) -#define AD9832_SELSRC (1 << 12) -#define AD9832_SLEEP (1 << 13) -#define AD9832_RESET (1 << 12) -#define AD9832_CLR (1 << 11) -#define CMD_SHIFT 12 -#define ADD_SHIFT 8 -#define AD9832_FREQ_BITS 32 -#define AD9832_PHASE_BITS 12 -#define RES_MASK(bits) ((1 << (bits)) - 1) - -/** - * struct ad9832_state - driver instance specific data - * @spi: spi_device - * @reg: supply regulator - * @mclk: external master clock - * @ctrl_fp: cached frequency/phase control word - * @ctrl_ss: cached sync/selsrc control word - * @ctrl_src: cached sleep/reset/clr word - * @xfer: default spi transfer - * @msg: default spi message - * @freq_xfer: tuning word spi transfer - * @freq_msg: tuning word spi message - * @phase_xfer: tuning word spi transfer - * @phase_msg: tuning word spi message - * @data: spi transmit buffer - * @phase_data: tuning word spi transmit buffer - * @freq_data: tuning word spi transmit buffer - */ - -struct ad9832_state { - struct spi_device *spi; - struct regulator *reg; - unsigned long mclk; - unsigned short ctrl_fp; - unsigned short ctrl_ss; - unsigned short ctrl_src; - struct spi_transfer xfer; - struct spi_message msg; - struct spi_transfer freq_xfer[4]; - struct spi_message freq_msg; - struct spi_transfer phase_xfer[2]; - struct spi_message phase_msg; - /* - * DMA (thus cache coherency maintenance) requires the - * transfer buffers to live in their own cache lines. - */ - union { - unsigned short freq_data[4]____cacheline_aligned; - unsigned short phase_data[2]; - unsigned short data; - }; -}; - -/* - * TODO: struct ad9832_platform_data needs to go into include/linux/iio - */ - -/** - * struct ad9832_platform_data - platform specific information - * @mclk: master clock in Hz - * @freq0: power up freq0 tuning word in Hz - * @freq1: power up freq1 tuning word in Hz - * @phase0: power up phase0 value [0..4095] correlates with 0..2PI - * @phase1: power up phase1 value [0..4095] correlates with 0..2PI - * @phase2: power up phase2 value [0..4095] correlates with 0..2PI - * @phase3: power up phase3 value [0..4095] correlates with 0..2PI - */ - -struct ad9832_platform_data { - unsigned long mclk; - unsigned long freq0; - unsigned long freq1; - unsigned short phase0; - unsigned short phase1; - unsigned short phase2; - unsigned short phase3; -}; - -#endif /* IIO_DDS_AD9832_H_ */ diff --git a/drivers/staging/iio/dds/ad9834.c b/drivers/staging/iio/dds/ad9834.c deleted file mode 100644 index b8ef8d9..0000000 --- a/drivers/staging/iio/dds/ad9834.c +++ /dev/null @@ -1,464 +0,0 @@ -/* - * AD9833/AD9834/AD9837/AD9838 SPI DDS driver - * - * Copyright 2010-2011 Analog Devices Inc. - * - * Licensed under the GPL-2. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "dds.h" - -#include "ad9834.h" - -static unsigned int ad9834_calc_freqreg(unsigned long mclk, unsigned long fout) -{ - unsigned long long freqreg = (u64) fout * (u64) (1 << AD9834_FREQ_BITS); - do_div(freqreg, mclk); - return freqreg; -} - -static int ad9834_write_frequency(struct ad9834_state *st, - unsigned long addr, unsigned long fout) -{ - unsigned long regval; - - if (fout > (st->mclk / 2)) - return -EINVAL; - - regval = ad9834_calc_freqreg(st->mclk, fout); - - st->freq_data[0] = cpu_to_be16(addr | (regval & - RES_MASK(AD9834_FREQ_BITS / 2))); - st->freq_data[1] = cpu_to_be16(addr | ((regval >> - (AD9834_FREQ_BITS / 2)) & - RES_MASK(AD9834_FREQ_BITS / 2))); - - return spi_sync(st->spi, &st->freq_msg); -} - -static int ad9834_write_phase(struct ad9834_state *st, - unsigned long addr, unsigned long phase) -{ - if (phase > (1 << AD9834_PHASE_BITS)) - return -EINVAL; - st->data = cpu_to_be16(addr | phase); - - return spi_sync(st->spi, &st->msg); -} - -static ssize_t ad9834_write(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad9834_state *st = iio_priv(indio_dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int ret; - long val; - - ret = strict_strtoul(buf, 10, &val); - if (ret) - goto error_ret; - - mutex_lock(&indio_dev->mlock); - switch ((u32) this_attr->address) { - case AD9834_REG_FREQ0: - case AD9834_REG_FREQ1: - ret = ad9834_write_frequency(st, this_attr->address, val); - break; - case AD9834_REG_PHASE0: - case AD9834_REG_PHASE1: - ret = ad9834_write_phase(st, this_attr->address, val); - break; - case AD9834_OPBITEN: - if (st->control & AD9834_MODE) { - ret = -EINVAL; /* AD9843 reserved mode */ - break; - } - - if (val) - st->control |= AD9834_OPBITEN; - else - st->control &= ~AD9834_OPBITEN; - - st->data = cpu_to_be16(AD9834_REG_CMD | st->control); - ret = spi_sync(st->spi, &st->msg); - break; - case AD9834_PIN_SW: - if (val) - st->control |= AD9834_PIN_SW; - else - st->control &= ~AD9834_PIN_SW; - st->data = cpu_to_be16(AD9834_REG_CMD | st->control); - ret = spi_sync(st->spi, &st->msg); - break; - case AD9834_FSEL: - case AD9834_PSEL: - if (val == 0) - st->control &= ~(this_attr->address | AD9834_PIN_SW); - else if (val == 1) { - st->control |= this_attr->address; - st->control &= ~AD9834_PIN_SW; - } else { - ret = -EINVAL; - break; - } - st->data = cpu_to_be16(AD9834_REG_CMD | st->control); - ret = spi_sync(st->spi, &st->msg); - break; - case AD9834_RESET: - if (val) - st->control &= ~AD9834_RESET; - else - st->control |= AD9834_RESET; - - st->data = cpu_to_be16(AD9834_REG_CMD | st->control); - ret = spi_sync(st->spi, &st->msg); - break; - default: - ret = -ENODEV; - } - mutex_unlock(&indio_dev->mlock); - -error_ret: - return ret ? ret : len; -} - -static ssize_t ad9834_store_wavetype(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad9834_state *st = iio_priv(indio_dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int ret = 0; - bool is_ad9833_7 = (st->devid == ID_AD9833) || (st->devid == ID_AD9837); - - mutex_lock(&indio_dev->mlock); - - switch ((u32) this_attr->address) { - case 0: - if (sysfs_streq(buf, "sine")) { - st->control &= ~AD9834_MODE; - if (is_ad9833_7) - st->control &= ~AD9834_OPBITEN; - } else if (sysfs_streq(buf, "triangle")) { - if (is_ad9833_7) { - st->control &= ~AD9834_OPBITEN; - st->control |= AD9834_MODE; - } else if (st->control & AD9834_OPBITEN) { - ret = -EINVAL; /* AD9843 reserved mode */ - } else { - st->control |= AD9834_MODE; - } - } else if (is_ad9833_7 && sysfs_streq(buf, "square")) { - st->control &= ~AD9834_MODE; - st->control |= AD9834_OPBITEN; - } else { - ret = -EINVAL; - } - - break; - case 1: - if (sysfs_streq(buf, "square") && - !(st->control & AD9834_MODE)) { - st->control &= ~AD9834_MODE; - st->control |= AD9834_OPBITEN; - } else { - ret = -EINVAL; - } - break; - default: - ret = -EINVAL; - break; - } - - if (!ret) { - st->data = cpu_to_be16(AD9834_REG_CMD | st->control); - ret = spi_sync(st->spi, &st->msg); - } - mutex_unlock(&indio_dev->mlock); - - return ret ? ret : len; -} - -static ssize_t ad9834_show_out0_wavetype_available(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad9834_state *st = iio_priv(indio_dev); - char *str; - - if ((st->devid == ID_AD9833) || (st->devid == ID_AD9837)) - str = "sine triangle square"; - else if (st->control & AD9834_OPBITEN) - str = "sine"; - else - str = "sine triangle"; - - return sprintf(buf, "%s\n", str); -} - - -static IIO_DEVICE_ATTR(dds0_out0_wavetype_available, S_IRUGO, - ad9834_show_out0_wavetype_available, NULL, 0); - -static ssize_t ad9834_show_out1_wavetype_available(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad9834_state *st = iio_priv(indio_dev); - char *str; - - if (st->control & AD9834_MODE) - str = ""; - else - str = "square"; - - return sprintf(buf, "%s\n", str); -} - -static IIO_DEVICE_ATTR(dds0_out1_wavetype_available, S_IRUGO, - ad9834_show_out1_wavetype_available, NULL, 0); - -/** - * see dds.h for further information - */ - -static IIO_DEV_ATTR_FREQ(0, 0, S_IWUSR, NULL, ad9834_write, AD9834_REG_FREQ0); -static IIO_DEV_ATTR_FREQ(0, 1, S_IWUSR, NULL, ad9834_write, AD9834_REG_FREQ1); -static IIO_DEV_ATTR_FREQSYMBOL(0, S_IWUSR, NULL, ad9834_write, AD9834_FSEL); -static IIO_CONST_ATTR_FREQ_SCALE(0, "1"); /* 1Hz */ - -static IIO_DEV_ATTR_PHASE(0, 0, S_IWUSR, NULL, ad9834_write, AD9834_REG_PHASE0); -static IIO_DEV_ATTR_PHASE(0, 1, S_IWUSR, NULL, ad9834_write, AD9834_REG_PHASE1); -static IIO_DEV_ATTR_PHASESYMBOL(0, S_IWUSR, NULL, ad9834_write, AD9834_PSEL); -static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808"); /* 2PI/2^12 rad*/ - -static IIO_DEV_ATTR_PINCONTROL_EN(0, S_IWUSR, NULL, - ad9834_write, AD9834_PIN_SW); -static IIO_DEV_ATTR_OUT_ENABLE(0, S_IWUSR, NULL, ad9834_write, AD9834_RESET); -static IIO_DEV_ATTR_OUTY_ENABLE(0, 1, S_IWUSR, NULL, - ad9834_write, AD9834_OPBITEN); -static IIO_DEV_ATTR_OUT_WAVETYPE(0, 0, ad9834_store_wavetype, 0); -static IIO_DEV_ATTR_OUT_WAVETYPE(0, 1, ad9834_store_wavetype, 1); - -static struct attribute *ad9834_attributes[] = { - &iio_dev_attr_dds0_freq0.dev_attr.attr, - &iio_dev_attr_dds0_freq1.dev_attr.attr, - &iio_const_attr_dds0_freq_scale.dev_attr.attr, - &iio_dev_attr_dds0_phase0.dev_attr.attr, - &iio_dev_attr_dds0_phase1.dev_attr.attr, - &iio_const_attr_dds0_phase_scale.dev_attr.attr, - &iio_dev_attr_dds0_pincontrol_en.dev_attr.attr, - &iio_dev_attr_dds0_freqsymbol.dev_attr.attr, - &iio_dev_attr_dds0_phasesymbol.dev_attr.attr, - &iio_dev_attr_dds0_out_enable.dev_attr.attr, - &iio_dev_attr_dds0_out1_enable.dev_attr.attr, - &iio_dev_attr_dds0_out0_wavetype.dev_attr.attr, - &iio_dev_attr_dds0_out1_wavetype.dev_attr.attr, - &iio_dev_attr_dds0_out0_wavetype_available.dev_attr.attr, - &iio_dev_attr_dds0_out1_wavetype_available.dev_attr.attr, - NULL, -}; - -static struct attribute *ad9833_attributes[] = { - &iio_dev_attr_dds0_freq0.dev_attr.attr, - &iio_dev_attr_dds0_freq1.dev_attr.attr, - &iio_const_attr_dds0_freq_scale.dev_attr.attr, - &iio_dev_attr_dds0_phase0.dev_attr.attr, - &iio_dev_attr_dds0_phase1.dev_attr.attr, - &iio_const_attr_dds0_phase_scale.dev_attr.attr, - &iio_dev_attr_dds0_freqsymbol.dev_attr.attr, - &iio_dev_attr_dds0_phasesymbol.dev_attr.attr, - &iio_dev_attr_dds0_out_enable.dev_attr.attr, - &iio_dev_attr_dds0_out0_wavetype.dev_attr.attr, - &iio_dev_attr_dds0_out0_wavetype_available.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad9834_attribute_group = { - .attrs = ad9834_attributes, -}; - -static const struct attribute_group ad9833_attribute_group = { - .attrs = ad9833_attributes, -}; - -static const struct iio_info ad9834_info = { - .attrs = &ad9834_attribute_group, - .driver_module = THIS_MODULE, -}; - -static const struct iio_info ad9833_info = { - .attrs = &ad9833_attribute_group, - .driver_module = THIS_MODULE, -}; - -static int __devinit ad9834_probe(struct spi_device *spi) -{ - struct ad9834_platform_data *pdata = spi->dev.platform_data; - struct ad9834_state *st; - struct iio_dev *indio_dev; - struct regulator *reg; - int ret; - - if (!pdata) { - dev_dbg(&spi->dev, "no platform data?\n"); - return -ENODEV; - } - - reg = regulator_get(&spi->dev, "vcc"); - if (!IS_ERR(reg)) { - ret = regulator_enable(reg); - if (ret) - goto error_put_reg; - } - - indio_dev = iio_device_alloc(sizeof(*st)); - if (indio_dev == NULL) { - ret = -ENOMEM; - goto error_disable_reg; - } - spi_set_drvdata(spi, indio_dev); - st = iio_priv(indio_dev); - st->mclk = pdata->mclk; - st->spi = spi; - st->devid = spi_get_device_id(spi)->driver_data; - st->reg = reg; - indio_dev->dev.parent = &spi->dev; - indio_dev->name = spi_get_device_id(spi)->name; - switch (st->devid) { - case ID_AD9833: - case ID_AD9837: - indio_dev->info = &ad9833_info; - break; - default: - indio_dev->info = &ad9834_info; - break; - } - indio_dev->modes = INDIO_DIRECT_MODE; - - /* Setup default messages */ - - st->xfer.tx_buf = &st->data; - st->xfer.len = 2; - - spi_message_init(&st->msg); - spi_message_add_tail(&st->xfer, &st->msg); - - st->freq_xfer[0].tx_buf = &st->freq_data[0]; - st->freq_xfer[0].len = 2; - st->freq_xfer[0].cs_change = 1; - st->freq_xfer[1].tx_buf = &st->freq_data[1]; - st->freq_xfer[1].len = 2; - - spi_message_init(&st->freq_msg); - spi_message_add_tail(&st->freq_xfer[0], &st->freq_msg); - spi_message_add_tail(&st->freq_xfer[1], &st->freq_msg); - - st->control = AD9834_B28 | AD9834_RESET; - - if (!pdata->en_div2) - st->control |= AD9834_DIV2; - - if (!pdata->en_signbit_msb_out && (st->devid == ID_AD9834)) - st->control |= AD9834_SIGN_PIB; - - st->data = cpu_to_be16(AD9834_REG_CMD | st->control); - ret = spi_sync(st->spi, &st->msg); - if (ret) { - dev_err(&spi->dev, "device init failed\n"); - goto error_free_device; - } - - ret = ad9834_write_frequency(st, AD9834_REG_FREQ0, pdata->freq0); - if (ret) - goto error_free_device; - - ret = ad9834_write_frequency(st, AD9834_REG_FREQ1, pdata->freq1); - if (ret) - goto error_free_device; - - ret = ad9834_write_phase(st, AD9834_REG_PHASE0, pdata->phase0); - if (ret) - goto error_free_device; - - ret = ad9834_write_phase(st, AD9834_REG_PHASE1, pdata->phase1); - if (ret) - goto error_free_device; - - ret = iio_device_register(indio_dev); - if (ret) - goto error_free_device; - - return 0; - -error_free_device: - iio_device_free(indio_dev); -error_disable_reg: - if (!IS_ERR(reg)) - regulator_disable(reg); -error_put_reg: - if (!IS_ERR(reg)) - regulator_put(reg); - return ret; -} - -static int __devexit ad9834_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct ad9834_state *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - if (!IS_ERR(st->reg)) { - regulator_disable(st->reg); - regulator_put(st->reg); - } - iio_device_free(indio_dev); - - return 0; -} - -static const struct spi_device_id ad9834_id[] = { - {"ad9833", ID_AD9833}, - {"ad9834", ID_AD9834}, - {"ad9837", ID_AD9837}, - {"ad9838", ID_AD9838}, - {} -}; -MODULE_DEVICE_TABLE(spi, ad9834_id); - -static struct spi_driver ad9834_driver = { - .driver = { - .name = "ad9834", - .owner = THIS_MODULE, - }, - .probe = ad9834_probe, - .remove = __devexit_p(ad9834_remove), - .id_table = ad9834_id, -}; -module_spi_driver(ad9834_driver); - -MODULE_AUTHOR("Michael Hennerich "); -MODULE_DESCRIPTION("Analog Devices AD9833/AD9834/AD9837/AD9838 DDS"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/dds/ad9834.h b/drivers/staging/iio/dds/ad9834.h deleted file mode 100644 index ed5ed8d..0000000 --- a/drivers/staging/iio/dds/ad9834.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * AD9833/AD9834/AD9837/AD9838 SPI DDS driver - * - * Copyright 2010-2011 Analog Devices Inc. - * - * Licensed under the GPL-2. - */ -#ifndef IIO_DDS_AD9834_H_ -#define IIO_DDS_AD9834_H_ - -/* Registers */ - -#define AD9834_REG_CMD (0 << 14) -#define AD9834_REG_FREQ0 (1 << 14) -#define AD9834_REG_FREQ1 (2 << 14) -#define AD9834_REG_PHASE0 (6 << 13) -#define AD9834_REG_PHASE1 (7 << 13) - -/* Command Control Bits */ - -#define AD9834_B28 (1 << 13) -#define AD9834_HLB (1 << 12) -#define AD9834_FSEL (1 << 11) -#define AD9834_PSEL (1 << 10) -#define AD9834_PIN_SW (1 << 9) -#define AD9834_RESET (1 << 8) -#define AD9834_SLEEP1 (1 << 7) -#define AD9834_SLEEP12 (1 << 6) -#define AD9834_OPBITEN (1 << 5) -#define AD9834_SIGN_PIB (1 << 4) -#define AD9834_DIV2 (1 << 3) -#define AD9834_MODE (1 << 1) - -#define AD9834_FREQ_BITS 28 -#define AD9834_PHASE_BITS 12 - -#define RES_MASK(bits) ((1 << (bits)) - 1) - -/** - * struct ad9834_state - driver instance specific data - * @spi: spi_device - * @reg: supply regulator - * @mclk: external master clock - * @control: cached control word - * @xfer: default spi transfer - * @msg: default spi message - * @freq_xfer: tuning word spi transfer - * @freq_msg: tuning word spi message - * @data: spi transmit buffer - * @freq_data: tuning word spi transmit buffer - */ - -struct ad9834_state { - struct spi_device *spi; - struct regulator *reg; - unsigned int mclk; - unsigned short control; - unsigned short devid; - struct spi_transfer xfer; - struct spi_message msg; - struct spi_transfer freq_xfer[2]; - struct spi_message freq_msg; - - /* - * DMA (thus cache coherency maintenance) requires the - * transfer buffers to live in their own cache lines. - */ - unsigned short data ____cacheline_aligned; - unsigned short freq_data[2] ; -}; - - -/* - * TODO: struct ad7887_platform_data needs to go into include/linux/iio - */ - -/** - * struct ad9834_platform_data - platform specific information - * @mclk: master clock in Hz - * @freq0: power up freq0 tuning word in Hz - * @freq1: power up freq1 tuning word in Hz - * @phase0: power up phase0 value [0..4095] correlates with 0..2PI - * @phase1: power up phase1 value [0..4095] correlates with 0..2PI - * @en_div2: digital output/2 is passed to the SIGN BIT OUT pin - * @en_signbit_msb_out: the MSB (or MSB/2) of the DAC data is connected to the - * SIGN BIT OUT pin. en_div2 controls whether it is the MSB - * or MSB/2 that is output. if en_signbit_msb_out=false, - * the on-board comparator is connected to SIGN BIT OUT - */ - -struct ad9834_platform_data { - unsigned int mclk; - unsigned int freq0; - unsigned int freq1; - unsigned short phase0; - unsigned short phase1; - bool en_div2; - bool en_signbit_msb_out; -}; - -/** - * ad9834_supported_device_ids: - */ - -enum ad9834_supported_device_ids { - ID_AD9833, - ID_AD9834, - ID_AD9837, - ID_AD9838, -}; - -#endif /* IIO_DDS_AD9834_H_ */ diff --git a/drivers/staging/iio/dds/ad9850.c b/drivers/staging/iio/dds/ad9850.c deleted file mode 100644 index 39f12a6..0000000 --- a/drivers/staging/iio/dds/ad9850.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Driver for ADI Direct Digital Synthesis ad9850 - * - * Copyright (c) 2010-2010 Analog Devices Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define DRV_NAME "ad9850" - -#define value_mask (u16)0xf000 -#define addr_shift 12 - -/* Register format: 4 bits addr + 12 bits value */ -struct ad9850_config { - u8 control[5]; -}; - -struct ad9850_state { - struct mutex lock; - struct spi_device *sdev; -}; - -static ssize_t ad9850_set_parameter(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct spi_message msg; - struct spi_transfer xfer; - int ret; - struct ad9850_config *config = (struct ad9850_config *)buf; - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad9850_state *st = iio_priv(idev); - - xfer.len = len; - xfer.tx_buf = config; - mutex_lock(&st->lock); - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; -error_ret: - mutex_unlock(&st->lock); - - return ret ? ret : len; -} - -static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9850_set_parameter, 0); - -static struct attribute *ad9850_attributes[] = { - &iio_dev_attr_dds.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad9850_attribute_group = { - .attrs = ad9850_attributes, -}; - -static const struct iio_info ad9850_info = { - .attrs = &ad9850_attribute_group, - .driver_module = THIS_MODULE, -}; - -static int __devinit ad9850_probe(struct spi_device *spi) -{ - struct ad9850_state *st; - struct iio_dev *idev; - int ret = 0; - - idev = iio_device_alloc(sizeof(*st)); - if (idev == NULL) { - ret = -ENOMEM; - goto error_ret; - } - spi_set_drvdata(spi, idev); - st = iio_priv(idev); - mutex_init(&st->lock); - st->sdev = spi; - - idev->dev.parent = &spi->dev; - idev->info = &ad9850_info; - idev->modes = INDIO_DIRECT_MODE; - - ret = iio_device_register(idev); - if (ret) - goto error_free_dev; - spi->max_speed_hz = 2000000; - spi->mode = SPI_MODE_3; - spi->bits_per_word = 16; - spi_setup(spi); - - return 0; - -error_free_dev: - iio_device_free(idev); -error_ret: - return ret; -} - -static int __devexit ad9850_remove(struct spi_device *spi) -{ - iio_device_unregister(spi_get_drvdata(spi)); - iio_device_free(spi_get_drvdata(spi)); - - return 0; -} - -static struct spi_driver ad9850_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .probe = ad9850_probe, - .remove = __devexit_p(ad9850_remove), -}; -module_spi_driver(ad9850_driver); - -MODULE_AUTHOR("Cliff Cai"); -MODULE_DESCRIPTION("Analog Devices ad9850 driver"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("spi:" DRV_NAME); diff --git a/drivers/staging/iio/dds/ad9852.c b/drivers/staging/iio/dds/ad9852.c deleted file mode 100644 index 58d4bf8..0000000 --- a/drivers/staging/iio/dds/ad9852.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Driver for ADI Direct Digital Synthesis ad9852 - * - * Copyright (c) 2010 Analog Devices Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define DRV_NAME "ad9852" - -#define addr_phaad1 0x0 -#define addr_phaad2 0x1 -#define addr_fretu1 0x2 -#define addr_fretu2 0x3 -#define addr_delfre 0x4 -#define addr_updclk 0x5 -#define addr_ramclk 0x6 -#define addr_contrl 0x7 -#define addr_optskm 0x8 -#define addr_optskr 0xa -#define addr_dacctl 0xb - -#define COMPPD (1 << 4) -#define REFMULT2 (1 << 2) -#define BYPPLL (1 << 5) -#define PLLRANG (1 << 6) -#define IEUPCLK (1) -#define OSKEN (1 << 5) - -#define read_bit (1 << 7) - -/* Register format: 1 byte addr + value */ -struct ad9852_config { - u8 phajst0[3]; - u8 phajst1[3]; - u8 fretun1[6]; - u8 fretun2[6]; - u8 dltafre[6]; - u8 updtclk[5]; - u8 ramprat[4]; - u8 control[5]; - u8 outpskm[3]; - u8 outpskr[2]; - u8 daccntl[3]; -}; - -struct ad9852_state { - struct mutex lock; - struct spi_device *sdev; -}; - -static ssize_t ad9852_set_parameter(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct spi_message msg; - struct spi_transfer xfer; - int ret; - struct ad9852_config *config = (struct ad9852_config *)buf; - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad9852_state *st = iio_priv(idev); - - xfer.len = 3; - xfer.tx_buf = &config->phajst0[0]; - mutex_lock(&st->lock); - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 3; - xfer.tx_buf = &config->phajst1[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 6; - xfer.tx_buf = &config->fretun1[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 6; - xfer.tx_buf = &config->fretun2[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 6; - xfer.tx_buf = &config->dltafre[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 5; - xfer.tx_buf = &config->updtclk[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 4; - xfer.tx_buf = &config->ramprat[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 5; - xfer.tx_buf = &config->control[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 3; - xfer.tx_buf = &config->outpskm[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 2; - xfer.tx_buf = &config->outpskr[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 3; - xfer.tx_buf = &config->daccntl[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; -error_ret: - mutex_unlock(&st->lock); - - return ret ? ret : len; -} - -static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9852_set_parameter, 0); - -static void ad9852_init(struct ad9852_state *st) -{ - struct spi_message msg; - struct spi_transfer xfer; - int ret; - u8 config[5]; - - config[0] = addr_contrl; - config[1] = COMPPD; - config[2] = REFMULT2 | BYPPLL | PLLRANG; - config[3] = IEUPCLK; - config[4] = OSKEN; - - mutex_lock(&st->lock); - - xfer.len = 5; - xfer.tx_buf = &config; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - -error_ret: - mutex_unlock(&st->lock); - - - -} - -static struct attribute *ad9852_attributes[] = { - &iio_dev_attr_dds.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad9852_attribute_group = { - .attrs = ad9852_attributes, -}; - -static const struct iio_info ad9852_info = { - .attrs = &ad9852_attribute_group, - .driver_module = THIS_MODULE, -}; - -static int __devinit ad9852_probe(struct spi_device *spi) -{ - struct ad9852_state *st; - struct iio_dev *idev; - int ret = 0; - - idev = iio_device_alloc(sizeof(*st)); - if (idev == NULL) { - ret = -ENOMEM; - goto error_ret; - } - st = iio_priv(idev); - spi_set_drvdata(spi, idev); - mutex_init(&st->lock); - st->sdev = spi; - - idev->dev.parent = &spi->dev; - idev->info = &ad9852_info; - idev->modes = INDIO_DIRECT_MODE; - - ret = iio_device_register(idev); - if (ret) - goto error_free_dev; - spi->max_speed_hz = 2000000; - spi->mode = SPI_MODE_3; - spi->bits_per_word = 8; - spi_setup(spi); - ad9852_init(st); - - return 0; - -error_free_dev: - iio_device_free(idev); - -error_ret: - return ret; -} - -static int __devexit ad9852_remove(struct spi_device *spi) -{ - iio_device_unregister(spi_get_drvdata(spi)); - iio_device_free(spi_get_drvdata(spi)); - - return 0; -} - -static struct spi_driver ad9852_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .probe = ad9852_probe, - .remove = __devexit_p(ad9852_remove), -}; -module_spi_driver(ad9852_driver); - -MODULE_AUTHOR("Cliff Cai"); -MODULE_DESCRIPTION("Analog Devices ad9852 driver"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("spi:" DRV_NAME); diff --git a/drivers/staging/iio/dds/ad9910.c b/drivers/staging/iio/dds/ad9910.c deleted file mode 100644 index 6e7a97e..0000000 --- a/drivers/staging/iio/dds/ad9910.c +++ /dev/null @@ -1,421 +0,0 @@ -/* - * Driver for ADI Direct Digital Synthesis ad9910 - * - * Copyright (c) 2010 Analog Devices Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define DRV_NAME "ad9910" - -#define CFR1 0x0 -#define CFR2 0x1 -#define CFR3 0x2 - -#define AUXDAC 0x3 -#define IOUPD 0x4 -#define FTW 0x7 -#define POW 0x8 -#define ASF 0x9 -#define MULTC 0x0A -#define DIG_RAMPL 0x0B -#define DIG_RAMPS 0x0C -#define DIG_RAMPR 0x0D -#define SIN_TONEP0 0x0E -#define SIN_TONEP1 0x0F -#define SIN_TONEP2 0x10 -#define SIN_TONEP3 0x11 -#define SIN_TONEP4 0x12 -#define SIN_TONEP5 0x13 -#define SIN_TONEP6 0x14 -#define SIN_TONEP7 0x15 - -#define RAM_ENABLE (1 << 7) - -#define MANUAL_OSK (1 << 7) -#define INVSIC (1 << 6) -#define DDS_SINEOP (1) - -#define AUTO_OSK (1) -#define OSKEN (1 << 1) -#define LOAD_ARR (1 << 2) -#define CLR_PHA (1 << 3) -#define CLR_DIG (1 << 4) -#define ACLR_PHA (1 << 5) -#define ACLR_DIG (1 << 6) -#define LOAD_LRR (1 << 7) - -#define LSB_FST (1) -#define SDIO_IPT (1 << 1) -#define EXT_PWD (1 << 3) -#define ADAC_PWD (1 << 4) -#define REFCLK_PWD (1 << 5) -#define DAC_PWD (1 << 6) -#define DIG_PWD (1 << 7) - -#define ENA_AMP (1) -#define READ_FTW (1) -#define DIGR_LOW (1 << 1) -#define DIGR_HIGH (1 << 2) -#define DIGR_ENA (1 << 3) -#define SYNCCLK_ENA (1 << 6) -#define ITER_IOUPD (1 << 7) - -#define TX_ENA (1 << 1) -#define PDCLK_INV (1 << 2) -#define PDCLK_ENB (1 << 3) - -#define PARA_ENA (1 << 4) -#define SYNC_DIS (1 << 5) -#define DATA_ASS (1 << 6) -#define MATCH_ENA (1 << 7) - -#define PLL_ENA (1) -#define PFD_RST (1 << 2) -#define REFCLK_RST (1 << 6) -#define REFCLK_BYP (1 << 7) - -/* Register format: 1 byte addr + value */ -struct ad9910_config { - u8 auxdac[5]; - u8 ioupd[5]; - u8 ftw[5]; - u8 pow[3]; - u8 asf[5]; - u8 multc[5]; - u8 dig_rampl[9]; - u8 dig_ramps[9]; - u8 dig_rampr[5]; - u8 sin_tonep0[9]; - u8 sin_tonep1[9]; - u8 sin_tonep2[9]; - u8 sin_tonep3[9]; - u8 sin_tonep4[9]; - u8 sin_tonep5[9]; - u8 sin_tonep6[9]; - u8 sin_tonep7[9]; -}; - -struct ad9910_state { - struct mutex lock; - struct spi_device *sdev; -}; - -static ssize_t ad9910_set_parameter(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct spi_message msg; - struct spi_transfer xfer; - int ret; - struct ad9910_config *config = (struct ad9910_config *)buf; - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad9910_state *st = iio_priv(idev); - - xfer.len = 5; - xfer.tx_buf = &config->auxdac[0]; - mutex_lock(&st->lock); - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 5; - xfer.tx_buf = &config->ioupd[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 5; - xfer.tx_buf = &config->ftw[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 3; - xfer.tx_buf = &config->pow[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 5; - xfer.tx_buf = &config->asf[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 5; - xfer.tx_buf = &config->multc[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 9; - xfer.tx_buf = &config->dig_rampl[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 9; - xfer.tx_buf = &config->dig_ramps[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 5; - xfer.tx_buf = &config->dig_rampr[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 9; - xfer.tx_buf = &config->sin_tonep0[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 9; - xfer.tx_buf = &config->sin_tonep1[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 9; - xfer.tx_buf = &config->sin_tonep2[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - xfer.len = 9; - xfer.tx_buf = &config->sin_tonep3[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 9; - xfer.tx_buf = &config->sin_tonep4[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 9; - xfer.tx_buf = &config->sin_tonep5[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 9; - xfer.tx_buf = &config->sin_tonep6[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 9; - xfer.tx_buf = &config->sin_tonep7[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; -error_ret: - mutex_unlock(&st->lock); - - return ret ? ret : len; -} - -static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9910_set_parameter, 0); - -static void ad9910_init(struct ad9910_state *st) -{ - struct spi_message msg; - struct spi_transfer xfer; - int ret; - u8 cfr[5]; - - cfr[0] = CFR1; - cfr[1] = 0; - cfr[2] = MANUAL_OSK | INVSIC | DDS_SINEOP; - cfr[3] = AUTO_OSK | OSKEN | ACLR_PHA | ACLR_DIG | LOAD_LRR; - cfr[4] = 0; - - mutex_lock(&st->lock); - - xfer.len = 5; - xfer.tx_buf = 𝔠 - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - cfr[0] = CFR2; - cfr[1] = ENA_AMP; - cfr[2] = READ_FTW | DIGR_ENA | ITER_IOUPD; - cfr[3] = TX_ENA | PDCLK_INV | PDCLK_ENB; - cfr[4] = PARA_ENA; - - xfer.len = 5; - xfer.tx_buf = 𝔠 - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - cfr[0] = CFR3; - cfr[1] = PLL_ENA; - cfr[2] = 0; - cfr[3] = REFCLK_RST | REFCLK_BYP; - cfr[4] = 0; - - xfer.len = 5; - xfer.tx_buf = 𝔠 - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - -error_ret: - mutex_unlock(&st->lock); - - - -} - -static struct attribute *ad9910_attributes[] = { - &iio_dev_attr_dds.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad9910_attribute_group = { - .attrs = ad9910_attributes, -}; - -static const struct iio_info ad9910_info = { - .attrs = &ad9910_attribute_group, - .driver_module = THIS_MODULE, -}; - -static int __devinit ad9910_probe(struct spi_device *spi) -{ - struct ad9910_state *st; - struct iio_dev *idev; - int ret = 0; - - idev = iio_device_alloc(sizeof(*st)); - if (idev == NULL) { - ret = -ENOMEM; - goto error_ret; - } - spi_set_drvdata(spi, idev); - st = iio_priv(idev); - mutex_init(&st->lock); - st->sdev = spi; - - idev->dev.parent = &spi->dev; - idev->info = &ad9910_info; - idev->modes = INDIO_DIRECT_MODE; - - ret = iio_device_register(idev); - if (ret) - goto error_free_dev; - spi->max_speed_hz = 2000000; - spi->mode = SPI_MODE_3; - spi->bits_per_word = 8; - spi_setup(spi); - ad9910_init(st); - return 0; - -error_free_dev: - iio_device_free(idev); -error_ret: - return ret; -} - -static int __devexit ad9910_remove(struct spi_device *spi) -{ - iio_device_unregister(spi_get_drvdata(spi)); - iio_device_free(spi_get_drvdata(spi)); - - return 0; -} - -static struct spi_driver ad9910_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .probe = ad9910_probe, - .remove = __devexit_p(ad9910_remove), -}; -module_spi_driver(ad9910_driver); - -MODULE_AUTHOR("Cliff Cai"); -MODULE_DESCRIPTION("Analog Devices ad9910 driver"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("spi:" DRV_NAME); diff --git a/drivers/staging/iio/dds/ad9951.c b/drivers/staging/iio/dds/ad9951.c deleted file mode 100644 index 19ba721..0000000 --- a/drivers/staging/iio/dds/ad9951.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Driver for ADI Direct Digital Synthesis ad9951 - * - * Copyright (c) 2010 Analog Devices Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define DRV_NAME "ad9951" - -#define CFR1 0x0 -#define CFR2 0x1 - -#define AUTO_OSK (1) -#define OSKEN (1 << 1) -#define LOAD_ARR (1 << 2) - -#define AUTO_SYNC (1 << 7) - -#define LSB_FST (1) -#define SDIO_IPT (1 << 1) -#define CLR_PHA (1 << 2) -#define SINE_OPT (1 << 4) -#define ACLR_PHA (1 << 5) - -#define VCO_RANGE (1 << 2) - -#define CRS_OPT (1 << 1) -#define HMANU_SYNC (1 << 2) -#define HSPD_SYNC (1 << 3) - -/* Register format: 1 byte addr + value */ -struct ad9951_config { - u8 asf[3]; - u8 arr[2]; - u8 ftw0[5]; - u8 ftw1[3]; -}; - -struct ad9951_state { - struct mutex lock; - struct spi_device *sdev; -}; - -static ssize_t ad9951_set_parameter(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct spi_message msg; - struct spi_transfer xfer; - int ret; - struct ad9951_config *config = (struct ad9951_config *)buf; - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad9951_state *st = iio_priv(idev); - - xfer.len = 3; - xfer.tx_buf = &config->asf[0]; - mutex_lock(&st->lock); - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 2; - xfer.tx_buf = &config->arr[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 5; - xfer.tx_buf = &config->ftw0[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - xfer.len = 3; - xfer.tx_buf = &config->ftw1[0]; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; -error_ret: - mutex_unlock(&st->lock); - - return ret ? ret : len; -} - -static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9951_set_parameter, 0); - -static void ad9951_init(struct ad9951_state *st) -{ - struct spi_message msg; - struct spi_transfer xfer; - int ret; - u8 cfr[5]; - - cfr[0] = CFR1; - cfr[1] = 0; - cfr[2] = LSB_FST | CLR_PHA | SINE_OPT | ACLR_PHA; - cfr[3] = AUTO_OSK | OSKEN | LOAD_ARR; - cfr[4] = 0; - - mutex_lock(&st->lock); - - xfer.len = 5; - xfer.tx_buf = 𝔠 - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - - cfr[0] = CFR2; - cfr[1] = VCO_RANGE; - cfr[2] = HSPD_SYNC; - cfr[3] = 0; - - xfer.len = 4; - xfer.tx_buf = 𝔠 - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - -error_ret: - mutex_unlock(&st->lock); - - - -} - -static struct attribute *ad9951_attributes[] = { - &iio_dev_attr_dds.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad9951_attribute_group = { - .attrs = ad9951_attributes, -}; - -static const struct iio_info ad9951_info = { - .attrs = &ad9951_attribute_group, - .driver_module = THIS_MODULE, -}; - -static int __devinit ad9951_probe(struct spi_device *spi) -{ - struct ad9951_state *st; - struct iio_dev *idev; - int ret = 0; - - idev = iio_device_alloc(sizeof(*st)); - if (idev == NULL) { - ret = -ENOMEM; - goto error_ret; - } - spi_set_drvdata(spi, idev); - st = iio_priv(idev); - mutex_init(&st->lock); - st->sdev = spi; - - idev->dev.parent = &spi->dev; - - idev->info = &ad9951_info; - idev->modes = INDIO_DIRECT_MODE; - - ret = iio_device_register(idev); - if (ret) - goto error_free_dev; - spi->max_speed_hz = 2000000; - spi->mode = SPI_MODE_3; - spi->bits_per_word = 8; - spi_setup(spi); - ad9951_init(st); - return 0; - -error_free_dev: - iio_device_free(idev); - -error_ret: - return ret; -} - -static int __devexit ad9951_remove(struct spi_device *spi) -{ - iio_device_unregister(spi_get_drvdata(spi)); - iio_device_free(spi_get_drvdata(spi)); - - return 0; -} - -static struct spi_driver ad9951_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .probe = ad9951_probe, - .remove = __devexit_p(ad9951_remove), -}; -module_spi_driver(ad9951_driver); - -MODULE_AUTHOR("Cliff Cai"); -MODULE_DESCRIPTION("Analog Devices ad9951 driver"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("spi:" DRV_NAME); diff --git a/drivers/staging/iio/dds/dds.h b/drivers/staging/iio/dds/dds.h deleted file mode 100644 index d8ac3a9..0000000 --- a/drivers/staging/iio/dds/dds.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * dds.h - sysfs attributes associated with DDS devices - * - * Copyright (c) 2010 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -/** - * /sys/bus/iio/devices/.../ddsX_freqY - */ - -#define IIO_DEV_ATTR_FREQ(_channel, _num, _mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(dds##_channel##_freq##_num, \ - _mode, _show, _store, _addr) - -/** - * /sys/bus/iio/devices/.../ddsX_freqY_scale - */ - -#define IIO_CONST_ATTR_FREQ_SCALE(_channel, _string) \ - IIO_CONST_ATTR(dds##_channel##_freq_scale, _string) - -/** - * /sys/bus/iio/devices/.../ddsX_freqsymbol - */ - -#define IIO_DEV_ATTR_FREQSYMBOL(_channel, _mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(dds##_channel##_freqsymbol, \ - _mode, _show, _store, _addr); - -/** - * /sys/bus/iio/devices/.../ddsX_phaseY - */ - -#define IIO_DEV_ATTR_PHASE(_channel, _num, _mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(dds##_channel##_phase##_num, \ - _mode, _show, _store, _addr) - -/** - * /sys/bus/iio/devices/.../ddsX_phaseY_scale - */ - -#define IIO_CONST_ATTR_PHASE_SCALE(_channel, _string) \ - IIO_CONST_ATTR(dds##_channel##_phase_scale, _string) - -/** - * /sys/bus/iio/devices/.../ddsX_phasesymbol - */ - -#define IIO_DEV_ATTR_PHASESYMBOL(_channel, _mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(dds##_channel##_phasesymbol, \ - _mode, _show, _store, _addr); - -/** - * /sys/bus/iio/devices/.../ddsX_pincontrol_en - */ - -#define IIO_DEV_ATTR_PINCONTROL_EN(_channel, _mode, _show, _store, _addr)\ - IIO_DEVICE_ATTR(dds##_channel##_pincontrol_en, \ - _mode, _show, _store, _addr); - -/** - * /sys/bus/iio/devices/.../ddsX_pincontrol_freq_en - */ - -#define IIO_DEV_ATTR_PINCONTROL_FREQ_EN(_channel, _mode, _show, _store, _addr)\ - IIO_DEVICE_ATTR(dds##_channel##_pincontrol_freq_en, \ - _mode, _show, _store, _addr); - -/** - * /sys/bus/iio/devices/.../ddsX_pincontrol_phase_en - */ - -#define IIO_DEV_ATTR_PINCONTROL_PHASE_EN(_channel, _mode, _show, _store, _addr)\ - IIO_DEVICE_ATTR(dds##_channel##_pincontrol_phase_en, \ - _mode, _show, _store, _addr); - -/** - * /sys/bus/iio/devices/.../ddsX_out_enable - */ - -#define IIO_DEV_ATTR_OUT_ENABLE(_channel, _mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(dds##_channel##_out_enable, \ - _mode, _show, _store, _addr); - -/** - * /sys/bus/iio/devices/.../ddsX_outY_enable - */ - -#define IIO_DEV_ATTR_OUTY_ENABLE(_channel, _output, \ - _mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(dds##_channel##_out##_output##_enable, \ - _mode, _show, _store, _addr); - -/** - * /sys/bus/iio/devices/.../ddsX_outY_wavetype - */ - -#define IIO_DEV_ATTR_OUT_WAVETYPE(_channel, _output, _store, _addr) \ - IIO_DEVICE_ATTR(dds##_channel##_out##_output##_wavetype, \ - S_IWUSR, NULL, _store, _addr); - -/** - * /sys/bus/iio/devices/.../ddsX_outY_wavetype_available - */ - -#define IIO_CONST_ATTR_OUT_WAVETYPES_AVAILABLE(_channel, _output, _modes)\ - IIO_CONST_ATTR(dds##_channel##_out##_output##_wavetype_available,\ - _modes); diff --git a/drivers/staging/iio/frequency/Kconfig b/drivers/staging/iio/frequency/Kconfig new file mode 100644 index 0000000..93b7141 --- /dev/null +++ b/drivers/staging/iio/frequency/Kconfig @@ -0,0 +1,61 @@ +# +# Direct Digital Synthesis drivers +# +menu "Direct Digital Synthesis" + +config AD5930 + tristate "Analog Devices ad5930/5932 driver" + depends on SPI + help + Say yes here to build support for Analog Devices DDS chip + ad5930/ad5932, provides direct access via sysfs. + +config AD9832 + tristate "Analog Devices ad9832/5 driver" + depends on SPI + help + Say yes here to build support for Analog Devices DDS chip + AD9832 and AD9835, provides direct access via sysfs. + + To compile this driver as a module, choose M here: the + module will be called ad9832. + +config AD9834 + tristate "Analog Devices AD9833/4/7/8 driver" + depends on SPI + help + Say yes here to build support for Analog Devices DDS chip + AD9833, AD9834, AD9837 and AD9838, provides direct access via sysfs. + + To compile this driver as a module, choose M here: the + module will be called ad9834. + +config AD9850 + tristate "Analog Devices ad9850/1 driver" + depends on SPI + help + Say yes here to build support for Analog Devices DDS chip + ad9850/1, provides direct access via sysfs. + +config AD9852 + tristate "Analog Devices ad9852/4 driver" + depends on SPI + help + Say yes here to build support for Analog Devices DDS chip + ad9852/4, provides direct access via sysfs. + +config AD9910 + tristate "Analog Devices ad9910 driver" + depends on SPI + help + Say yes here to build support for Analog Devices DDS chip + ad9910, provides direct access via sysfs. + +config AD9951 + tristate "Analog Devices ad9951 driver" + depends on SPI + help + Say yes here to build support for Analog Devices DDS chip + ad9951, provides direct access via sysfs. + +endmenu diff --git a/drivers/staging/iio/frequency/Makefile b/drivers/staging/iio/frequency/Makefile new file mode 100644 index 0000000..1477461 --- /dev/null +++ b/drivers/staging/iio/frequency/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for Direct Digital Synthesis drivers +# + +obj-$(CONFIG_AD5930) += ad5930.o +obj-$(CONFIG_AD9832) += ad9832.o +obj-$(CONFIG_AD9834) += ad9834.o +obj-$(CONFIG_AD9850) += ad9850.o +obj-$(CONFIG_AD9852) += ad9852.o +obj-$(CONFIG_AD9910) += ad9910.o +obj-$(CONFIG_AD9951) += ad9951.o diff --git a/drivers/staging/iio/frequency/ad5930.c b/drivers/staging/iio/frequency/ad5930.c new file mode 100644 index 0000000..97542fc --- /dev/null +++ b/drivers/staging/iio/frequency/ad5930.c @@ -0,0 +1,151 @@ +/* + * Driver for ADI Direct Digital Synthesis ad5930 + * + * Copyright (c) 2010-2010 Analog Devices Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DRV_NAME "ad5930" + +#define value_mask (u16)0xf000 +#define addr_shift 12 + +/* Register format: 4 bits addr + 12 bits value */ +struct ad5903_config { + u16 control; + u16 incnum; + u16 frqdelt[2]; + u16 incitvl; + u16 buritvl; + u16 strtfrq[2]; +}; + +struct ad5930_state { + struct mutex lock; + struct spi_device *sdev; +}; + +static ssize_t ad5930_set_parameter(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret; + struct ad5903_config *config = (struct ad5903_config *)buf; + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad5930_state *st = iio_priv(idev); + + config->control = (config->control & ~value_mask); + config->incnum = (config->control & ~value_mask) | (1 << addr_shift); + config->frqdelt[0] = (config->control & ~value_mask) | (2 << addr_shift); + config->frqdelt[1] = (config->control & ~value_mask) | 3 << addr_shift; + config->incitvl = (config->control & ~value_mask) | 4 << addr_shift; + config->buritvl = (config->control & ~value_mask) | 8 << addr_shift; + config->strtfrq[0] = (config->control & ~value_mask) | 0xc << addr_shift; + config->strtfrq[1] = (config->control & ~value_mask) | 0xd << addr_shift; + + xfer.len = len; + xfer.tx_buf = config; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; +error_ret: + mutex_unlock(&st->lock); + + return ret ? ret : len; +} + +static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad5930_set_parameter, 0); + +static struct attribute *ad5930_attributes[] = { + &iio_dev_attr_dds.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad5930_attribute_group = { + .attrs = ad5930_attributes, +}; + +static const struct iio_info ad5930_info = { + .attrs = &ad5930_attribute_group, + .driver_module = THIS_MODULE, +}; + +static int __devinit ad5930_probe(struct spi_device *spi) +{ + struct ad5930_state *st; + struct iio_dev *idev; + int ret = 0; + + idev = iio_device_alloc(sizeof(*st)); + if (idev == NULL) { + ret = -ENOMEM; + goto error_ret; + } + spi_set_drvdata(spi, idev); + st = iio_priv(idev); + + mutex_init(&st->lock); + st->sdev = spi; + idev->dev.parent = &spi->dev; + idev->info = &ad5930_info; + idev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(idev); + if (ret) + goto error_free_dev; + spi->max_speed_hz = 2000000; + spi->mode = SPI_MODE_3; + spi->bits_per_word = 16; + spi_setup(spi); + + return 0; + +error_free_dev: + iio_device_free(idev); +error_ret: + return ret; +} + +static int __devexit ad5930_remove(struct spi_device *spi) +{ + iio_device_unregister(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); + + return 0; +} + +static struct spi_driver ad5930_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = ad5930_probe, + .remove = __devexit_p(ad5930_remove), +}; +module_spi_driver(ad5930_driver); + +MODULE_AUTHOR("Cliff Cai"); +MODULE_DESCRIPTION("Analog Devices ad5930 driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("spi:" DRV_NAME); diff --git a/drivers/staging/iio/frequency/ad9832.c b/drivers/staging/iio/frequency/ad9832.c new file mode 100644 index 0000000..7a9b723 --- /dev/null +++ b/drivers/staging/iio/frequency/ad9832.c @@ -0,0 +1,362 @@ +/* + * AD9832 SPI DDS driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "dds.h" + +#include "ad9832.h" + +static unsigned long ad9832_calc_freqreg(unsigned long mclk, unsigned long fout) +{ + unsigned long long freqreg = (u64) fout * + (u64) ((u64) 1L << AD9832_FREQ_BITS); + do_div(freqreg, mclk); + return freqreg; +} + +static int ad9832_write_frequency(struct ad9832_state *st, + unsigned addr, unsigned long fout) +{ + unsigned long regval; + + if (fout > (st->mclk / 2)) + return -EINVAL; + + regval = ad9832_calc_freqreg(st->mclk, fout); + + st->freq_data[0] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) | + (addr << ADD_SHIFT) | + ((regval >> 24) & 0xFF)); + st->freq_data[1] = cpu_to_be16((AD9832_CMD_FRE16BITSW << CMD_SHIFT) | + ((addr - 1) << ADD_SHIFT) | + ((regval >> 16) & 0xFF)); + st->freq_data[2] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) | + ((addr - 2) << ADD_SHIFT) | + ((regval >> 8) & 0xFF)); + st->freq_data[3] = cpu_to_be16((AD9832_CMD_FRE16BITSW << CMD_SHIFT) | + ((addr - 3) << ADD_SHIFT) | + ((regval >> 0) & 0xFF)); + + return spi_sync(st->spi, &st->freq_msg); +} + +static int ad9832_write_phase(struct ad9832_state *st, + unsigned long addr, unsigned long phase) +{ + if (phase > (1 << AD9832_PHASE_BITS)) + return -EINVAL; + + st->phase_data[0] = cpu_to_be16((AD9832_CMD_PHA8BITSW << CMD_SHIFT) | + (addr << ADD_SHIFT) | + ((phase >> 8) & 0xFF)); + st->phase_data[1] = cpu_to_be16((AD9832_CMD_PHA16BITSW << CMD_SHIFT) | + ((addr - 1) << ADD_SHIFT) | + (phase & 0xFF)); + + return spi_sync(st->spi, &st->phase_msg); +} + +static ssize_t ad9832_write(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad9832_state *st = iio_priv(indio_dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtoul(buf, 10, &val); + if (ret) + goto error_ret; + + mutex_lock(&indio_dev->mlock); + switch ((u32) this_attr->address) { + case AD9832_FREQ0HM: + case AD9832_FREQ1HM: + ret = ad9832_write_frequency(st, this_attr->address, val); + break; + case AD9832_PHASE0H: + case AD9832_PHASE1H: + case AD9832_PHASE2H: + case AD9832_PHASE3H: + ret = ad9832_write_phase(st, this_attr->address, val); + break; + case AD9832_PINCTRL_EN: + if (val) + st->ctrl_ss &= ~AD9832_SELSRC; + else + st->ctrl_ss |= AD9832_SELSRC; + st->data = cpu_to_be16((AD9832_CMD_SYNCSELSRC << CMD_SHIFT) | + st->ctrl_ss); + ret = spi_sync(st->spi, &st->msg); + break; + case AD9832_FREQ_SYM: + if (val == 1) + st->ctrl_fp |= AD9832_FREQ; + else if (val == 0) + st->ctrl_fp &= ~AD9832_FREQ; + else { + ret = -EINVAL; + break; + } + st->data = cpu_to_be16((AD9832_CMD_FPSELECT << CMD_SHIFT) | + st->ctrl_fp); + ret = spi_sync(st->spi, &st->msg); + break; + case AD9832_PHASE_SYM: + if (val < 0 || val > 3) { + ret = -EINVAL; + break; + } + + st->ctrl_fp &= ~AD9832_PHASE(3); + st->ctrl_fp |= AD9832_PHASE(val); + + st->data = cpu_to_be16((AD9832_CMD_FPSELECT << CMD_SHIFT) | + st->ctrl_fp); + ret = spi_sync(st->spi, &st->msg); + break; + case AD9832_OUTPUT_EN: + if (val) + st->ctrl_src &= ~(AD9832_RESET | AD9832_SLEEP | + AD9832_CLR); + else + st->ctrl_src |= AD9832_RESET; + + st->data = cpu_to_be16((AD9832_CMD_SLEEPRESCLR << CMD_SHIFT) | + st->ctrl_src); + ret = spi_sync(st->spi, &st->msg); + break; + default: + ret = -ENODEV; + } + mutex_unlock(&indio_dev->mlock); + +error_ret: + return ret ? ret : len; +} + +/** + * see dds.h for further information + */ + +static IIO_DEV_ATTR_FREQ(0, 0, S_IWUSR, NULL, ad9832_write, AD9832_FREQ0HM); +static IIO_DEV_ATTR_FREQ(0, 1, S_IWUSR, NULL, ad9832_write, AD9832_FREQ1HM); +static IIO_DEV_ATTR_FREQSYMBOL(0, S_IWUSR, NULL, ad9832_write, AD9832_FREQ_SYM); +static IIO_CONST_ATTR_FREQ_SCALE(0, "1"); /* 1Hz */ + +static IIO_DEV_ATTR_PHASE(0, 0, S_IWUSR, NULL, ad9832_write, AD9832_PHASE0H); +static IIO_DEV_ATTR_PHASE(0, 1, S_IWUSR, NULL, ad9832_write, AD9832_PHASE1H); +static IIO_DEV_ATTR_PHASE(0, 2, S_IWUSR, NULL, ad9832_write, AD9832_PHASE2H); +static IIO_DEV_ATTR_PHASE(0, 3, S_IWUSR, NULL, ad9832_write, AD9832_PHASE3H); +static IIO_DEV_ATTR_PHASESYMBOL(0, S_IWUSR, NULL, + ad9832_write, AD9832_PHASE_SYM); +static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808"); /* 2PI/2^12 rad*/ + +static IIO_DEV_ATTR_PINCONTROL_EN(0, S_IWUSR, NULL, + ad9832_write, AD9832_PINCTRL_EN); +static IIO_DEV_ATTR_OUT_ENABLE(0, S_IWUSR, NULL, + ad9832_write, AD9832_OUTPUT_EN); + +static struct attribute *ad9832_attributes[] = { + &iio_dev_attr_dds0_freq0.dev_attr.attr, + &iio_dev_attr_dds0_freq1.dev_attr.attr, + &iio_const_attr_dds0_freq_scale.dev_attr.attr, + &iio_dev_attr_dds0_phase0.dev_attr.attr, + &iio_dev_attr_dds0_phase1.dev_attr.attr, + &iio_dev_attr_dds0_phase2.dev_attr.attr, + &iio_dev_attr_dds0_phase3.dev_attr.attr, + &iio_const_attr_dds0_phase_scale.dev_attr.attr, + &iio_dev_attr_dds0_pincontrol_en.dev_attr.attr, + &iio_dev_attr_dds0_freqsymbol.dev_attr.attr, + &iio_dev_attr_dds0_phasesymbol.dev_attr.attr, + &iio_dev_attr_dds0_out_enable.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad9832_attribute_group = { + .attrs = ad9832_attributes, +}; + +static const struct iio_info ad9832_info = { + .attrs = &ad9832_attribute_group, + .driver_module = THIS_MODULE, +}; + +static int __devinit ad9832_probe(struct spi_device *spi) +{ + struct ad9832_platform_data *pdata = spi->dev.platform_data; + struct iio_dev *indio_dev; + struct ad9832_state *st; + struct regulator *reg; + int ret; + + if (!pdata) { + dev_dbg(&spi->dev, "no platform data?\n"); + return -ENODEV; + } + + reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(reg)) { + ret = regulator_enable(reg); + if (ret) + goto error_put_reg; + } + + indio_dev = iio_device_alloc(sizeof(*st)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_disable_reg; + } + spi_set_drvdata(spi, indio_dev); + st = iio_priv(indio_dev); + st->reg = reg; + st->mclk = pdata->mclk; + st->spi = spi; + + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->info = &ad9832_info; + indio_dev->modes = INDIO_DIRECT_MODE; + + /* Setup default messages */ + + st->xfer.tx_buf = &st->data; + st->xfer.len = 2; + + spi_message_init(&st->msg); + spi_message_add_tail(&st->xfer, &st->msg); + + st->freq_xfer[0].tx_buf = &st->freq_data[0]; + st->freq_xfer[0].len = 2; + st->freq_xfer[0].cs_change = 1; + st->freq_xfer[1].tx_buf = &st->freq_data[1]; + st->freq_xfer[1].len = 2; + st->freq_xfer[1].cs_change = 1; + st->freq_xfer[2].tx_buf = &st->freq_data[2]; + st->freq_xfer[2].len = 2; + st->freq_xfer[2].cs_change = 1; + st->freq_xfer[3].tx_buf = &st->freq_data[3]; + st->freq_xfer[3].len = 2; + + spi_message_init(&st->freq_msg); + spi_message_add_tail(&st->freq_xfer[0], &st->freq_msg); + spi_message_add_tail(&st->freq_xfer[1], &st->freq_msg); + spi_message_add_tail(&st->freq_xfer[2], &st->freq_msg); + spi_message_add_tail(&st->freq_xfer[3], &st->freq_msg); + + st->phase_xfer[0].tx_buf = &st->phase_data[0]; + st->phase_xfer[0].len = 2; + st->phase_xfer[0].cs_change = 1; + st->phase_xfer[1].tx_buf = &st->phase_data[1]; + st->phase_xfer[1].len = 2; + + spi_message_init(&st->phase_msg); + spi_message_add_tail(&st->phase_xfer[0], &st->phase_msg); + spi_message_add_tail(&st->phase_xfer[1], &st->phase_msg); + + st->ctrl_src = AD9832_SLEEP | AD9832_RESET | AD9832_CLR; + st->data = cpu_to_be16((AD9832_CMD_SLEEPRESCLR << CMD_SHIFT) | + st->ctrl_src); + ret = spi_sync(st->spi, &st->msg); + if (ret) { + dev_err(&spi->dev, "device init failed\n"); + goto error_free_device; + } + + ret = ad9832_write_frequency(st, AD9832_FREQ0HM, pdata->freq0); + if (ret) + goto error_free_device; + + ret = ad9832_write_frequency(st, AD9832_FREQ1HM, pdata->freq1); + if (ret) + goto error_free_device; + + ret = ad9832_write_phase(st, AD9832_PHASE0H, pdata->phase0); + if (ret) + goto error_free_device; + + ret = ad9832_write_phase(st, AD9832_PHASE1H, pdata->phase1); + if (ret) + goto error_free_device; + + ret = ad9832_write_phase(st, AD9832_PHASE2H, pdata->phase2); + if (ret) + goto error_free_device; + + ret = ad9832_write_phase(st, AD9832_PHASE3H, pdata->phase3); + if (ret) + goto error_free_device; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_free_device; + + return 0; + +error_free_device: + iio_device_free(indio_dev); +error_disable_reg: + if (!IS_ERR(reg)) + regulator_disable(reg); +error_put_reg: + if (!IS_ERR(reg)) + regulator_put(reg); + + return ret; +} + +static int __devexit ad9832_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad9832_state *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + if (!IS_ERR(st->reg)) { + regulator_disable(st->reg); + regulator_put(st->reg); + } + iio_device_free(indio_dev); + + return 0; +} + +static const struct spi_device_id ad9832_id[] = { + {"ad9832", 0}, + {"ad9835", 0}, + {} +}; +MODULE_DEVICE_TABLE(spi, ad9832_id); + +static struct spi_driver ad9832_driver = { + .driver = { + .name = "ad9832", + .owner = THIS_MODULE, + }, + .probe = ad9832_probe, + .remove = __devexit_p(ad9832_remove), + .id_table = ad9832_id, +}; +module_spi_driver(ad9832_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD9832/AD9835 DDS"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/frequency/ad9832.h b/drivers/staging/iio/frequency/ad9832.h new file mode 100644 index 0000000..c5b701f --- /dev/null +++ b/drivers/staging/iio/frequency/ad9832.h @@ -0,0 +1,126 @@ +/* + * AD9832 SPI DDS driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ +#ifndef IIO_DDS_AD9832_H_ +#define IIO_DDS_AD9832_H_ + +/* Registers */ + +#define AD9832_FREQ0LL 0x0 +#define AD9832_FREQ0HL 0x1 +#define AD9832_FREQ0LM 0x2 +#define AD9832_FREQ0HM 0x3 +#define AD9832_FREQ1LL 0x4 +#define AD9832_FREQ1HL 0x5 +#define AD9832_FREQ1LM 0x6 +#define AD9832_FREQ1HM 0x7 +#define AD9832_PHASE0L 0x8 +#define AD9832_PHASE0H 0x9 +#define AD9832_PHASE1L 0xA +#define AD9832_PHASE1H 0xB +#define AD9832_PHASE2L 0xC +#define AD9832_PHASE2H 0xD +#define AD9832_PHASE3L 0xE +#define AD9832_PHASE3H 0xF + +#define AD9832_PHASE_SYM 0x10 +#define AD9832_FREQ_SYM 0x11 +#define AD9832_PINCTRL_EN 0x12 +#define AD9832_OUTPUT_EN 0x13 + +/* Command Control Bits */ + +#define AD9832_CMD_PHA8BITSW 0x1 +#define AD9832_CMD_PHA16BITSW 0x0 +#define AD9832_CMD_FRE8BITSW 0x3 +#define AD9832_CMD_FRE16BITSW 0x2 +#define AD9832_CMD_FPSELECT 0x6 +#define AD9832_CMD_SYNCSELSRC 0x8 +#define AD9832_CMD_SLEEPRESCLR 0xC + +#define AD9832_FREQ (1 << 11) +#define AD9832_PHASE(x) (((x) & 3) << 9) +#define AD9832_SYNC (1 << 13) +#define AD9832_SELSRC (1 << 12) +#define AD9832_SLEEP (1 << 13) +#define AD9832_RESET (1 << 12) +#define AD9832_CLR (1 << 11) +#define CMD_SHIFT 12 +#define ADD_SHIFT 8 +#define AD9832_FREQ_BITS 32 +#define AD9832_PHASE_BITS 12 +#define RES_MASK(bits) ((1 << (bits)) - 1) + +/** + * struct ad9832_state - driver instance specific data + * @spi: spi_device + * @reg: supply regulator + * @mclk: external master clock + * @ctrl_fp: cached frequency/phase control word + * @ctrl_ss: cached sync/selsrc control word + * @ctrl_src: cached sleep/reset/clr word + * @xfer: default spi transfer + * @msg: default spi message + * @freq_xfer: tuning word spi transfer + * @freq_msg: tuning word spi message + * @phase_xfer: tuning word spi transfer + * @phase_msg: tuning word spi message + * @data: spi transmit buffer + * @phase_data: tuning word spi transmit buffer + * @freq_data: tuning word spi transmit buffer + */ + +struct ad9832_state { + struct spi_device *spi; + struct regulator *reg; + unsigned long mclk; + unsigned short ctrl_fp; + unsigned short ctrl_ss; + unsigned short ctrl_src; + struct spi_transfer xfer; + struct spi_message msg; + struct spi_transfer freq_xfer[4]; + struct spi_message freq_msg; + struct spi_transfer phase_xfer[2]; + struct spi_message phase_msg; + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + union { + unsigned short freq_data[4]____cacheline_aligned; + unsigned short phase_data[2]; + unsigned short data; + }; +}; + +/* + * TODO: struct ad9832_platform_data needs to go into include/linux/iio + */ + +/** + * struct ad9832_platform_data - platform specific information + * @mclk: master clock in Hz + * @freq0: power up freq0 tuning word in Hz + * @freq1: power up freq1 tuning word in Hz + * @phase0: power up phase0 value [0..4095] correlates with 0..2PI + * @phase1: power up phase1 value [0..4095] correlates with 0..2PI + * @phase2: power up phase2 value [0..4095] correlates with 0..2PI + * @phase3: power up phase3 value [0..4095] correlates with 0..2PI + */ + +struct ad9832_platform_data { + unsigned long mclk; + unsigned long freq0; + unsigned long freq1; + unsigned short phase0; + unsigned short phase1; + unsigned short phase2; + unsigned short phase3; +}; + +#endif /* IIO_DDS_AD9832_H_ */ diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c new file mode 100644 index 0000000..b8ef8d9 --- /dev/null +++ b/drivers/staging/iio/frequency/ad9834.c @@ -0,0 +1,464 @@ +/* + * AD9833/AD9834/AD9837/AD9838 SPI DDS driver + * + * Copyright 2010-2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "dds.h" + +#include "ad9834.h" + +static unsigned int ad9834_calc_freqreg(unsigned long mclk, unsigned long fout) +{ + unsigned long long freqreg = (u64) fout * (u64) (1 << AD9834_FREQ_BITS); + do_div(freqreg, mclk); + return freqreg; +} + +static int ad9834_write_frequency(struct ad9834_state *st, + unsigned long addr, unsigned long fout) +{ + unsigned long regval; + + if (fout > (st->mclk / 2)) + return -EINVAL; + + regval = ad9834_calc_freqreg(st->mclk, fout); + + st->freq_data[0] = cpu_to_be16(addr | (regval & + RES_MASK(AD9834_FREQ_BITS / 2))); + st->freq_data[1] = cpu_to_be16(addr | ((regval >> + (AD9834_FREQ_BITS / 2)) & + RES_MASK(AD9834_FREQ_BITS / 2))); + + return spi_sync(st->spi, &st->freq_msg); +} + +static int ad9834_write_phase(struct ad9834_state *st, + unsigned long addr, unsigned long phase) +{ + if (phase > (1 << AD9834_PHASE_BITS)) + return -EINVAL; + st->data = cpu_to_be16(addr | phase); + + return spi_sync(st->spi, &st->msg); +} + +static ssize_t ad9834_write(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad9834_state *st = iio_priv(indio_dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtoul(buf, 10, &val); + if (ret) + goto error_ret; + + mutex_lock(&indio_dev->mlock); + switch ((u32) this_attr->address) { + case AD9834_REG_FREQ0: + case AD9834_REG_FREQ1: + ret = ad9834_write_frequency(st, this_attr->address, val); + break; + case AD9834_REG_PHASE0: + case AD9834_REG_PHASE1: + ret = ad9834_write_phase(st, this_attr->address, val); + break; + case AD9834_OPBITEN: + if (st->control & AD9834_MODE) { + ret = -EINVAL; /* AD9843 reserved mode */ + break; + } + + if (val) + st->control |= AD9834_OPBITEN; + else + st->control &= ~AD9834_OPBITEN; + + st->data = cpu_to_be16(AD9834_REG_CMD | st->control); + ret = spi_sync(st->spi, &st->msg); + break; + case AD9834_PIN_SW: + if (val) + st->control |= AD9834_PIN_SW; + else + st->control &= ~AD9834_PIN_SW; + st->data = cpu_to_be16(AD9834_REG_CMD | st->control); + ret = spi_sync(st->spi, &st->msg); + break; + case AD9834_FSEL: + case AD9834_PSEL: + if (val == 0) + st->control &= ~(this_attr->address | AD9834_PIN_SW); + else if (val == 1) { + st->control |= this_attr->address; + st->control &= ~AD9834_PIN_SW; + } else { + ret = -EINVAL; + break; + } + st->data = cpu_to_be16(AD9834_REG_CMD | st->control); + ret = spi_sync(st->spi, &st->msg); + break; + case AD9834_RESET: + if (val) + st->control &= ~AD9834_RESET; + else + st->control |= AD9834_RESET; + + st->data = cpu_to_be16(AD9834_REG_CMD | st->control); + ret = spi_sync(st->spi, &st->msg); + break; + default: + ret = -ENODEV; + } + mutex_unlock(&indio_dev->mlock); + +error_ret: + return ret ? ret : len; +} + +static ssize_t ad9834_store_wavetype(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad9834_state *st = iio_priv(indio_dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret = 0; + bool is_ad9833_7 = (st->devid == ID_AD9833) || (st->devid == ID_AD9837); + + mutex_lock(&indio_dev->mlock); + + switch ((u32) this_attr->address) { + case 0: + if (sysfs_streq(buf, "sine")) { + st->control &= ~AD9834_MODE; + if (is_ad9833_7) + st->control &= ~AD9834_OPBITEN; + } else if (sysfs_streq(buf, "triangle")) { + if (is_ad9833_7) { + st->control &= ~AD9834_OPBITEN; + st->control |= AD9834_MODE; + } else if (st->control & AD9834_OPBITEN) { + ret = -EINVAL; /* AD9843 reserved mode */ + } else { + st->control |= AD9834_MODE; + } + } else if (is_ad9833_7 && sysfs_streq(buf, "square")) { + st->control &= ~AD9834_MODE; + st->control |= AD9834_OPBITEN; + } else { + ret = -EINVAL; + } + + break; + case 1: + if (sysfs_streq(buf, "square") && + !(st->control & AD9834_MODE)) { + st->control &= ~AD9834_MODE; + st->control |= AD9834_OPBITEN; + } else { + ret = -EINVAL; + } + break; + default: + ret = -EINVAL; + break; + } + + if (!ret) { + st->data = cpu_to_be16(AD9834_REG_CMD | st->control); + ret = spi_sync(st->spi, &st->msg); + } + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} + +static ssize_t ad9834_show_out0_wavetype_available(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad9834_state *st = iio_priv(indio_dev); + char *str; + + if ((st->devid == ID_AD9833) || (st->devid == ID_AD9837)) + str = "sine triangle square"; + else if (st->control & AD9834_OPBITEN) + str = "sine"; + else + str = "sine triangle"; + + return sprintf(buf, "%s\n", str); +} + + +static IIO_DEVICE_ATTR(dds0_out0_wavetype_available, S_IRUGO, + ad9834_show_out0_wavetype_available, NULL, 0); + +static ssize_t ad9834_show_out1_wavetype_available(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad9834_state *st = iio_priv(indio_dev); + char *str; + + if (st->control & AD9834_MODE) + str = ""; + else + str = "square"; + + return sprintf(buf, "%s\n", str); +} + +static IIO_DEVICE_ATTR(dds0_out1_wavetype_available, S_IRUGO, + ad9834_show_out1_wavetype_available, NULL, 0); + +/** + * see dds.h for further information + */ + +static IIO_DEV_ATTR_FREQ(0, 0, S_IWUSR, NULL, ad9834_write, AD9834_REG_FREQ0); +static IIO_DEV_ATTR_FREQ(0, 1, S_IWUSR, NULL, ad9834_write, AD9834_REG_FREQ1); +static IIO_DEV_ATTR_FREQSYMBOL(0, S_IWUSR, NULL, ad9834_write, AD9834_FSEL); +static IIO_CONST_ATTR_FREQ_SCALE(0, "1"); /* 1Hz */ + +static IIO_DEV_ATTR_PHASE(0, 0, S_IWUSR, NULL, ad9834_write, AD9834_REG_PHASE0); +static IIO_DEV_ATTR_PHASE(0, 1, S_IWUSR, NULL, ad9834_write, AD9834_REG_PHASE1); +static IIO_DEV_ATTR_PHASESYMBOL(0, S_IWUSR, NULL, ad9834_write, AD9834_PSEL); +static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808"); /* 2PI/2^12 rad*/ + +static IIO_DEV_ATTR_PINCONTROL_EN(0, S_IWUSR, NULL, + ad9834_write, AD9834_PIN_SW); +static IIO_DEV_ATTR_OUT_ENABLE(0, S_IWUSR, NULL, ad9834_write, AD9834_RESET); +static IIO_DEV_ATTR_OUTY_ENABLE(0, 1, S_IWUSR, NULL, + ad9834_write, AD9834_OPBITEN); +static IIO_DEV_ATTR_OUT_WAVETYPE(0, 0, ad9834_store_wavetype, 0); +static IIO_DEV_ATTR_OUT_WAVETYPE(0, 1, ad9834_store_wavetype, 1); + +static struct attribute *ad9834_attributes[] = { + &iio_dev_attr_dds0_freq0.dev_attr.attr, + &iio_dev_attr_dds0_freq1.dev_attr.attr, + &iio_const_attr_dds0_freq_scale.dev_attr.attr, + &iio_dev_attr_dds0_phase0.dev_attr.attr, + &iio_dev_attr_dds0_phase1.dev_attr.attr, + &iio_const_attr_dds0_phase_scale.dev_attr.attr, + &iio_dev_attr_dds0_pincontrol_en.dev_attr.attr, + &iio_dev_attr_dds0_freqsymbol.dev_attr.attr, + &iio_dev_attr_dds0_phasesymbol.dev_attr.attr, + &iio_dev_attr_dds0_out_enable.dev_attr.attr, + &iio_dev_attr_dds0_out1_enable.dev_attr.attr, + &iio_dev_attr_dds0_out0_wavetype.dev_attr.attr, + &iio_dev_attr_dds0_out1_wavetype.dev_attr.attr, + &iio_dev_attr_dds0_out0_wavetype_available.dev_attr.attr, + &iio_dev_attr_dds0_out1_wavetype_available.dev_attr.attr, + NULL, +}; + +static struct attribute *ad9833_attributes[] = { + &iio_dev_attr_dds0_freq0.dev_attr.attr, + &iio_dev_attr_dds0_freq1.dev_attr.attr, + &iio_const_attr_dds0_freq_scale.dev_attr.attr, + &iio_dev_attr_dds0_phase0.dev_attr.attr, + &iio_dev_attr_dds0_phase1.dev_attr.attr, + &iio_const_attr_dds0_phase_scale.dev_attr.attr, + &iio_dev_attr_dds0_freqsymbol.dev_attr.attr, + &iio_dev_attr_dds0_phasesymbol.dev_attr.attr, + &iio_dev_attr_dds0_out_enable.dev_attr.attr, + &iio_dev_attr_dds0_out0_wavetype.dev_attr.attr, + &iio_dev_attr_dds0_out0_wavetype_available.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad9834_attribute_group = { + .attrs = ad9834_attributes, +}; + +static const struct attribute_group ad9833_attribute_group = { + .attrs = ad9833_attributes, +}; + +static const struct iio_info ad9834_info = { + .attrs = &ad9834_attribute_group, + .driver_module = THIS_MODULE, +}; + +static const struct iio_info ad9833_info = { + .attrs = &ad9833_attribute_group, + .driver_module = THIS_MODULE, +}; + +static int __devinit ad9834_probe(struct spi_device *spi) +{ + struct ad9834_platform_data *pdata = spi->dev.platform_data; + struct ad9834_state *st; + struct iio_dev *indio_dev; + struct regulator *reg; + int ret; + + if (!pdata) { + dev_dbg(&spi->dev, "no platform data?\n"); + return -ENODEV; + } + + reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(reg)) { + ret = regulator_enable(reg); + if (ret) + goto error_put_reg; + } + + indio_dev = iio_device_alloc(sizeof(*st)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_disable_reg; + } + spi_set_drvdata(spi, indio_dev); + st = iio_priv(indio_dev); + st->mclk = pdata->mclk; + st->spi = spi; + st->devid = spi_get_device_id(spi)->driver_data; + st->reg = reg; + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + switch (st->devid) { + case ID_AD9833: + case ID_AD9837: + indio_dev->info = &ad9833_info; + break; + default: + indio_dev->info = &ad9834_info; + break; + } + indio_dev->modes = INDIO_DIRECT_MODE; + + /* Setup default messages */ + + st->xfer.tx_buf = &st->data; + st->xfer.len = 2; + + spi_message_init(&st->msg); + spi_message_add_tail(&st->xfer, &st->msg); + + st->freq_xfer[0].tx_buf = &st->freq_data[0]; + st->freq_xfer[0].len = 2; + st->freq_xfer[0].cs_change = 1; + st->freq_xfer[1].tx_buf = &st->freq_data[1]; + st->freq_xfer[1].len = 2; + + spi_message_init(&st->freq_msg); + spi_message_add_tail(&st->freq_xfer[0], &st->freq_msg); + spi_message_add_tail(&st->freq_xfer[1], &st->freq_msg); + + st->control = AD9834_B28 | AD9834_RESET; + + if (!pdata->en_div2) + st->control |= AD9834_DIV2; + + if (!pdata->en_signbit_msb_out && (st->devid == ID_AD9834)) + st->control |= AD9834_SIGN_PIB; + + st->data = cpu_to_be16(AD9834_REG_CMD | st->control); + ret = spi_sync(st->spi, &st->msg); + if (ret) { + dev_err(&spi->dev, "device init failed\n"); + goto error_free_device; + } + + ret = ad9834_write_frequency(st, AD9834_REG_FREQ0, pdata->freq0); + if (ret) + goto error_free_device; + + ret = ad9834_write_frequency(st, AD9834_REG_FREQ1, pdata->freq1); + if (ret) + goto error_free_device; + + ret = ad9834_write_phase(st, AD9834_REG_PHASE0, pdata->phase0); + if (ret) + goto error_free_device; + + ret = ad9834_write_phase(st, AD9834_REG_PHASE1, pdata->phase1); + if (ret) + goto error_free_device; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_free_device; + + return 0; + +error_free_device: + iio_device_free(indio_dev); +error_disable_reg: + if (!IS_ERR(reg)) + regulator_disable(reg); +error_put_reg: + if (!IS_ERR(reg)) + regulator_put(reg); + return ret; +} + +static int __devexit ad9834_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad9834_state *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + if (!IS_ERR(st->reg)) { + regulator_disable(st->reg); + regulator_put(st->reg); + } + iio_device_free(indio_dev); + + return 0; +} + +static const struct spi_device_id ad9834_id[] = { + {"ad9833", ID_AD9833}, + {"ad9834", ID_AD9834}, + {"ad9837", ID_AD9837}, + {"ad9838", ID_AD9838}, + {} +}; +MODULE_DEVICE_TABLE(spi, ad9834_id); + +static struct spi_driver ad9834_driver = { + .driver = { + .name = "ad9834", + .owner = THIS_MODULE, + }, + .probe = ad9834_probe, + .remove = __devexit_p(ad9834_remove), + .id_table = ad9834_id, +}; +module_spi_driver(ad9834_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD9833/AD9834/AD9837/AD9838 DDS"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/frequency/ad9834.h b/drivers/staging/iio/frequency/ad9834.h new file mode 100644 index 0000000..ed5ed8d --- /dev/null +++ b/drivers/staging/iio/frequency/ad9834.h @@ -0,0 +1,112 @@ +/* + * AD9833/AD9834/AD9837/AD9838 SPI DDS driver + * + * Copyright 2010-2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ +#ifndef IIO_DDS_AD9834_H_ +#define IIO_DDS_AD9834_H_ + +/* Registers */ + +#define AD9834_REG_CMD (0 << 14) +#define AD9834_REG_FREQ0 (1 << 14) +#define AD9834_REG_FREQ1 (2 << 14) +#define AD9834_REG_PHASE0 (6 << 13) +#define AD9834_REG_PHASE1 (7 << 13) + +/* Command Control Bits */ + +#define AD9834_B28 (1 << 13) +#define AD9834_HLB (1 << 12) +#define AD9834_FSEL (1 << 11) +#define AD9834_PSEL (1 << 10) +#define AD9834_PIN_SW (1 << 9) +#define AD9834_RESET (1 << 8) +#define AD9834_SLEEP1 (1 << 7) +#define AD9834_SLEEP12 (1 << 6) +#define AD9834_OPBITEN (1 << 5) +#define AD9834_SIGN_PIB (1 << 4) +#define AD9834_DIV2 (1 << 3) +#define AD9834_MODE (1 << 1) + +#define AD9834_FREQ_BITS 28 +#define AD9834_PHASE_BITS 12 + +#define RES_MASK(bits) ((1 << (bits)) - 1) + +/** + * struct ad9834_state - driver instance specific data + * @spi: spi_device + * @reg: supply regulator + * @mclk: external master clock + * @control: cached control word + * @xfer: default spi transfer + * @msg: default spi message + * @freq_xfer: tuning word spi transfer + * @freq_msg: tuning word spi message + * @data: spi transmit buffer + * @freq_data: tuning word spi transmit buffer + */ + +struct ad9834_state { + struct spi_device *spi; + struct regulator *reg; + unsigned int mclk; + unsigned short control; + unsigned short devid; + struct spi_transfer xfer; + struct spi_message msg; + struct spi_transfer freq_xfer[2]; + struct spi_message freq_msg; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + unsigned short data ____cacheline_aligned; + unsigned short freq_data[2] ; +}; + + +/* + * TODO: struct ad7887_platform_data needs to go into include/linux/iio + */ + +/** + * struct ad9834_platform_data - platform specific information + * @mclk: master clock in Hz + * @freq0: power up freq0 tuning word in Hz + * @freq1: power up freq1 tuning word in Hz + * @phase0: power up phase0 value [0..4095] correlates with 0..2PI + * @phase1: power up phase1 value [0..4095] correlates with 0..2PI + * @en_div2: digital output/2 is passed to the SIGN BIT OUT pin + * @en_signbit_msb_out: the MSB (or MSB/2) of the DAC data is connected to the + * SIGN BIT OUT pin. en_div2 controls whether it is the MSB + * or MSB/2 that is output. if en_signbit_msb_out=false, + * the on-board comparator is connected to SIGN BIT OUT + */ + +struct ad9834_platform_data { + unsigned int mclk; + unsigned int freq0; + unsigned int freq1; + unsigned short phase0; + unsigned short phase1; + bool en_div2; + bool en_signbit_msb_out; +}; + +/** + * ad9834_supported_device_ids: + */ + +enum ad9834_supported_device_ids { + ID_AD9833, + ID_AD9834, + ID_AD9837, + ID_AD9838, +}; + +#endif /* IIO_DDS_AD9834_H_ */ diff --git a/drivers/staging/iio/frequency/ad9850.c b/drivers/staging/iio/frequency/ad9850.c new file mode 100644 index 0000000..39f12a6 --- /dev/null +++ b/drivers/staging/iio/frequency/ad9850.c @@ -0,0 +1,137 @@ +/* + * Driver for ADI Direct Digital Synthesis ad9850 + * + * Copyright (c) 2010-2010 Analog Devices Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DRV_NAME "ad9850" + +#define value_mask (u16)0xf000 +#define addr_shift 12 + +/* Register format: 4 bits addr + 12 bits value */ +struct ad9850_config { + u8 control[5]; +}; + +struct ad9850_state { + struct mutex lock; + struct spi_device *sdev; +}; + +static ssize_t ad9850_set_parameter(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret; + struct ad9850_config *config = (struct ad9850_config *)buf; + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad9850_state *st = iio_priv(idev); + + xfer.len = len; + xfer.tx_buf = config; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; +error_ret: + mutex_unlock(&st->lock); + + return ret ? ret : len; +} + +static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9850_set_parameter, 0); + +static struct attribute *ad9850_attributes[] = { + &iio_dev_attr_dds.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad9850_attribute_group = { + .attrs = ad9850_attributes, +}; + +static const struct iio_info ad9850_info = { + .attrs = &ad9850_attribute_group, + .driver_module = THIS_MODULE, +}; + +static int __devinit ad9850_probe(struct spi_device *spi) +{ + struct ad9850_state *st; + struct iio_dev *idev; + int ret = 0; + + idev = iio_device_alloc(sizeof(*st)); + if (idev == NULL) { + ret = -ENOMEM; + goto error_ret; + } + spi_set_drvdata(spi, idev); + st = iio_priv(idev); + mutex_init(&st->lock); + st->sdev = spi; + + idev->dev.parent = &spi->dev; + idev->info = &ad9850_info; + idev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(idev); + if (ret) + goto error_free_dev; + spi->max_speed_hz = 2000000; + spi->mode = SPI_MODE_3; + spi->bits_per_word = 16; + spi_setup(spi); + + return 0; + +error_free_dev: + iio_device_free(idev); +error_ret: + return ret; +} + +static int __devexit ad9850_remove(struct spi_device *spi) +{ + iio_device_unregister(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); + + return 0; +} + +static struct spi_driver ad9850_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = ad9850_probe, + .remove = __devexit_p(ad9850_remove), +}; +module_spi_driver(ad9850_driver); + +MODULE_AUTHOR("Cliff Cai"); +MODULE_DESCRIPTION("Analog Devices ad9850 driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("spi:" DRV_NAME); diff --git a/drivers/staging/iio/frequency/ad9852.c b/drivers/staging/iio/frequency/ad9852.c new file mode 100644 index 0000000..58d4bf8 --- /dev/null +++ b/drivers/staging/iio/frequency/ad9852.c @@ -0,0 +1,288 @@ +/* + * Driver for ADI Direct Digital Synthesis ad9852 + * + * Copyright (c) 2010 Analog Devices Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DRV_NAME "ad9852" + +#define addr_phaad1 0x0 +#define addr_phaad2 0x1 +#define addr_fretu1 0x2 +#define addr_fretu2 0x3 +#define addr_delfre 0x4 +#define addr_updclk 0x5 +#define addr_ramclk 0x6 +#define addr_contrl 0x7 +#define addr_optskm 0x8 +#define addr_optskr 0xa +#define addr_dacctl 0xb + +#define COMPPD (1 << 4) +#define REFMULT2 (1 << 2) +#define BYPPLL (1 << 5) +#define PLLRANG (1 << 6) +#define IEUPCLK (1) +#define OSKEN (1 << 5) + +#define read_bit (1 << 7) + +/* Register format: 1 byte addr + value */ +struct ad9852_config { + u8 phajst0[3]; + u8 phajst1[3]; + u8 fretun1[6]; + u8 fretun2[6]; + u8 dltafre[6]; + u8 updtclk[5]; + u8 ramprat[4]; + u8 control[5]; + u8 outpskm[3]; + u8 outpskr[2]; + u8 daccntl[3]; +}; + +struct ad9852_state { + struct mutex lock; + struct spi_device *sdev; +}; + +static ssize_t ad9852_set_parameter(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret; + struct ad9852_config *config = (struct ad9852_config *)buf; + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad9852_state *st = iio_priv(idev); + + xfer.len = 3; + xfer.tx_buf = &config->phajst0[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 3; + xfer.tx_buf = &config->phajst1[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 6; + xfer.tx_buf = &config->fretun1[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 6; + xfer.tx_buf = &config->fretun2[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 6; + xfer.tx_buf = &config->dltafre[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 5; + xfer.tx_buf = &config->updtclk[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 4; + xfer.tx_buf = &config->ramprat[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 5; + xfer.tx_buf = &config->control[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 3; + xfer.tx_buf = &config->outpskm[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 2; + xfer.tx_buf = &config->outpskr[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 3; + xfer.tx_buf = &config->daccntl[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; +error_ret: + mutex_unlock(&st->lock); + + return ret ? ret : len; +} + +static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9852_set_parameter, 0); + +static void ad9852_init(struct ad9852_state *st) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret; + u8 config[5]; + + config[0] = addr_contrl; + config[1] = COMPPD; + config[2] = REFMULT2 | BYPPLL | PLLRANG; + config[3] = IEUPCLK; + config[4] = OSKEN; + + mutex_lock(&st->lock); + + xfer.len = 5; + xfer.tx_buf = &config; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + +error_ret: + mutex_unlock(&st->lock); + + + +} + +static struct attribute *ad9852_attributes[] = { + &iio_dev_attr_dds.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad9852_attribute_group = { + .attrs = ad9852_attributes, +}; + +static const struct iio_info ad9852_info = { + .attrs = &ad9852_attribute_group, + .driver_module = THIS_MODULE, +}; + +static int __devinit ad9852_probe(struct spi_device *spi) +{ + struct ad9852_state *st; + struct iio_dev *idev; + int ret = 0; + + idev = iio_device_alloc(sizeof(*st)); + if (idev == NULL) { + ret = -ENOMEM; + goto error_ret; + } + st = iio_priv(idev); + spi_set_drvdata(spi, idev); + mutex_init(&st->lock); + st->sdev = spi; + + idev->dev.parent = &spi->dev; + idev->info = &ad9852_info; + idev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(idev); + if (ret) + goto error_free_dev; + spi->max_speed_hz = 2000000; + spi->mode = SPI_MODE_3; + spi->bits_per_word = 8; + spi_setup(spi); + ad9852_init(st); + + return 0; + +error_free_dev: + iio_device_free(idev); + +error_ret: + return ret; +} + +static int __devexit ad9852_remove(struct spi_device *spi) +{ + iio_device_unregister(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); + + return 0; +} + +static struct spi_driver ad9852_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = ad9852_probe, + .remove = __devexit_p(ad9852_remove), +}; +module_spi_driver(ad9852_driver); + +MODULE_AUTHOR("Cliff Cai"); +MODULE_DESCRIPTION("Analog Devices ad9852 driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("spi:" DRV_NAME); diff --git a/drivers/staging/iio/frequency/ad9910.c b/drivers/staging/iio/frequency/ad9910.c new file mode 100644 index 0000000..6e7a97e --- /dev/null +++ b/drivers/staging/iio/frequency/ad9910.c @@ -0,0 +1,421 @@ +/* + * Driver for ADI Direct Digital Synthesis ad9910 + * + * Copyright (c) 2010 Analog Devices Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DRV_NAME "ad9910" + +#define CFR1 0x0 +#define CFR2 0x1 +#define CFR3 0x2 + +#define AUXDAC 0x3 +#define IOUPD 0x4 +#define FTW 0x7 +#define POW 0x8 +#define ASF 0x9 +#define MULTC 0x0A +#define DIG_RAMPL 0x0B +#define DIG_RAMPS 0x0C +#define DIG_RAMPR 0x0D +#define SIN_TONEP0 0x0E +#define SIN_TONEP1 0x0F +#define SIN_TONEP2 0x10 +#define SIN_TONEP3 0x11 +#define SIN_TONEP4 0x12 +#define SIN_TONEP5 0x13 +#define SIN_TONEP6 0x14 +#define SIN_TONEP7 0x15 + +#define RAM_ENABLE (1 << 7) + +#define MANUAL_OSK (1 << 7) +#define INVSIC (1 << 6) +#define DDS_SINEOP (1) + +#define AUTO_OSK (1) +#define OSKEN (1 << 1) +#define LOAD_ARR (1 << 2) +#define CLR_PHA (1 << 3) +#define CLR_DIG (1 << 4) +#define ACLR_PHA (1 << 5) +#define ACLR_DIG (1 << 6) +#define LOAD_LRR (1 << 7) + +#define LSB_FST (1) +#define SDIO_IPT (1 << 1) +#define EXT_PWD (1 << 3) +#define ADAC_PWD (1 << 4) +#define REFCLK_PWD (1 << 5) +#define DAC_PWD (1 << 6) +#define DIG_PWD (1 << 7) + +#define ENA_AMP (1) +#define READ_FTW (1) +#define DIGR_LOW (1 << 1) +#define DIGR_HIGH (1 << 2) +#define DIGR_ENA (1 << 3) +#define SYNCCLK_ENA (1 << 6) +#define ITER_IOUPD (1 << 7) + +#define TX_ENA (1 << 1) +#define PDCLK_INV (1 << 2) +#define PDCLK_ENB (1 << 3) + +#define PARA_ENA (1 << 4) +#define SYNC_DIS (1 << 5) +#define DATA_ASS (1 << 6) +#define MATCH_ENA (1 << 7) + +#define PLL_ENA (1) +#define PFD_RST (1 << 2) +#define REFCLK_RST (1 << 6) +#define REFCLK_BYP (1 << 7) + +/* Register format: 1 byte addr + value */ +struct ad9910_config { + u8 auxdac[5]; + u8 ioupd[5]; + u8 ftw[5]; + u8 pow[3]; + u8 asf[5]; + u8 multc[5]; + u8 dig_rampl[9]; + u8 dig_ramps[9]; + u8 dig_rampr[5]; + u8 sin_tonep0[9]; + u8 sin_tonep1[9]; + u8 sin_tonep2[9]; + u8 sin_tonep3[9]; + u8 sin_tonep4[9]; + u8 sin_tonep5[9]; + u8 sin_tonep6[9]; + u8 sin_tonep7[9]; +}; + +struct ad9910_state { + struct mutex lock; + struct spi_device *sdev; +}; + +static ssize_t ad9910_set_parameter(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret; + struct ad9910_config *config = (struct ad9910_config *)buf; + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad9910_state *st = iio_priv(idev); + + xfer.len = 5; + xfer.tx_buf = &config->auxdac[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 5; + xfer.tx_buf = &config->ioupd[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 5; + xfer.tx_buf = &config->ftw[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 3; + xfer.tx_buf = &config->pow[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 5; + xfer.tx_buf = &config->asf[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 5; + xfer.tx_buf = &config->multc[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 9; + xfer.tx_buf = &config->dig_rampl[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 9; + xfer.tx_buf = &config->dig_ramps[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 5; + xfer.tx_buf = &config->dig_rampr[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 9; + xfer.tx_buf = &config->sin_tonep0[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 9; + xfer.tx_buf = &config->sin_tonep1[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 9; + xfer.tx_buf = &config->sin_tonep2[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + xfer.len = 9; + xfer.tx_buf = &config->sin_tonep3[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 9; + xfer.tx_buf = &config->sin_tonep4[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 9; + xfer.tx_buf = &config->sin_tonep5[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 9; + xfer.tx_buf = &config->sin_tonep6[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 9; + xfer.tx_buf = &config->sin_tonep7[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; +error_ret: + mutex_unlock(&st->lock); + + return ret ? ret : len; +} + +static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9910_set_parameter, 0); + +static void ad9910_init(struct ad9910_state *st) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret; + u8 cfr[5]; + + cfr[0] = CFR1; + cfr[1] = 0; + cfr[2] = MANUAL_OSK | INVSIC | DDS_SINEOP; + cfr[3] = AUTO_OSK | OSKEN | ACLR_PHA | ACLR_DIG | LOAD_LRR; + cfr[4] = 0; + + mutex_lock(&st->lock); + + xfer.len = 5; + xfer.tx_buf = 𝔠 + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + cfr[0] = CFR2; + cfr[1] = ENA_AMP; + cfr[2] = READ_FTW | DIGR_ENA | ITER_IOUPD; + cfr[3] = TX_ENA | PDCLK_INV | PDCLK_ENB; + cfr[4] = PARA_ENA; + + xfer.len = 5; + xfer.tx_buf = 𝔠 + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + cfr[0] = CFR3; + cfr[1] = PLL_ENA; + cfr[2] = 0; + cfr[3] = REFCLK_RST | REFCLK_BYP; + cfr[4] = 0; + + xfer.len = 5; + xfer.tx_buf = 𝔠 + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + +error_ret: + mutex_unlock(&st->lock); + + + +} + +static struct attribute *ad9910_attributes[] = { + &iio_dev_attr_dds.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad9910_attribute_group = { + .attrs = ad9910_attributes, +}; + +static const struct iio_info ad9910_info = { + .attrs = &ad9910_attribute_group, + .driver_module = THIS_MODULE, +}; + +static int __devinit ad9910_probe(struct spi_device *spi) +{ + struct ad9910_state *st; + struct iio_dev *idev; + int ret = 0; + + idev = iio_device_alloc(sizeof(*st)); + if (idev == NULL) { + ret = -ENOMEM; + goto error_ret; + } + spi_set_drvdata(spi, idev); + st = iio_priv(idev); + mutex_init(&st->lock); + st->sdev = spi; + + idev->dev.parent = &spi->dev; + idev->info = &ad9910_info; + idev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(idev); + if (ret) + goto error_free_dev; + spi->max_speed_hz = 2000000; + spi->mode = SPI_MODE_3; + spi->bits_per_word = 8; + spi_setup(spi); + ad9910_init(st); + return 0; + +error_free_dev: + iio_device_free(idev); +error_ret: + return ret; +} + +static int __devexit ad9910_remove(struct spi_device *spi) +{ + iio_device_unregister(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); + + return 0; +} + +static struct spi_driver ad9910_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = ad9910_probe, + .remove = __devexit_p(ad9910_remove), +}; +module_spi_driver(ad9910_driver); + +MODULE_AUTHOR("Cliff Cai"); +MODULE_DESCRIPTION("Analog Devices ad9910 driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("spi:" DRV_NAME); diff --git a/drivers/staging/iio/frequency/ad9951.c b/drivers/staging/iio/frequency/ad9951.c new file mode 100644 index 0000000..19ba721 --- /dev/null +++ b/drivers/staging/iio/frequency/ad9951.c @@ -0,0 +1,232 @@ +/* + * Driver for ADI Direct Digital Synthesis ad9951 + * + * Copyright (c) 2010 Analog Devices Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DRV_NAME "ad9951" + +#define CFR1 0x0 +#define CFR2 0x1 + +#define AUTO_OSK (1) +#define OSKEN (1 << 1) +#define LOAD_ARR (1 << 2) + +#define AUTO_SYNC (1 << 7) + +#define LSB_FST (1) +#define SDIO_IPT (1 << 1) +#define CLR_PHA (1 << 2) +#define SINE_OPT (1 << 4) +#define ACLR_PHA (1 << 5) + +#define VCO_RANGE (1 << 2) + +#define CRS_OPT (1 << 1) +#define HMANU_SYNC (1 << 2) +#define HSPD_SYNC (1 << 3) + +/* Register format: 1 byte addr + value */ +struct ad9951_config { + u8 asf[3]; + u8 arr[2]; + u8 ftw0[5]; + u8 ftw1[3]; +}; + +struct ad9951_state { + struct mutex lock; + struct spi_device *sdev; +}; + +static ssize_t ad9951_set_parameter(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret; + struct ad9951_config *config = (struct ad9951_config *)buf; + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad9951_state *st = iio_priv(idev); + + xfer.len = 3; + xfer.tx_buf = &config->asf[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 2; + xfer.tx_buf = &config->arr[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 5; + xfer.tx_buf = &config->ftw0[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 3; + xfer.tx_buf = &config->ftw1[0]; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; +error_ret: + mutex_unlock(&st->lock); + + return ret ? ret : len; +} + +static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9951_set_parameter, 0); + +static void ad9951_init(struct ad9951_state *st) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret; + u8 cfr[5]; + + cfr[0] = CFR1; + cfr[1] = 0; + cfr[2] = LSB_FST | CLR_PHA | SINE_OPT | ACLR_PHA; + cfr[3] = AUTO_OSK | OSKEN | LOAD_ARR; + cfr[4] = 0; + + mutex_lock(&st->lock); + + xfer.len = 5; + xfer.tx_buf = 𝔠 + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + cfr[0] = CFR2; + cfr[1] = VCO_RANGE; + cfr[2] = HSPD_SYNC; + cfr[3] = 0; + + xfer.len = 4; + xfer.tx_buf = 𝔠 + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + +error_ret: + mutex_unlock(&st->lock); + + + +} + +static struct attribute *ad9951_attributes[] = { + &iio_dev_attr_dds.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad9951_attribute_group = { + .attrs = ad9951_attributes, +}; + +static const struct iio_info ad9951_info = { + .attrs = &ad9951_attribute_group, + .driver_module = THIS_MODULE, +}; + +static int __devinit ad9951_probe(struct spi_device *spi) +{ + struct ad9951_state *st; + struct iio_dev *idev; + int ret = 0; + + idev = iio_device_alloc(sizeof(*st)); + if (idev == NULL) { + ret = -ENOMEM; + goto error_ret; + } + spi_set_drvdata(spi, idev); + st = iio_priv(idev); + mutex_init(&st->lock); + st->sdev = spi; + + idev->dev.parent = &spi->dev; + + idev->info = &ad9951_info; + idev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(idev); + if (ret) + goto error_free_dev; + spi->max_speed_hz = 2000000; + spi->mode = SPI_MODE_3; + spi->bits_per_word = 8; + spi_setup(spi); + ad9951_init(st); + return 0; + +error_free_dev: + iio_device_free(idev); + +error_ret: + return ret; +} + +static int __devexit ad9951_remove(struct spi_device *spi) +{ + iio_device_unregister(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); + + return 0; +} + +static struct spi_driver ad9951_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = ad9951_probe, + .remove = __devexit_p(ad9951_remove), +}; +module_spi_driver(ad9951_driver); + +MODULE_AUTHOR("Cliff Cai"); +MODULE_DESCRIPTION("Analog Devices ad9951 driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("spi:" DRV_NAME); diff --git a/drivers/staging/iio/frequency/dds.h b/drivers/staging/iio/frequency/dds.h new file mode 100644 index 0000000..d8ac3a9 --- /dev/null +++ b/drivers/staging/iio/frequency/dds.h @@ -0,0 +1,110 @@ +/* + * dds.h - sysfs attributes associated with DDS devices + * + * Copyright (c) 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +/** + * /sys/bus/iio/devices/.../ddsX_freqY + */ + +#define IIO_DEV_ATTR_FREQ(_channel, _num, _mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(dds##_channel##_freq##_num, \ + _mode, _show, _store, _addr) + +/** + * /sys/bus/iio/devices/.../ddsX_freqY_scale + */ + +#define IIO_CONST_ATTR_FREQ_SCALE(_channel, _string) \ + IIO_CONST_ATTR(dds##_channel##_freq_scale, _string) + +/** + * /sys/bus/iio/devices/.../ddsX_freqsymbol + */ + +#define IIO_DEV_ATTR_FREQSYMBOL(_channel, _mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(dds##_channel##_freqsymbol, \ + _mode, _show, _store, _addr); + +/** + * /sys/bus/iio/devices/.../ddsX_phaseY + */ + +#define IIO_DEV_ATTR_PHASE(_channel, _num, _mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(dds##_channel##_phase##_num, \ + _mode, _show, _store, _addr) + +/** + * /sys/bus/iio/devices/.../ddsX_phaseY_scale + */ + +#define IIO_CONST_ATTR_PHASE_SCALE(_channel, _string) \ + IIO_CONST_ATTR(dds##_channel##_phase_scale, _string) + +/** + * /sys/bus/iio/devices/.../ddsX_phasesymbol + */ + +#define IIO_DEV_ATTR_PHASESYMBOL(_channel, _mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(dds##_channel##_phasesymbol, \ + _mode, _show, _store, _addr); + +/** + * /sys/bus/iio/devices/.../ddsX_pincontrol_en + */ + +#define IIO_DEV_ATTR_PINCONTROL_EN(_channel, _mode, _show, _store, _addr)\ + IIO_DEVICE_ATTR(dds##_channel##_pincontrol_en, \ + _mode, _show, _store, _addr); + +/** + * /sys/bus/iio/devices/.../ddsX_pincontrol_freq_en + */ + +#define IIO_DEV_ATTR_PINCONTROL_FREQ_EN(_channel, _mode, _show, _store, _addr)\ + IIO_DEVICE_ATTR(dds##_channel##_pincontrol_freq_en, \ + _mode, _show, _store, _addr); + +/** + * /sys/bus/iio/devices/.../ddsX_pincontrol_phase_en + */ + +#define IIO_DEV_ATTR_PINCONTROL_PHASE_EN(_channel, _mode, _show, _store, _addr)\ + IIO_DEVICE_ATTR(dds##_channel##_pincontrol_phase_en, \ + _mode, _show, _store, _addr); + +/** + * /sys/bus/iio/devices/.../ddsX_out_enable + */ + +#define IIO_DEV_ATTR_OUT_ENABLE(_channel, _mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(dds##_channel##_out_enable, \ + _mode, _show, _store, _addr); + +/** + * /sys/bus/iio/devices/.../ddsX_outY_enable + */ + +#define IIO_DEV_ATTR_OUTY_ENABLE(_channel, _output, \ + _mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(dds##_channel##_out##_output##_enable, \ + _mode, _show, _store, _addr); + +/** + * /sys/bus/iio/devices/.../ddsX_outY_wavetype + */ + +#define IIO_DEV_ATTR_OUT_WAVETYPE(_channel, _output, _store, _addr) \ + IIO_DEVICE_ATTR(dds##_channel##_out##_output##_wavetype, \ + S_IWUSR, NULL, _store, _addr); + +/** + * /sys/bus/iio/devices/.../ddsX_outY_wavetype_available + */ + +#define IIO_CONST_ATTR_OUT_WAVETYPES_AVAILABLE(_channel, _output, _modes)\ + IIO_CONST_ATTR(dds##_channel##_out##_output##_wavetype_available,\ + _modes); -- cgit v0.10.2 From a6b12855b58bff429f3961e2577b8bbbb48fe470 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 27 Apr 2012 10:58:34 +0200 Subject: iio: core: Introduce IIO_ALTVOLTAGE and appropriate channel info elements Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index e8e280d..47a7247 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -63,6 +63,7 @@ static const char * const iio_chan_type_name_spec[] = { [IIO_ANGL] = "angl", [IIO_TIMESTAMP] = "timestamp", [IIO_CAPACITANCE] = "capacitance", + [IIO_ALTVOLTAGE] = "altvoltage", }; static const char * const iio_modifier_names[] = { @@ -88,6 +89,8 @@ static const char * const iio_chan_info_postfix[] = { [IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY] = "filter_low_pass_3db_frequency", [IIO_CHAN_INFO_SAMP_FREQ] = "sampling_frequency", + [IIO_CHAN_INFO_FREQUENCY] = "frequency", + [IIO_CHAN_INFO_PHASE] = "phase", }; const struct iio_chan_spec diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index d218339..43002b2 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -32,6 +32,8 @@ enum iio_chan_info_enum { IIO_CHAN_INFO_AVERAGE_RAW, IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY, IIO_CHAN_INFO_SAMP_FREQ, + IIO_CHAN_INFO_FREQUENCY, + IIO_CHAN_INFO_PHASE, }; #define IIO_CHAN_INFO_SHARED_BIT(type) BIT(type*2) @@ -85,6 +87,14 @@ enum iio_chan_info_enum { IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_SAMP_FREQ) #define IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT \ IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_SAMP_FREQ) +#define IIO_CHAN_INFO_FREQUENCY_SEPARATE_BIT \ + IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_FREQUENCY) +#define IIO_CHAN_INFO_FREQUENCY_SHARED_BIT \ + IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_FREQUENCY) +#define IIO_CHAN_INFO_PHASE_SEPARATE_BIT \ + IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_PHASE) +#define IIO_CHAN_INFO_PHASE_SHARED_BIT \ + IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_PHASE) enum iio_endian { IIO_CPU, diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h index 0c32136..a471fd5 100644 --- a/include/linux/iio/types.h +++ b/include/linux/iio/types.h @@ -27,6 +27,7 @@ enum iio_chan_type { IIO_ANGL, IIO_TIMESTAMP, IIO_CAPACITANCE, + IIO_ALTVOLTAGE, }; enum iio_modifier { -- cgit v0.10.2 From 73e016ef94d801bd0278959606d2f72f07a2abab Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 27 Apr 2012 10:58:35 +0200 Subject: iio: frequency: Update DDS drivers to use new channel naming convention Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-dds b/drivers/staging/iio/Documentation/sysfs-bus-iio-dds index ffdd547..ee8c509 100644 --- a/drivers/staging/iio/Documentation/sysfs-bus-iio-dds +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio-dds @@ -1,83 +1,86 @@ -What: /sys/bus/iio/devices/.../ddsX_freqY +What: /sys/bus/iio/devices/.../out_altvoltageX_frequencyY KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: Stores frequency into tuning word Y. - There will be more than one ddsX_freqY file, which allows for - pin controlled FSK Frequency Shift Keying - (ddsX_pincontrol_freq_en is active) or the user can control - the desired active tuning word by writing Y to the - ddsX_freqsymbol file. + There will be more than one out_altvoltageX_frequencyY file, + which allows for pin controlled FSK Frequency Shift Keying + (out_altvoltageX_pincontrol_frequency_en is active) or the user + can control the desired active tuning word by writing Y to the + out_altvoltageX_frequencysymbol file. -What: /sys/bus/iio/devices/.../ddsX_freqY_scale +What: /sys/bus/iio/devices/.../out_altvoltageX_frequencyY_scale KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: - Scale to be applied to ddsX_freqY in order to obtain the - desired value in Hz. If shared across all frequency registers - Y is not present. It is also possible X is not present if - shared across all channels. + Scale to be applied to out_altvoltageX_frequencyY in order to + obtain the desired value in Hz. If shared across all frequency + registers Y is not present. It is also possible X is not present + if shared across all channels. -What: /sys/bus/iio/devices/.../ddsX_freqsymbol +What: /sys/bus/iio/devices/.../out_altvoltageX_frequencysymbol KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: Specifies the active output frequency tuning word. The value - corresponds to the Y in ddsX_freqY. To exit this mode the user - can write ddsX_pincontrol_freq_en or ddsX_out_enable file. + corresponds to the Y in out_altvoltageX_frequencyY. + To exit this mode the user can write + out_altvoltageX_pincontrol_frequency_en or + out_altvoltageX_out_enable file. -What: /sys/bus/iio/devices/.../ddsX_phaseY +What: /sys/bus/iio/devices/.../out_altvoltageX_phaseY KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: Stores phase into Y. - There will be more than one ddsX_phaseY file, which allows for - pin controlled PSK Phase Shift Keying - (ddsX_pincontrol_phase_en is active) or the user can + There will be more than one out_altvoltageX_phaseY file, which + allows for pin controlled PSK Phase Shift Keying + (out_altvoltageX_pincontrol_phase_en is active) or the user can control the desired phase Y which is added to the phase - accumulator output by writing Y to the en_phase file. + accumulator output by writing Y to the phase_en file. -What: /sys/bus/iio/devices/.../ddsX_phaseY_scale +What: /sys/bus/iio/devices/.../out_altvoltageX_phaseY_scale KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: - Scale to be applied to ddsX_phaseY in order to obtain the - desired value in rad. If shared across all phase registers + Scale to be applied to out_altvoltageX_phaseY in order to obtain + the desired value in rad. If shared across all phase registers Y is not present. It is also possible X is not present if shared across all channels. -What: /sys/bus/iio/devices/.../ddsX_phasesymbol +What: /sys/bus/iio/devices/.../out_altvoltageX_phasesymbol KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: Specifies the active phase Y which is added to the phase accumulator output. The value corresponds to the Y in - ddsX_phaseY. To exit this mode the user can write - ddsX_pincontrol_phase_en or disable file. + out_altvoltageX_phaseY. To exit this mode the user can write + out_altvoltageX_pincontrol_phase_en or disable file. -What: /sys/bus/iio/devices/.../ddsX_pincontrol_en -What: /sys/bus/iio/devices/.../ddsX_pincontrol_freq_en -What: /sys/bus/iio/devices/.../ddsX_pincontrol_phase_en +What: /sys/bus/iio/devices/.../out_altvoltageX_pincontrol_en +What: /sys/bus/iio/devices/.../out_altvoltageX_pincontrol_frequency_en +What: /sys/bus/iio/devices/.../out_altvoltageX_pincontrol_phase_en KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: - ddsX_pincontrol_en: Both, the active frequency and phase is - controlled by the respective phase and frequency control inputs. - In case the device in question allows to independent controls, - then there are dedicated files (ddsX_pincontrol_freq_en, - ddsX_pincontrol_phase_en). + out_altvoltageX_pincontrol_en: Both, the active frequency and + phase is controlled by the respective phase and frequency + control inputs. In case the device in features independent + controls, then there are dedicated files + (out_altvoltageX_pincontrol_frequency_en, + out_altvoltageX_pincontrol_phase_en). -What: /sys/bus/iio/devices/.../ddsX_out_enable -What: /sys/bus/iio/devices/.../ddsX_outY_enable +What: /sys/bus/iio/devices/.../out_altvoltageX_out_enable +What: /sys/bus/iio/devices/.../out_altvoltageX_outY_enable KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: - ddsX_outY_enable controls signal generation on output Y of - channel X. Y may be suppressed if all channels are + out_altvoltageX_outY_enable controls signal generation on + output Y of channel X. Y may be suppressed if all channels are controlled together. -What: /sys/bus/iio/devices/.../ddsX_outY_wavetype +What: /sys/bus/iio/devices/.../out_altvoltageX_outY_wavetype KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: @@ -86,7 +89,7 @@ Description: For a list of available output waveform options read available_output_modes. -What: /sys/bus/iio/devices/.../ddsX_outY_wavetype_available +What: /sys/bus/iio/devices/.../out_altvoltageX_outY_wavetype_available KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: diff --git a/drivers/staging/iio/frequency/ad9832.c b/drivers/staging/iio/frequency/ad9832.c index 7a9b723..2f9abac 100644 --- a/drivers/staging/iio/frequency/ad9832.c +++ b/drivers/staging/iio/frequency/ad9832.c @@ -177,18 +177,18 @@ static IIO_DEV_ATTR_OUT_ENABLE(0, S_IWUSR, NULL, ad9832_write, AD9832_OUTPUT_EN); static struct attribute *ad9832_attributes[] = { - &iio_dev_attr_dds0_freq0.dev_attr.attr, - &iio_dev_attr_dds0_freq1.dev_attr.attr, - &iio_const_attr_dds0_freq_scale.dev_attr.attr, - &iio_dev_attr_dds0_phase0.dev_attr.attr, - &iio_dev_attr_dds0_phase1.dev_attr.attr, - &iio_dev_attr_dds0_phase2.dev_attr.attr, - &iio_dev_attr_dds0_phase3.dev_attr.attr, - &iio_const_attr_dds0_phase_scale.dev_attr.attr, - &iio_dev_attr_dds0_pincontrol_en.dev_attr.attr, - &iio_dev_attr_dds0_freqsymbol.dev_attr.attr, - &iio_dev_attr_dds0_phasesymbol.dev_attr.attr, - &iio_dev_attr_dds0_out_enable.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_frequency0.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_frequency1.dev_attr.attr, + &iio_const_attr_out_altvoltage0_frequency_scale.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phase0.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phase1.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phase2.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phase3.dev_attr.attr, + &iio_const_attr_out_altvoltage0_phase_scale.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_pincontrol_en.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_frequencysymbol.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phasesymbol.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_out_enable.dev_attr.attr, NULL, }; diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c index b8ef8d9..f4b581f 100644 --- a/drivers/staging/iio/frequency/ad9834.c +++ b/drivers/staging/iio/frequency/ad9834.c @@ -218,7 +218,7 @@ static ssize_t ad9834_show_out0_wavetype_available(struct device *dev, } -static IIO_DEVICE_ATTR(dds0_out0_wavetype_available, S_IRUGO, +static IIO_DEVICE_ATTR(out_altvoltage0_out0_wavetype_available, S_IRUGO, ad9834_show_out0_wavetype_available, NULL, 0); static ssize_t ad9834_show_out1_wavetype_available(struct device *dev, @@ -237,7 +237,7 @@ static ssize_t ad9834_show_out1_wavetype_available(struct device *dev, return sprintf(buf, "%s\n", str); } -static IIO_DEVICE_ATTR(dds0_out1_wavetype_available, S_IRUGO, +static IIO_DEVICE_ATTR(out_altvoltage0_out1_wavetype_available, S_IRUGO, ad9834_show_out1_wavetype_available, NULL, 0); /** @@ -263,36 +263,36 @@ static IIO_DEV_ATTR_OUT_WAVETYPE(0, 0, ad9834_store_wavetype, 0); static IIO_DEV_ATTR_OUT_WAVETYPE(0, 1, ad9834_store_wavetype, 1); static struct attribute *ad9834_attributes[] = { - &iio_dev_attr_dds0_freq0.dev_attr.attr, - &iio_dev_attr_dds0_freq1.dev_attr.attr, - &iio_const_attr_dds0_freq_scale.dev_attr.attr, - &iio_dev_attr_dds0_phase0.dev_attr.attr, - &iio_dev_attr_dds0_phase1.dev_attr.attr, - &iio_const_attr_dds0_phase_scale.dev_attr.attr, - &iio_dev_attr_dds0_pincontrol_en.dev_attr.attr, - &iio_dev_attr_dds0_freqsymbol.dev_attr.attr, - &iio_dev_attr_dds0_phasesymbol.dev_attr.attr, - &iio_dev_attr_dds0_out_enable.dev_attr.attr, - &iio_dev_attr_dds0_out1_enable.dev_attr.attr, - &iio_dev_attr_dds0_out0_wavetype.dev_attr.attr, - &iio_dev_attr_dds0_out1_wavetype.dev_attr.attr, - &iio_dev_attr_dds0_out0_wavetype_available.dev_attr.attr, - &iio_dev_attr_dds0_out1_wavetype_available.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_frequency0.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_frequency1.dev_attr.attr, + &iio_const_attr_out_altvoltage0_frequency_scale.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phase0.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phase1.dev_attr.attr, + &iio_const_attr_out_altvoltage0_phase_scale.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_pincontrol_en.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_frequencysymbol.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phasesymbol.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_out_enable.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_out1_enable.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_out0_wavetype.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_out1_wavetype.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_out0_wavetype_available.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_out1_wavetype_available.dev_attr.attr, NULL, }; static struct attribute *ad9833_attributes[] = { - &iio_dev_attr_dds0_freq0.dev_attr.attr, - &iio_dev_attr_dds0_freq1.dev_attr.attr, - &iio_const_attr_dds0_freq_scale.dev_attr.attr, - &iio_dev_attr_dds0_phase0.dev_attr.attr, - &iio_dev_attr_dds0_phase1.dev_attr.attr, - &iio_const_attr_dds0_phase_scale.dev_attr.attr, - &iio_dev_attr_dds0_freqsymbol.dev_attr.attr, - &iio_dev_attr_dds0_phasesymbol.dev_attr.attr, - &iio_dev_attr_dds0_out_enable.dev_attr.attr, - &iio_dev_attr_dds0_out0_wavetype.dev_attr.attr, - &iio_dev_attr_dds0_out0_wavetype_available.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_frequency0.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_frequency1.dev_attr.attr, + &iio_const_attr_out_altvoltage0_frequency_scale.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phase0.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phase1.dev_attr.attr, + &iio_const_attr_out_altvoltage0_phase_scale.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_frequencysymbol.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phasesymbol.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_out_enable.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_out0_wavetype.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_out0_wavetype_available.dev_attr.attr, NULL, }; diff --git a/drivers/staging/iio/frequency/dds.h b/drivers/staging/iio/frequency/dds.h index d8ac3a9..c3342f6 100644 --- a/drivers/staging/iio/frequency/dds.h +++ b/drivers/staging/iio/frequency/dds.h @@ -7,104 +7,104 @@ */ /** - * /sys/bus/iio/devices/.../ddsX_freqY + * /sys/bus/iio/devices/.../out_altvoltageX_frequencyY */ #define IIO_DEV_ATTR_FREQ(_channel, _num, _mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(dds##_channel##_freq##_num, \ + IIO_DEVICE_ATTR(out_altvoltage##_channel##_frequency##_num, \ _mode, _show, _store, _addr) /** - * /sys/bus/iio/devices/.../ddsX_freqY_scale + * /sys/bus/iio/devices/.../out_altvoltageX_frequencyY_scale */ #define IIO_CONST_ATTR_FREQ_SCALE(_channel, _string) \ - IIO_CONST_ATTR(dds##_channel##_freq_scale, _string) + IIO_CONST_ATTR(out_altvoltage##_channel##_frequency_scale, _string) /** - * /sys/bus/iio/devices/.../ddsX_freqsymbol + * /sys/bus/iio/devices/.../out_altvoltageX_frequencysymbol */ #define IIO_DEV_ATTR_FREQSYMBOL(_channel, _mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(dds##_channel##_freqsymbol, \ + IIO_DEVICE_ATTR(out_altvoltage##_channel##_frequencysymbol, \ _mode, _show, _store, _addr); /** - * /sys/bus/iio/devices/.../ddsX_phaseY + * /sys/bus/iio/devices/.../out_altvoltageX_phaseY */ #define IIO_DEV_ATTR_PHASE(_channel, _num, _mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(dds##_channel##_phase##_num, \ + IIO_DEVICE_ATTR(out_altvoltage##_channel##_phase##_num, \ _mode, _show, _store, _addr) /** - * /sys/bus/iio/devices/.../ddsX_phaseY_scale + * /sys/bus/iio/devices/.../out_altvoltageX_phaseY_scale */ #define IIO_CONST_ATTR_PHASE_SCALE(_channel, _string) \ - IIO_CONST_ATTR(dds##_channel##_phase_scale, _string) + IIO_CONST_ATTR(out_altvoltage##_channel##_phase_scale, _string) /** - * /sys/bus/iio/devices/.../ddsX_phasesymbol + * /sys/bus/iio/devices/.../out_altvoltageX_phasesymbol */ #define IIO_DEV_ATTR_PHASESYMBOL(_channel, _mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(dds##_channel##_phasesymbol, \ + IIO_DEVICE_ATTR(out_altvoltage##_channel##_phasesymbol, \ _mode, _show, _store, _addr); /** - * /sys/bus/iio/devices/.../ddsX_pincontrol_en + * /sys/bus/iio/devices/.../out_altvoltageX_pincontrol_en */ #define IIO_DEV_ATTR_PINCONTROL_EN(_channel, _mode, _show, _store, _addr)\ - IIO_DEVICE_ATTR(dds##_channel##_pincontrol_en, \ + IIO_DEVICE_ATTR(out_altvoltage##_channel##_pincontrol_en, \ _mode, _show, _store, _addr); /** - * /sys/bus/iio/devices/.../ddsX_pincontrol_freq_en + * /sys/bus/iio/devices/.../out_altvoltageX_pincontrol_frequency_en */ #define IIO_DEV_ATTR_PINCONTROL_FREQ_EN(_channel, _mode, _show, _store, _addr)\ - IIO_DEVICE_ATTR(dds##_channel##_pincontrol_freq_en, \ + IIO_DEVICE_ATTR(out_altvoltage##_channel##_pincontrol_frequency_en,\ _mode, _show, _store, _addr); /** - * /sys/bus/iio/devices/.../ddsX_pincontrol_phase_en + * /sys/bus/iio/devices/.../out_altvoltageX_pincontrol_phase_en */ #define IIO_DEV_ATTR_PINCONTROL_PHASE_EN(_channel, _mode, _show, _store, _addr)\ - IIO_DEVICE_ATTR(dds##_channel##_pincontrol_phase_en, \ + IIO_DEVICE_ATTR(out_altvoltage##_channel##_pincontrol_phase_en, \ _mode, _show, _store, _addr); /** - * /sys/bus/iio/devices/.../ddsX_out_enable + * /sys/bus/iio/devices/.../out_altvoltageX_out_enable */ #define IIO_DEV_ATTR_OUT_ENABLE(_channel, _mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(dds##_channel##_out_enable, \ + IIO_DEVICE_ATTR(out_altvoltage##_channel##_out_enable, \ _mode, _show, _store, _addr); /** - * /sys/bus/iio/devices/.../ddsX_outY_enable + * /sys/bus/iio/devices/.../out_altvoltageX_outY_enable */ #define IIO_DEV_ATTR_OUTY_ENABLE(_channel, _output, \ _mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(dds##_channel##_out##_output##_enable, \ + IIO_DEVICE_ATTR(out_altvoltage##_channel##_out##_output##_enable,\ _mode, _show, _store, _addr); /** - * /sys/bus/iio/devices/.../ddsX_outY_wavetype + * /sys/bus/iio/devices/.../out_altvoltageX_outY_wavetype */ #define IIO_DEV_ATTR_OUT_WAVETYPE(_channel, _output, _store, _addr) \ - IIO_DEVICE_ATTR(dds##_channel##_out##_output##_wavetype, \ + IIO_DEVICE_ATTR(out_altvoltage##_channel##_out##_output##_wavetype,\ S_IWUSR, NULL, _store, _addr); /** - * /sys/bus/iio/devices/.../ddsX_outY_wavetype_available + * /sys/bus/iio/devices/.../out_altvoltageX_outY_wavetype_available */ #define IIO_CONST_ATTR_OUT_WAVETYPES_AVAILABLE(_channel, _output, _modes)\ - IIO_CONST_ATTR(dds##_channel##_out##_output##_wavetype_available,\ - _modes); + IIO_CONST_ATTR( \ + out_altvoltage##_channel##_out##_output##_wavetype_available, _modes); -- cgit v0.10.2 From fc6d11398e22a3b2cfd7c3b8421653c6075b624b Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 27 Apr 2012 10:58:36 +0200 Subject: iio: core: iio_chan_spec_ext_info: Add private handle There is currently no user, but we might need it in future. So better add it now, before we have to convert drivers afterwards. Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 47a7247..72e33b8 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -281,7 +281,7 @@ static ssize_t iio_read_channel_ext_info(struct device *dev, ext_info = &this_attr->c->ext_info[this_attr->address]; - return ext_info->read(indio_dev, this_attr->c, buf); + return ext_info->read(indio_dev, ext_info->private, this_attr->c, buf); } static ssize_t iio_write_channel_ext_info(struct device *dev, @@ -295,7 +295,8 @@ static ssize_t iio_write_channel_ext_info(struct device *dev, ext_info = &this_attr->c->ext_info[this_attr->address]; - return ext_info->write(indio_dev, this_attr->c, buf, len); + return ext_info->write(indio_dev, ext_info->private, + this_attr->c, buf, len); } static ssize_t iio_read_channel_info(struct device *dev, diff --git a/drivers/staging/iio/dac/ad5064.c b/drivers/staging/iio/dac/ad5064.c index bce641a..047148a 100644 --- a/drivers/staging/iio/dac/ad5064.c +++ b/drivers/staging/iio/dac/ad5064.c @@ -144,14 +144,14 @@ static const char ad5064_powerdown_modes[][15] = { }; static ssize_t ad5064_read_powerdown_mode_available(struct iio_dev *indio_dev, - const struct iio_chan_spec *chan, char *buf) + uintptr_t private, const struct iio_chan_spec *chan, char *buf) { return sprintf(buf, "%s %s %s\n", ad5064_powerdown_modes[1], ad5064_powerdown_modes[2], ad5064_powerdown_modes[3]); } static ssize_t ad5064_read_powerdown_mode(struct iio_dev *indio_dev, - const struct iio_chan_spec *chan, char *buf) + uintptr_t private, const struct iio_chan_spec *chan, char *buf) { struct ad5064_state *st = iio_priv(indio_dev); @@ -160,7 +160,8 @@ static ssize_t ad5064_read_powerdown_mode(struct iio_dev *indio_dev, } static ssize_t ad5064_write_powerdown_mode(struct iio_dev *indio_dev, - const struct iio_chan_spec *chan, const char *buf, size_t len) + uintptr_t private, const struct iio_chan_spec *chan, const char *buf, + size_t len) { struct ad5064_state *st = iio_priv(indio_dev); unsigned int mode, i; @@ -187,7 +188,7 @@ static ssize_t ad5064_write_powerdown_mode(struct iio_dev *indio_dev, } static ssize_t ad5064_read_dac_powerdown(struct iio_dev *indio_dev, - const struct iio_chan_spec *chan, char *buf) + uintptr_t private, const struct iio_chan_spec *chan, char *buf) { struct ad5064_state *st = iio_priv(indio_dev); @@ -195,7 +196,8 @@ static ssize_t ad5064_read_dac_powerdown(struct iio_dev *indio_dev, } static ssize_t ad5064_write_dac_powerdown(struct iio_dev *indio_dev, - const struct iio_chan_spec *chan, const char *buf, size_t len) + uintptr_t private, const struct iio_chan_spec *chan, const char *buf, + size_t len) { struct ad5064_state *st = iio_priv(indio_dev); bool pwr_down; diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index 3b2551f..daa65b3 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -46,13 +46,14 @@ static const char * const ad5446_powerdown_modes[] = { }; static ssize_t ad5446_read_powerdown_mode_available(struct iio_dev *indio_dev, - const struct iio_chan_spec *chan, char *buf) + uintptr_t private, const struct iio_chan_spec *chan, char *buf) { return sprintf(buf, "%s %s %s\n", ad5446_powerdown_modes[1], ad5446_powerdown_modes[2], ad5446_powerdown_modes[3]); } static ssize_t ad5446_write_powerdown_mode(struct iio_dev *indio_dev, + uintptr_t private, const struct iio_chan_spec *chan, const char *buf, size_t len) { @@ -73,6 +74,7 @@ static ssize_t ad5446_write_powerdown_mode(struct iio_dev *indio_dev, } static ssize_t ad5446_read_powerdown_mode(struct iio_dev *indio_dev, + uintptr_t private, const struct iio_chan_spec *chan, char *buf) { @@ -82,6 +84,7 @@ static ssize_t ad5446_read_powerdown_mode(struct iio_dev *indio_dev, } static ssize_t ad5446_read_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, const struct iio_chan_spec *chan, char *buf) { @@ -91,6 +94,7 @@ static ssize_t ad5446_read_dac_powerdown(struct iio_dev *indio_dev, } static ssize_t ad5446_write_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, const struct iio_chan_spec *chan, const char *buf, size_t len) { diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 43002b2..6fdbdb8 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -111,14 +111,17 @@ struct iio_dev; * @shared: Whether this attribute is shared between all channels. * @read: Read callback for this info attribute, may be NULL. * @write: Write callback for this info attribute, may be NULL. + * @private: Data private to the driver. */ struct iio_chan_spec_ext_info { const char *name; bool shared; - ssize_t (*read)(struct iio_dev *, struct iio_chan_spec const *, - char *buf); - ssize_t (*write)(struct iio_dev *, struct iio_chan_spec const *, - const char *buf, size_t len); + ssize_t (*read)(struct iio_dev *, uintptr_t private, + struct iio_chan_spec const *, char *buf); + ssize_t (*write)(struct iio_dev *, uintptr_t private, + struct iio_chan_spec const *, const char *buf, + size_t len); + uintptr_t private; }; /** -- cgit v0.10.2 From 03e7c251533bf45913a73a9cd8f79adc5efe1c30 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 26 Apr 2012 13:46:42 +0200 Subject: MAINTAINERS: Add new Industrial I/O subsystem location Add the new out-of-staging IIO directory to the IIO MAINTAINERS file entry. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/MAINTAINERS b/MAINTAINERS index 2dcfca8..4893026 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3384,6 +3384,7 @@ IIO SUBSYSTEM AND DRIVERS M: Jonathan Cameron L: linux-iio@vger.kernel.org S: Maintained +F: drivers/iio/ F: drivers/staging/iio/ IKANOS/ADI EAGLE ADSL USB DRIVER -- cgit v0.10.2 From 86f3125b84b1b830c19ec733bcbea927590e635d Mon Sep 17 00:00:00 2001 From: "Javier M. Mellid" Date: Thu, 26 Apr 2012 20:45:49 +0200 Subject: staging: sm7xx: remove old references and non updated comments This patch removes obsolete references to previous code and non updated comments. Tested with SM712 Signed-off-by: Javier M. Mellid Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c index 83c582e..39ba558 100644 --- a/drivers/staging/sm7xx/smtcfb.c +++ b/drivers/staging/sm7xx/smtcfb.c @@ -2,31 +2,19 @@ * Silicon Motion SM7XX frame buffer device * * Copyright (C) 2006 Silicon Motion Technology Corp. - * Authors: Ge Wang, gewang@siliconmotion.com - * Boyod boyod.yang@siliconmotion.com.cn + * Authors: Ge Wang, gewang@siliconmotion.com + * Boyod boyod.yang@siliconmotion.com.cn * * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com + * Author: Wu Zhangjin, wuzhangjin@gmail.com * * Copyright (C) 2011 Igalia, S.L. - * Author: Javier M. Mellid + * Author: Javier M. Mellid * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive for - * more details. + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. * - * Version 0.10.26192.21.01 - * - Add PowerPC/Big endian support - * - Verified on 2.6.19.2 - * Boyod.yang - * - * Version 0.09.2621.00.01 - * - Only support Linux Kernel's version 2.6.21 - * Boyod.yang - * - * Version 0.09 - * - Only support Linux Kernel's version 2.6.12 - * Boyod.yang */ #include @@ -57,12 +45,6 @@ struct screen_info smtc_screen_info; * Private structure */ struct smtcfb_info { - /* - * The following is a pointer to be passed into the - * functions below. The modules outside the main - * voyager.c driver have no knowledge as to what - * is within this structure. - */ struct fb_info fb; struct display_switch *dispsw; struct pci_dev *dev; @@ -858,10 +840,6 @@ static int __init sm712vga_setup(char *options) } __setup("vga=", sm712vga_setup); -/* Jason (08/13/2009) - * Original init function changed to probe method to be used by pci_drv - * process used to detect chips replaced with kernel process in pci_drv - */ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -885,9 +863,7 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, if (!sfb) goto failed_free; - /* Jason (08/13/2009) - * Store fb_info to be further used when suspending and resuming - */ + pci_set_drvdata(pdev, sfb); sm7xx_init_hw(); @@ -1021,7 +997,6 @@ failed_free: } -/* Jason (08/11/2009) PCI_DRV wrapper essential structs */ static DEFINE_PCI_DEVICE_TABLE(smtcfb_pci_table) = { { PCI_DEVICE(0x126f, 0x710), }, { PCI_DEVICE(0x126f, 0x712), }, @@ -1030,9 +1005,6 @@ static DEFINE_PCI_DEVICE_TABLE(smtcfb_pci_table) = { }; -/* Jason (08/14/2009) - * do some clean up when the driver module is removed - */ static void __devexit smtcfb_pci_remove(struct pci_dev *pdev) { struct smtcfb_info *sfb; -- cgit v0.10.2 From d89954fa9b3db254d40136080e91f8ce19646345 Mon Sep 17 00:00:00 2001 From: "Javier M. Mellid" Date: Thu, 26 Apr 2012 20:45:50 +0200 Subject: staging: sm7xx: dead code removal This patch remove dead code. Tested with SM712. Signed-off-by: Javier M. Mellid Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c index 39ba558..abed491 100644 --- a/drivers/staging/sm7xx/smtcfb.c +++ b/drivers/staging/sm7xx/smtcfb.c @@ -105,14 +105,6 @@ char __iomem *smtc_VRAMBaseAddress; /* video memory starting address */ static u32 colreg[17]; static struct par_info hw; /* hardware information */ -u16 smtc_ChipIDs[] = { - 0x710, - 0x712, - 0x720 -}; - -#define numSMTCchipIDs ARRAY_SIZE(smtc_ChipIDs) - static struct fb_var_screeninfo smtcfb_var = { .xres = 1024, .yres = 600, diff --git a/drivers/staging/sm7xx/smtcfb.h b/drivers/staging/sm7xx/smtcfb.h index ab95af2..70283a1 100644 --- a/drivers/staging/sm7xx/smtcfb.h +++ b/drivers/staging/sm7xx/smtcfb.h @@ -20,12 +20,6 @@ #define FB_ACCEL_SMI_LYNX 88 -#ifdef __BIG_ENDIAN -#define PC_VGA 0 -#else -#define PC_VGA 1 -#endif - #define SCREEN_X_RES 1024 #define SCREEN_Y_RES 600 #define SCREEN_BPP 16 -- cgit v0.10.2 From bfdd40361987b5c2bd427f0fcf869b8862d4498d Mon Sep 17 00:00:00 2001 From: "Javier M. Mellid" Date: Thu, 26 Apr 2012 20:45:51 +0200 Subject: staging: sm7xx: use dynamic debug support This patch uses dynamic debug support. Tested with SM712 Signed-off-by: Javier M. Mellid Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c index abed491..69721c2 100644 --- a/drivers/staging/sm7xx/smtcfb.c +++ b/drivers/staging/sm7xx/smtcfb.c @@ -33,12 +33,6 @@ #include "smtcfb.h" -#ifdef DEBUG -#define smdbg(format, arg...) printk(KERN_DEBUG format , ## arg) -#else -#define smdbg(format, arg...) -#endif - struct screen_info smtc_screen_info; /* @@ -134,8 +128,9 @@ static void sm712_set_timing(struct smtcfb_info *sfb, int i = 0, j = 0; u32 m_nScreenStride; - smdbg("\nppar_info->width = %d ppar_info->height = %d" - "sfb->fb.var.bits_per_pixel = %d ppar_info->hz = %d\n", + dev_dbg(&sfb->dev->dev, + "ppar_info->width=%d ppar_info->height=%d" + "sfb->fb.var.bits_per_pixel=%d ppar_info->hz=%d\n", ppar_info->width, ppar_info->height, sfb->fb.var.bits_per_pixel, ppar_info->hz); @@ -145,13 +140,14 @@ static void sm712_set_timing(struct smtcfb_info *sfb, VGAMode[j].bpp == sfb->fb.var.bits_per_pixel && VGAMode[j].hz == ppar_info->hz) { - smdbg("\nVGAMode[j].mmSizeX = %d VGAMode[j].mmSizeY =" - "%d VGAMode[j].bpp = %d" - "VGAMode[j].hz=%d\n", - VGAMode[j].mmSizeX, VGAMode[j].mmSizeY, - VGAMode[j].bpp, VGAMode[j].hz); + dev_dbg(&sfb->dev->dev, + "VGAMode[j].mmSizeX=%d VGAMode[j].mmSizeY=%d" + "VGAMode[j].bpp=%d VGAMode[j].hz=%d\n", + VGAMode[j].mmSizeX, VGAMode[j].mmSizeY, + VGAMode[j].bpp, VGAMode[j].hz); - smdbg("VGAMode index=%d\n", j); + dev_dbg(&sfb->dev->dev, + "VGAMode index=%d\n", j); smtc_mmiowb(0x0, 0x3c6); @@ -805,16 +801,14 @@ static int __init sm712vga_setup(char *options) { int index; - if (!options || !*options) { - smdbg("\n No vga parameter\n"); + if (!options || !*options) return -EINVAL; - } smtc_screen_info.lfb_width = 0; smtc_screen_info.lfb_height = 0; smtc_screen_info.lfb_depth = 0; - smdbg("\nsm712vga_setup = %s\n", options); + pr_debug("sm712vga_setup = %s\n", options); for (index = 0; index < ARRAY_SIZE(vesa_mode); -- cgit v0.10.2 From 6f54b0948ad459fa9ffa22335aba2e2a86365b60 Mon Sep 17 00:00:00 2001 From: "Javier M. Mellid" Date: Thu, 26 Apr 2012 20:45:52 +0200 Subject: staging: sm7xx: use dynamic debug support to show info and errors This patch makes happy checkpatch script. It uses dynamic debug support to show info and errors. It unifies the way to report messages in the same way that debug messages. Tested with SM712 Signed-off-by: Javier M. Mellid Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c index 69721c2..e351e08 100644 --- a/drivers/staging/sm7xx/smtcfb.c +++ b/drivers/staging/sm7xx/smtcfb.c @@ -736,17 +736,17 @@ static void smtc_unmap_mmio(struct smtcfb_info *sfb) */ static int smtc_map_smem(struct smtcfb_info *sfb, - struct pci_dev *dev, u_long smem_len) + struct pci_dev *pdev, u_long smem_len) { if (sfb->fb.var.bits_per_pixel == 32) { #ifdef __BIG_ENDIAN - sfb->fb.fix.smem_start = pci_resource_start(dev, 0) + sfb->fb.fix.smem_start = pci_resource_start(pdev, 0) + 0x800000; #else - sfb->fb.fix.smem_start = pci_resource_start(dev, 0); + sfb->fb.fix.smem_start = pci_resource_start(pdev, 0); #endif } else { - sfb->fb.fix.smem_start = pci_resource_start(dev, 0); + sfb->fb.fix.smem_start = pci_resource_start(pdev, 0); } sfb->fb.fix.smem_len = smem_len; @@ -754,8 +754,8 @@ static int smtc_map_smem(struct smtcfb_info *sfb, sfb->fb.screen_base = smtc_VRAMBaseAddress; if (!sfb->fb.screen_base) { - printk(KERN_ERR "%s: unable to map screen memory\n", - sfb->fb.fix.id); + dev_err(&pdev->dev, + "%s: unable to map screen memory\n", sfb->fb.fix.id); return -ENOMEM; } @@ -835,8 +835,8 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, int err; unsigned long pFramebufferPhysical; - printk(KERN_INFO - "Silicon Motion display driver " SMTC_LINUX_FB_VERSION "\n"); + dev_info(&pdev->dev, + "Silicon Motion display driver " SMTC_LINUX_FB_VERSION); err = pci_enable_device(pdev); /* enable SMTC chip */ if (err) @@ -895,14 +895,14 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, if (sfb->fb.var.bits_per_pixel == 32) { smtc_VRAMBaseAddress += 0x800000; hw.m_pLFB += 0x800000; - printk(KERN_INFO - "\nsmtc_VRAMBaseAddress=%p hw.m_pLFB=%p\n", - smtc_VRAMBaseAddress, hw.m_pLFB); + dev_info(&pdev->dev, + "smtc_VRAMBaseAddress=%p sfb->m_pLFB=%p", + smtc_VRAMBaseAddress, sfb->m_pLFB); } #endif if (!smtc_RegBaseAddress) { - printk(KERN_ERR - "%s: unable to map memory mapped IO\n", + dev_err(&pdev->dev, + "%s: unable to map memory mapped IO!", sfb->fb.fix.id); err = -ENOMEM; goto failed_fb; @@ -936,8 +936,8 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, smtc_seqw(0x6b, 0x02); break; default: - printk(KERN_ERR - "No valid Silicon Motion display chip was detected!\n"); + dev_err(&pdev->dev, + "No valid Silicon Motion display chip was detected!"); goto failed_fb; } @@ -961,15 +961,16 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, if (err < 0) goto failed; - printk(KERN_INFO "Silicon Motion SM%X Rev%X primary display mode" - "%dx%d-%d Init Complete.\n", hw.chipID, hw.chipRevID, - sfb->fb.var.xres, sfb->fb.var.yres, - sfb->fb.var.bits_per_pixel); + dev_info(&pdev->dev, + "Silicon Motion SM%X Rev%X primary display mode" + "%dx%d-%d Init Complete.\n", hw.chipID, hw.chipRevID, + sfb->fb.var.xres, sfb->fb.var.yres, + sfb->fb.var.bits_per_pixel); return 0; failed: - printk(KERN_ERR "Silicon Motion, Inc. primary display init fail\n"); + dev_err(&pdev->dev, "Silicon Motion, Inc. primary display init fail."); smtc_unmap_smem(sfb); smtc_unmap_mmio(sfb); -- cgit v0.10.2 From 9be467d5b7ef350ef50eddcccfb5ad69b2c19090 Mon Sep 17 00:00:00 2001 From: "Javier M. Mellid" Date: Thu, 26 Apr 2012 20:45:53 +0200 Subject: staging: sm7xx: merge hardware information in smtcfb_info struct With this patch smtcfb_info becomes the main structure to reach/handle state. fb_info struct links this struct via its private data field. This change improves encapsulation in functions. It reduces the number of arguments used in signatures too. Tested with SM712 Signed-off-by: Javier M. Mellid Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c index e351e08..5defdaf 100644 --- a/drivers/staging/sm7xx/smtcfb.c +++ b/drivers/staging/sm7xx/smtcfb.c @@ -40,21 +40,12 @@ struct screen_info smtc_screen_info; */ struct smtcfb_info { struct fb_info fb; - struct display_switch *dispsw; - struct pci_dev *dev; - signed int currcon; - + struct pci_dev *pdev; struct { u8 red, green, blue; } palette[NR_RGB]; - u_int palette_size; -}; -struct par_info { - /* - * Hardware - */ u16 chipID; unsigned char __iomem *m_pMMIO; char __iomem *m_pLFB; @@ -97,7 +88,6 @@ char __iomem *smtc_RegBaseAddress; /* Memory Map IO starting address */ char __iomem *smtc_VRAMBaseAddress; /* video memory starting address */ static u32 colreg[17]; -static struct par_info hw; /* hardware information */ static struct fb_var_screeninfo smtcfb_var = { .xres = 1024, @@ -122,32 +112,29 @@ static struct fb_fix_screeninfo smtcfb_fix = { .accel = FB_ACCEL_SMI_LYNX, }; -static void sm712_set_timing(struct smtcfb_info *sfb, - struct par_info *ppar_info) +static void sm712_set_timing(struct smtcfb_info *sfb) { int i = 0, j = 0; u32 m_nScreenStride; - dev_dbg(&sfb->dev->dev, - "ppar_info->width=%d ppar_info->height=%d" - "sfb->fb.var.bits_per_pixel=%d ppar_info->hz=%d\n", - ppar_info->width, ppar_info->height, - sfb->fb.var.bits_per_pixel, ppar_info->hz); + dev_dbg(&sfb->pdev->dev, + "sfb->width=%d sfb->height=%d " + "sfb->fb.var.bits_per_pixel=%d sfb->hz=%d\n", + sfb->width, sfb->height, sfb->fb.var.bits_per_pixel, sfb->hz); for (j = 0; j < numVGAModes; j++) { - if (VGAMode[j].mmSizeX == ppar_info->width && - VGAMode[j].mmSizeY == ppar_info->height && + if (VGAMode[j].mmSizeX == sfb->width && + VGAMode[j].mmSizeY == sfb->height && VGAMode[j].bpp == sfb->fb.var.bits_per_pixel && - VGAMode[j].hz == ppar_info->hz) { + VGAMode[j].hz == sfb->hz) { - dev_dbg(&sfb->dev->dev, - "VGAMode[j].mmSizeX=%d VGAMode[j].mmSizeY=%d" + dev_dbg(&sfb->pdev->dev, + "VGAMode[j].mmSizeX=%d VGAMode[j].mmSizeY=%d " "VGAMode[j].bpp=%d VGAMode[j].hz=%d\n", VGAMode[j].mmSizeX, VGAMode[j].mmSizeY, VGAMode[j].bpp, VGAMode[j].hz); - dev_dbg(&sfb->dev->dev, - "VGAMode index=%d\n", j); + dev_dbg(&sfb->pdev->dev, "VGAMode index=%d\n", j); smtc_mmiowb(0x0, 0x3c6); @@ -208,37 +195,37 @@ static void sm712_set_timing(struct smtcfb_info *sfb, smtc_mmiowb(0x67, 0x3c2); /* set VPR registers */ - writel(0x0, ppar_info->m_pVPR + 0x0C); - writel(0x0, ppar_info->m_pVPR + 0x40); + writel(0x0, sfb->m_pVPR + 0x0C); + writel(0x0, sfb->m_pVPR + 0x40); /* set data width */ m_nScreenStride = - (ppar_info->width * sfb->fb.var.bits_per_pixel) / 64; + (sfb->width * sfb->fb.var.bits_per_pixel) / 64; switch (sfb->fb.var.bits_per_pixel) { case 8: - writel(0x0, ppar_info->m_pVPR + 0x0); + writel(0x0, sfb->m_pVPR + 0x0); break; case 16: - writel(0x00020000, ppar_info->m_pVPR + 0x0); + writel(0x00020000, sfb->m_pVPR + 0x0); break; case 24: - writel(0x00040000, ppar_info->m_pVPR + 0x0); + writel(0x00040000, sfb->m_pVPR + 0x0); break; case 32: - writel(0x00030000, ppar_info->m_pVPR + 0x0); + writel(0x00030000, sfb->m_pVPR + 0x0); break; } writel((u32) (((m_nScreenStride + 2) << 16) | m_nScreenStride), - ppar_info->m_pVPR + 0x10); + sfb->m_pVPR + 0x10); } static void sm712_setpalette(int regno, unsigned red, unsigned green, unsigned blue, struct fb_info *info) { - struct par_info *cur_par = (struct par_info *)info->par; + struct smtcfb_info *sfb = info->par; - if (cur_par->BaseAddressInVRAM) + if (sfb->BaseAddressInVRAM) /* * second display palette for dual head. Enable CRT RAM, 6-bit * RAM @@ -253,14 +240,13 @@ static void sm712_setpalette(int regno, unsigned red, unsigned green, smtc_mmiowb(blue >> 10, dac_val); } -static void smtc_set_timing(struct smtcfb_info *sfb, struct par_info - *ppar_info) +static void smtc_set_timing(struct smtcfb_info *sfb) { - switch (ppar_info->chipID) { + switch (sfb->chipID) { case 0x710: case 0x712: case 0x720: - sm712_set_timing(sfb, ppar_info); + sm712_set_timing(sfb); break; } } @@ -630,10 +616,10 @@ void smtcfb_setmode(struct smtcfb_info *sfb) break; } - hw.width = sfb->fb.var.xres; - hw.height = sfb->fb.var.yres; - hw.hz = 60; - smtc_set_timing(sfb, &hw); + sfb->width = sfb->fb.var.xres; + sfb->height = sfb->fb.var.yres; + sfb->hz = 60; + smtc_set_timing(sfb); } static int smtc_check_var(struct fb_var_screeninfo *var, struct fb_info *info) @@ -680,8 +666,7 @@ static struct fb_ops smtcfb_ops = { /* * Alloc struct smtcfb_info and assign the default value */ -static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *dev, - char *name) +static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *pdev, char *name) { struct smtcfb_info *sfb; @@ -690,8 +675,7 @@ static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *dev, if (!sfb) return NULL; - sfb->currcon = -1; - sfb->dev = dev; + sfb->pdev = pdev; /*** Init sfb->fb with default value ***/ sfb->fb.flags = FBINFO_FLAG_DEFAULT; @@ -715,7 +699,9 @@ static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *dev, /* text mode acceleration */ sfb->fb.var.accel_flags = FB_ACCELF_TEXT; sfb->fb.var.vmode = FB_VMODE_NONINTERLACED; - sfb->fb.par = &hw; + + sfb->fb.par = sfb; + sfb->fb.pseudo_palette = colreg; return sfb; @@ -842,14 +828,14 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, if (err) return err; - hw.chipID = ent->device; - sprintf(name, "sm%Xfb", hw.chipID); - sfb = smtc_alloc_fb_info(pdev, name); if (!sfb) goto failed_free; + sfb->chipID = ent->device; + sprintf(name, "sm%Xfb", sfb->chipID); + pci_set_drvdata(pdev, sfb); sm7xx_init_hw(); @@ -872,29 +858,29 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, #endif /* Map address and memory detection */ pFramebufferPhysical = pci_resource_start(pdev, 0); - pci_read_config_byte(pdev, PCI_REVISION_ID, &hw.chipRevID); + pci_read_config_byte(pdev, PCI_REVISION_ID, &sfb->chipRevID); - switch (hw.chipID) { + switch (sfb->chipID) { case 0x710: case 0x712: sfb->fb.fix.mmio_start = pFramebufferPhysical + 0x00400000; sfb->fb.fix.mmio_len = 0x00400000; smem_size = SM712_VIDEOMEMORYSIZE; #ifdef __BIG_ENDIAN - hw.m_pLFB = (smtc_VRAMBaseAddress = + sfb->m_pLFB = (smtc_VRAMBaseAddress = ioremap(pFramebufferPhysical, 0x00c00000)); #else - hw.m_pLFB = (smtc_VRAMBaseAddress = + sfb->m_pLFB = (smtc_VRAMBaseAddress = ioremap(pFramebufferPhysical, 0x00800000)); #endif - hw.m_pMMIO = (smtc_RegBaseAddress = + sfb->m_pMMIO = (smtc_RegBaseAddress = smtc_VRAMBaseAddress + 0x00700000); - hw.m_pDPR = smtc_VRAMBaseAddress + 0x00408000; - hw.m_pVPR = hw.m_pLFB + 0x0040c000; + sfb->m_pDPR = smtc_VRAMBaseAddress + 0x00408000; + sfb->m_pVPR = sfb->m_pLFB + 0x0040c000; #ifdef __BIG_ENDIAN if (sfb->fb.var.bits_per_pixel == 32) { smtc_VRAMBaseAddress += 0x800000; - hw.m_pLFB += 0x800000; + sfb->m_pLFB += 0x800000; dev_info(&pdev->dev, "smtc_VRAMBaseAddress=%p sfb->m_pLFB=%p", smtc_VRAMBaseAddress, sfb->m_pLFB); @@ -924,12 +910,12 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, sfb->fb.fix.mmio_start = pFramebufferPhysical; sfb->fb.fix.mmio_len = 0x00200000; smem_size = SM722_VIDEOMEMORYSIZE; - hw.m_pDPR = ioremap(pFramebufferPhysical, 0x00a00000); - hw.m_pLFB = (smtc_VRAMBaseAddress = - hw.m_pDPR + 0x00200000); - hw.m_pMMIO = (smtc_RegBaseAddress = - hw.m_pDPR + 0x000c0000); - hw.m_pVPR = hw.m_pDPR + 0x800; + sfb->m_pDPR = ioremap(pFramebufferPhysical, 0x00a00000); + sfb->m_pLFB = (smtc_VRAMBaseAddress = + sfb->m_pDPR + 0x00200000); + sfb->m_pMMIO = (smtc_RegBaseAddress = + sfb->m_pDPR + 0x000c0000); + sfb->m_pVPR = sfb->m_pDPR + 0x800; smtc_seqw(0x62, 0xff); smtc_seqw(0x6a, 0x0d); @@ -954,18 +940,16 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, smtcfb_setmode(sfb); /* Primary display starting from 0 position */ - hw.BaseAddressInVRAM = 0; - sfb->fb.par = &hw; + sfb->BaseAddressInVRAM = 0; err = register_framebuffer(&sfb->fb); if (err < 0) goto failed; dev_info(&pdev->dev, - "Silicon Motion SM%X Rev%X primary display mode" - "%dx%d-%d Init Complete.\n", hw.chipID, hw.chipRevID, - sfb->fb.var.xres, sfb->fb.var.yres, - sfb->fb.var.bits_per_pixel); + "Silicon Motion SM%X Rev%X primary display mode %dx%d-%d Init Complete.", + sfb->chipID, sfb->chipRevID, sfb->fb.var.xres, + sfb->fb.var.yres, sfb->fb.var.bits_per_pixel); return 0; @@ -1037,7 +1021,7 @@ static int smtcfb_pci_resume(struct device *device) /* reinit hardware */ sm7xx_init_hw(); - switch (hw.chipID) { + switch (sfb->chipID) { case 0x710: case 0x712: /* set MCLK = 14.31818 * (0x16 / 0x2) */ -- cgit v0.10.2 From 5c40fb37c7e43db66ba8ecd4499ad5a6c2e734b8 Mon Sep 17 00:00:00 2001 From: "Javier M. Mellid" Date: Thu, 26 Apr 2012 20:45:54 +0200 Subject: staging: sm7xx: remove driver version support This patch removes non used version support. Code won't show version message almost 4 years old. Tested with SM712 Signed-off-by: Javier M. Mellid Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c index 5defdaf..83756a8 100644 --- a/drivers/staging/sm7xx/smtcfb.c +++ b/drivers/staging/sm7xx/smtcfb.c @@ -821,8 +821,7 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, int err; unsigned long pFramebufferPhysical; - dev_info(&pdev->dev, - "Silicon Motion display driver " SMTC_LINUX_FB_VERSION); + dev_info(&pdev->dev, "Silicon Motion display driver."); err = pci_enable_device(pdev); /* enable SMTC chip */ if (err) diff --git a/drivers/staging/sm7xx/smtcfb.h b/drivers/staging/sm7xx/smtcfb.h index 70283a1..43d86f8 100644 --- a/drivers/staging/sm7xx/smtcfb.h +++ b/drivers/staging/sm7xx/smtcfb.h @@ -13,8 +13,6 @@ * more details. */ -#define SMTC_LINUX_FB_VERSION "version 0.11.2619.21.01 July 27, 2008" - #define NR_PALETTE 256 #define NR_RGB 2 -- cgit v0.10.2 From acbaa0bf052a363de640725972563a34d61cfb82 Mon Sep 17 00:00:00 2001 From: "Javier M. Mellid" Date: Thu, 26 Apr 2012 20:45:55 +0200 Subject: staging: sm7xx: rename function This patch changes the name of function cfb_blank to smtc_blank. This function is not implemented like a generic function for frame buffer. Having the old prefix becomes confused when reading fb_ops structs. Tested with SM712 Signed-off-by: Javier M. Mellid Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c index 83756a8..746c4cd5 100644 --- a/drivers/staging/sm7xx/smtcfb.c +++ b/drivers/staging/sm7xx/smtcfb.c @@ -266,7 +266,7 @@ static inline unsigned int chan_to_field(unsigned int chan, return chan << bf->offset; } -static int cfb_blank(int blank_mode, struct fb_info *info) +static int smtc_blank(int blank_mode, struct fb_info *info) { /* clear DPMS setting */ switch (blank_mode) { @@ -653,7 +653,7 @@ static struct fb_ops smtcfb_ops = { .fb_check_var = smtc_check_var, .fb_set_par = smtc_set_par, .fb_setcolreg = smtc_setcolreg, - .fb_blank = cfb_blank, + .fb_blank = smtc_blank, .fb_fillrect = cfb_fillrect, .fb_imageblit = cfb_imageblit, .fb_copyarea = cfb_copyarea, -- cgit v0.10.2 From d9a861d55e0cf60829956d7c6e18b7de0b02ab92 Mon Sep 17 00:00:00 2001 From: "Kim, Milo" Date: Thu, 26 Apr 2012 22:01:10 -0700 Subject: staging: android: timed_output : disable the timed output device when the device is unregistered (Life cycle of timed output device driver) 1) register the device as the timed output 2) enable() ops is called via the sysfs timeout > 0 : timer is activated and device is turned on timeout = 0 : timer is cancelled and device is off 3) unregister the timed output device if not used any more So the registered device should be disabled explicitly when the module is removed. ('disabled' means the timer is stopped and the device is turned off) Rather than implementing that code in each driver, just call enable() with timeout = 0 to clean up the driver. Signed-off-by: Milo(Woogyom) Kim Cc: Mike Lockwood Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/timed_output.c b/drivers/staging/android/timed_output.c index f373422..38d930c 100644 --- a/drivers/staging/android/timed_output.c +++ b/drivers/staging/android/timed_output.c @@ -99,6 +99,7 @@ EXPORT_SYMBOL_GPL(timed_output_dev_register); void timed_output_dev_unregister(struct timed_output_dev *tdev) { + tdev->enable(tdev, 0); device_remove_file(tdev->dev, &dev_attr_enable); device_destroy(timed_output_class, MKDEV(0, tdev->index)); dev_set_drvdata(tdev->dev, NULL); -- cgit v0.10.2 From 37859f8893c00fe4baa95f61ba560b9990f59484 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 14:10:15 -0700 Subject: staging: comedi: introduce 'comedi_board' helper function This helper function is used to fetch the comedi_device board_ptr which is used during the attach to pass board specific information to the comedi drivers. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 300fd84..02e4ae0 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -235,6 +235,11 @@ struct comedi_device { void (*close) (struct comedi_device *dev); }; +static inline const void *comedi_board(struct comedi_device *dev) +{ + return dev->board_ptr; +} + struct comedi_device_file_info { struct comedi_device *device; struct comedi_subdevice *read_subdevice; -- cgit v0.10.2 From b85eec95ec5520037611727399f21692316e0213 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 17:59:18 -0700 Subject: staging: comedi: refactor dt2815 driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c index 4155da4..f5a0dc5 100644 --- a/drivers/staging/comedi/drivers/dt2815.c +++ b/drivers/staging/comedi/drivers/dt2815.c @@ -72,31 +72,6 @@ static const struct comedi_lrange #define DT2815_DATA 0 #define DT2815_STATUS 1 -static int dt2815_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int dt2815_detach(struct comedi_device *dev); -static struct comedi_driver driver_dt2815 = { - .driver_name = "dt2815", - .module = THIS_MODULE, - .attach = dt2815_attach, - .detach = dt2815_detach, -}; - -static int __init driver_dt2815_init_module(void) -{ - return comedi_driver_register(&driver_dt2815); -} - -static void __exit driver_dt2815_cleanup_module(void) -{ - comedi_driver_unregister(&driver_dt2815); -} - -module_init(driver_dt2815_init_module); -module_exit(driver_dt2815_cleanup_module); - -static void dt2815_free_resources(struct comedi_device *dev); - struct dt2815_private { const struct comedi_lrange *range_type_list[8]; @@ -267,6 +242,25 @@ static int dt2815_detach(struct comedi_device *dev) return 0; } +static struct comedi_driver driver_dt2815 = { + .driver_name = "dt2815", + .module = THIS_MODULE, + .attach = dt2815_attach, + .detach = dt2815_detach, +}; + +static int __init driver_dt2815_init_module(void) +{ + return comedi_driver_register(&driver_dt2815); +} +module_init(driver_dt2815_init_module); + +static void __exit driver_dt2815_cleanup_module(void) +{ + comedi_driver_unregister(&driver_dt2815); +} +module_exit(driver_dt2815_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 597092fcc448ae4716274e2d80830b5bc54e5617 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 17:57:16 -0700 Subject: staging: comedi: refactor dt2817 driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dt2817.c b/drivers/staging/comedi/drivers/dt2817.c index 99c1584..45d9a82 100644 --- a/drivers/staging/comedi/drivers/dt2817.c +++ b/drivers/staging/comedi/drivers/dt2817.c @@ -47,29 +47,6 @@ Configuration options: #define DT2817_CR 0 #define DT2817_DATA 1 -static int dt2817_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int dt2817_detach(struct comedi_device *dev); -static struct comedi_driver driver_dt2817 = { - .driver_name = "dt2817", - .module = THIS_MODULE, - .attach = dt2817_attach, - .detach = dt2817_detach, -}; - -static int __init driver_dt2817_init_module(void) -{ - return comedi_driver_register(&driver_dt2817); -} - -static void __exit driver_dt2817_cleanup_module(void) -{ - comedi_driver_unregister(&driver_dt2817); -} - -module_init(driver_dt2817_init_module); -module_exit(driver_dt2817_cleanup_module); - static int dt2817_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -192,6 +169,25 @@ static int dt2817_detach(struct comedi_device *dev) return 0; } +static struct comedi_driver driver_dt2817 = { + .driver_name = "dt2817", + .module = THIS_MODULE, + .attach = dt2817_attach, + .detach = dt2817_detach, +}; + +static int __init driver_dt2817_init_module(void) +{ + return comedi_driver_register(&driver_dt2817); +} +module_init(driver_dt2817_init_module); + +static void __exit driver_dt2817_cleanup_module(void) +{ + comedi_driver_unregister(&driver_dt2817); +} +module_exit(driver_dt2817_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 236788fcf0ecead56090d7d061f51974bdfed4a0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 17:35:22 -0700 Subject: staging: comedi: refactor ke_counter driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index fef6ea7..0db76a5 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -46,18 +46,6 @@ Kolter Electronic PCI Counter Card. #define PCI_VENDOR_ID_KOLTER 0x1001 #define CNT_CARD_DEVICE_ID 0x0014 -/*-- function prototypes ----------------------------------------------------*/ - -static int cnt_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int cnt_detach(struct comedi_device *dev); - -static DEFINE_PCI_DEVICE_TABLE(cnt_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_KOLTER, CNT_CARD_DEVICE_ID) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, cnt_pci_table); - /*-- board specification structure ------------------------------------------*/ struct cnt_board_struct { @@ -87,51 +75,6 @@ struct cnt_device_private { #define devpriv ((struct cnt_device_private *)dev->private) -static struct comedi_driver cnt_driver = { - .driver_name = CNT_DRIVER_NAME, - .module = THIS_MODULE, - .attach = cnt_attach, - .detach = cnt_detach, -}; - -static int __devinit cnt_driver_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, &cnt_driver); -} - -static void __devexit cnt_driver_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver cnt_driver_pci_driver = { - .id_table = cnt_pci_table, - .probe = &cnt_driver_pci_probe, - .remove = __devexit_p(&cnt_driver_pci_remove) -}; - -static int __init cnt_driver_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&cnt_driver); - if (retval < 0) - return retval; - - cnt_driver_pci_driver.name = (char *)cnt_driver.driver_name; - return pci_register_driver(&cnt_driver_pci_driver); -} - -static void __exit cnt_driver_cleanup_module(void) -{ - pci_unregister_driver(&cnt_driver_pci_driver); - comedi_driver_unregister(&cnt_driver); -} - -module_init(cnt_driver_init_module); -module_exit(cnt_driver_cleanup_module); - /*-- counter write ----------------------------------------------------------*/ /* This should be used only for resetting the counters; maybe it is better @@ -181,8 +124,6 @@ static int cnt_rinsn(struct comedi_device *dev, return 1; } -/*-- attach -----------------------------------------------------------------*/ - static int cnt_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *subdevice; @@ -278,8 +219,6 @@ found: return 0; } -/*-- detach -----------------------------------------------------------------*/ - static int cnt_detach(struct comedi_device *dev) { if (devpriv && devpriv->pcidev) { @@ -292,6 +231,56 @@ static int cnt_detach(struct comedi_device *dev) return 0; } +static struct comedi_driver cnt_driver = { + .driver_name = CNT_DRIVER_NAME, + .module = THIS_MODULE, + .attach = cnt_attach, + .detach = cnt_detach, +}; + +static int __devinit cnt_driver_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &cnt_driver); +} + +static void __devexit cnt_driver_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(cnt_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_KOLTER, CNT_CARD_DEVICE_ID) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, cnt_pci_table); + +static struct pci_driver cnt_driver_pci_driver = { + .id_table = cnt_pci_table, + .probe = cnt_driver_pci_probe, + .remove = __devexit_p(cnt_driver_pci_remove), +}; + +static int __init cnt_driver_init_module(void) +{ + int retval; + + retval = comedi_driver_register(&cnt_driver); + if (retval < 0) + return retval; + + cnt_driver_pci_driver.name = (char *)cnt_driver.driver_name; + return pci_register_driver(&cnt_driver_pci_driver); +} +module_init(cnt_driver_init_module); + +static void __exit cnt_driver_cleanup_module(void) +{ + pci_unregister_driver(&cnt_driver_pci_driver); + comedi_driver_unregister(&cnt_driver); +} +module_exit(cnt_driver_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From a39eb9061b4d16f0760fff0022e6b6e826275386 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 17:31:27 -0700 Subject: staging: comedi: refactor fl512 driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c index 7f49add..88c18ea 100644 --- a/drivers/staging/comedi/drivers/fl512.c +++ b/drivers/staging/comedi/drivers/fl512.c @@ -42,38 +42,6 @@ static const struct comedi_lrange range_fl512 = { 4, { } }; -static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int fl512_detach(struct comedi_device *dev); - -static struct comedi_driver driver_fl512 = { - .driver_name = "fl512", - .module = THIS_MODULE, - .attach = fl512_attach, - .detach = fl512_detach, -}; - -static int __init driver_fl512_init_module(void) -{ - return comedi_driver_register(&driver_fl512); -} - -static void __exit driver_fl512_cleanup_module(void) -{ - comedi_driver_unregister(&driver_fl512); -} - -module_init(driver_fl512_init_module); -module_exit(driver_fl512_cleanup_module); - -static int fl512_ai_insn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); -static int fl512_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int fl512_ao_insn_readback(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - /* * fl512_ai_insn : this is the analog input function */ @@ -140,9 +108,6 @@ static int fl512_ao_insn_readback(struct comedi_device *dev, return n; } -/* - * start attach - */ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it) { unsigned long iobase; @@ -217,6 +182,25 @@ static int fl512_detach(struct comedi_device *dev) return 0; } +static struct comedi_driver driver_fl512 = { + .driver_name = "fl512", + .module = THIS_MODULE, + .attach = fl512_attach, + .detach = fl512_detach, +}; + +static int __init driver_fl512_init_module(void) +{ + return comedi_driver_register(&driver_fl512); +} +module_init(driver_fl512_init_module); + +static void __exit driver_fl512_cleanup_module(void) +{ + comedi_driver_unregister(&driver_fl512); +} +module_exit(driver_fl512_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 8dbf14605d85b84d8a8ef2d870aa377ace947075 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 17:13:48 -0700 Subject: staging: comedi: refactor pcl711 driver to remove the forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c index ce6e514..fcb7cea 100644 --- a/drivers/staging/comedi/drivers/pcl711.c +++ b/drivers/staging/comedi/drivers/pcl711.c @@ -148,41 +148,8 @@ struct pcl711_board { const struct comedi_lrange *ai_range_type; }; -static const struct pcl711_board boardtypes[] = { - {"pcl711", 0, 0, 0, 5, 8, 1, 0, &range_bipolar5}, - {"pcl711b", 1, 0, 0, 5, 8, 1, 7, &range_pcl711b_ai}, - {"acl8112hg", 0, 1, 0, 12, 16, 2, 15, &range_acl8112hg_ai}, - {"acl8112dg", 0, 1, 1, 9, 16, 2, 15, &range_acl8112dg_ai}, -}; - #define this_board ((const struct pcl711_board *)dev->board_ptr) -static int pcl711_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcl711_detach(struct comedi_device *dev); -static struct comedi_driver driver_pcl711 = { - .driver_name = "pcl711", - .module = THIS_MODULE, - .attach = pcl711_attach, - .detach = pcl711_detach, - .board_name = &boardtypes[0].name, - .num_names = ARRAY_SIZE(boardtypes), - .offset = sizeof(struct pcl711_board), -}; - -static int __init driver_pcl711_init_module(void) -{ - return comedi_driver_register(&driver_pcl711); -} - -static void __exit driver_pcl711_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl711); -} - -module_init(driver_pcl711_init_module); -module_exit(driver_pcl711_cleanup_module); - struct pcl711_private { int board; @@ -512,21 +479,6 @@ static int pcl711_do_insn_bits(struct comedi_device *dev, return 2; } -/* Free any resources that we have claimed */ -static int pcl711_detach(struct comedi_device *dev) -{ - printk(KERN_INFO "comedi%d: pcl711: remove\n", dev->minor); - - if (dev->irq) - free_irq(dev->irq, dev); - - if (dev->iobase) - release_region(dev->iobase, PCL711_SIZE); - - return 0; -} - -/* Initialization */ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) { int ret; @@ -639,6 +591,48 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } +static int pcl711_detach(struct comedi_device *dev) +{ + printk(KERN_INFO "comedi%d: pcl711: remove\n", dev->minor); + + if (dev->irq) + free_irq(dev->irq, dev); + + if (dev->iobase) + release_region(dev->iobase, PCL711_SIZE); + + return 0; +} + +static const struct pcl711_board boardtypes[] = { + { "pcl711", 0, 0, 0, 5, 8, 1, 0, &range_bipolar5 }, + { "pcl711b", 1, 0, 0, 5, 8, 1, 7, &range_pcl711b_ai }, + { "acl8112hg", 0, 1, 0, 12, 16, 2, 15, &range_acl8112hg_ai }, + { "acl8112dg", 0, 1, 1, 9, 16, 2, 15, &range_acl8112dg_ai }, +}; + +static struct comedi_driver driver_pcl711 = { + .driver_name = "pcl711", + .module = THIS_MODULE, + .attach = pcl711_attach, + .detach = pcl711_detach, + .board_name = &boardtypes[0].name, + .num_names = ARRAY_SIZE(boardtypes), + .offset = sizeof(struct pcl711_board), +}; + +static int __init driver_pcl711_init_module(void) +{ + return comedi_driver_register(&driver_pcl711); +} +module_init(driver_pcl711_init_module); + +static void __exit driver_pcl711_cleanup_module(void) +{ + comedi_driver_unregister(&driver_pcl711); +} +module_exit(driver_pcl711_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From ccc66e0a06a08a2858bf81a334ee71e295ff8b7a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 16:31:58 -0700 Subject: staging: comedi: refactor pcl724 driver to remove the forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c index 20715d1..7d0a306 100644 --- a/drivers/staging/comedi/drivers/pcl724.c +++ b/drivers/staging/comedi/drivers/pcl724.c @@ -56,10 +56,6 @@ See the source for configuration details. /* #define PCL724_IRQ 1 no IRQ support now */ -static int pcl724_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcl724_detach(struct comedi_device *dev); - struct pcl724_board { const char *name; /* board name */ @@ -71,40 +67,8 @@ struct pcl724_board { char is_pet48; }; -static const struct pcl724_board boardtypes[] = { - {"pcl724", 24, 1, 0x00fc, PCL724_SIZE, 0, 0,}, - {"pcl722", 144, 6, 0x00fc, PCL722_SIZE, 1, 0,}, - {"pcl731", 48, 2, 0x9cfc, PCL731_SIZE, 0, 0,}, - {"acl7122", 144, 6, 0x9ee8, PCL722_SIZE, 1, 0,}, - {"acl7124", 24, 1, 0x00fc, PCL724_SIZE, 0, 0,}, - {"pet48dio", 48, 2, 0x9eb8, PET48_SIZE, 0, 1,}, -}; - #define this_board ((const struct pcl724_board *)dev->board_ptr) -static struct comedi_driver driver_pcl724 = { - .driver_name = "pcl724", - .module = THIS_MODULE, - .attach = pcl724_attach, - .detach = pcl724_detach, - .board_name = &boardtypes[0].name, - .num_names = ARRAY_SIZE(boardtypes), - .offset = sizeof(struct pcl724_board), -}; - -static int __init driver_pcl724_init_module(void) -{ - return comedi_driver_register(&driver_pcl724); -} - -static void __exit driver_pcl724_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl724); -} - -module_init(driver_pcl724_init_module); -module_exit(driver_pcl724_cleanup_module); - static int subdev_8255_cb(int dir, int port, int data, unsigned long arg) { unsigned long iobase = arg; @@ -232,6 +196,37 @@ static int pcl724_detach(struct comedi_device *dev) return 0; } +static const struct pcl724_board boardtypes[] = { + { "pcl724", 24, 1, 0x00fc, PCL724_SIZE, 0, 0, }, + { "pcl722", 144, 6, 0x00fc, PCL722_SIZE, 1, 0, }, + { "pcl731", 48, 2, 0x9cfc, PCL731_SIZE, 0, 0, }, + { "acl7122", 144, 6, 0x9ee8, PCL722_SIZE, 1, 0, }, + { "acl7124", 24, 1, 0x00fc, PCL724_SIZE, 0, 0, }, + { "pet48dio", 48, 2, 0x9eb8, PET48_SIZE, 0, 1, }, +}; + +static struct comedi_driver driver_pcl724 = { + .driver_name = "pcl724", + .module = THIS_MODULE, + .attach = pcl724_attach, + .detach = pcl724_detach, + .board_name = &boardtypes[0].name, + .num_names = ARRAY_SIZE(boardtypes), + .offset = sizeof(struct pcl724_board), +}; + +static int __init driver_pcl724_init_module(void) +{ + return comedi_driver_register(&driver_pcl724); +} +module_init(driver_pcl724_init_module); + +static void __exit driver_pcl724_cleanup_module(void) +{ + comedi_driver_unregister(&driver_pcl724); +} +module_exit(driver_pcl724_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From f21a38c453411660e85f9e68af4c20322021f941 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 16:27:20 -0700 Subject: staging: comedi: refactor pcl725 driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcl725.c b/drivers/staging/comedi/drivers/pcl725.c index 24b223c..4b761a6 100644 --- a/drivers/staging/comedi/drivers/pcl725.c +++ b/drivers/staging/comedi/drivers/pcl725.c @@ -20,29 +20,6 @@ Devices: [Advantech] PCL-725 (pcl725) #define PCL725_DO 0 #define PCL725_DI 1 -static int pcl725_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcl725_detach(struct comedi_device *dev); -static struct comedi_driver driver_pcl725 = { - .driver_name = "pcl725", - .module = THIS_MODULE, - .attach = pcl725_attach, - .detach = pcl725_detach, -}; - -static int __init driver_pcl725_init_module(void) -{ - return comedi_driver_register(&driver_pcl725); -} - -static void __exit driver_pcl725_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl725); -} - -module_init(driver_pcl725_init_module); -module_exit(driver_pcl725_cleanup_module); - static int pcl725_do_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { @@ -122,6 +99,25 @@ static int pcl725_detach(struct comedi_device *dev) return 0; } +static struct comedi_driver driver_pcl725 = { + .driver_name = "pcl725", + .module = THIS_MODULE, + .attach = pcl725_attach, + .detach = pcl725_detach, +}; + +static int __init driver_pcl725_init_module(void) +{ + return comedi_driver_register(&driver_pcl725); +} +module_init(driver_pcl725_init_module); + +static void __exit driver_pcl725_cleanup_module(void) +{ + comedi_driver_unregister(&driver_pcl725); +} +module_exit(driver_pcl725_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 2bc62b677a21307d476e5fdb8174df00bf3921a1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 16:25:06 -0700 Subject: staging: comedi: refactor pcl726 driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c index a880ceb..c63e91c 100644 --- a/drivers/staging/comedi/drivers/pcl726.c +++ b/drivers/staging/comedi/drivers/pcl726.c @@ -111,10 +111,6 @@ static const struct comedi_lrange *const rangelist_728[] = { &range_4_20mA, &range_0_20mA }; -static int pcl726_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcl726_detach(struct comedi_device *dev); - struct pcl726_board { const char *name; /* driver name */ @@ -151,29 +147,6 @@ static const struct pcl726_board boardtypes[] = { #define this_board ((const struct pcl726_board *)dev->board_ptr) -static struct comedi_driver driver_pcl726 = { - .driver_name = "pcl726", - .module = THIS_MODULE, - .attach = pcl726_attach, - .detach = pcl726_detach, - .board_name = &boardtypes[0].name, - .num_names = ARRAY_SIZE(boardtypes), - .offset = sizeof(struct pcl726_board), -}; - -static int __init driver_pcl726_init_module(void) -{ - return comedi_driver_register(&driver_pcl726); -} - -static void __exit driver_pcl726_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl726); -} - -module_init(driver_pcl726_init_module); -module_exit(driver_pcl726_cleanup_module); - struct pcl726_private { int bipolar[12]; @@ -392,6 +365,28 @@ static int pcl726_detach(struct comedi_device *dev) return 0; } +static struct comedi_driver driver_pcl726 = { + .driver_name = "pcl726", + .module = THIS_MODULE, + .attach = pcl726_attach, + .detach = pcl726_detach, + .board_name = &boardtypes[0].name, + .num_names = ARRAY_SIZE(boardtypes), + .offset = sizeof(struct pcl726_board), +}; + +static int __init driver_pcl726_init_module(void) +{ + return comedi_driver_register(&driver_pcl726); +} +module_init(driver_pcl726_init_module); + +static void __exit driver_pcl726_cleanup_module(void) +{ + comedi_driver_unregister(&driver_pcl726); +} +module_exit(driver_pcl726_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 4c6dacbd383c0cdd84826cb0663b6bd81eaf21fb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 16:21:21 -0700 Subject: staging: comedi: refactor pcl730 driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c index 78c8e59..f6fa8ae 100644 --- a/drivers/staging/comedi/drivers/pcl730.c +++ b/drivers/staging/comedi/drivers/pcl730.c @@ -26,47 +26,14 @@ The ACL-7130 card have an 8254 timer/counter not supported by this driver. #define PCL730_DIO_LO 2 /* TTL Digital I/O low byte (D0-D7) */ #define PCL730_DIO_HI 3 /* TTL Digital I/O high byte (D8-D15) */ -static int pcl730_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcl730_detach(struct comedi_device *dev); - struct pcl730_board { const char *name; /* board name */ unsigned int io_range; /* len of I/O space */ }; -static const struct pcl730_board boardtypes[] = { - {"pcl730", PCL730_SIZE,}, - {"iso730", PCL730_SIZE,}, - {"acl7130", ACL7130_SIZE,}, -}; - #define this_board ((const struct pcl730_board *)dev->board_ptr) -static struct comedi_driver driver_pcl730 = { - .driver_name = "pcl730", - .module = THIS_MODULE, - .attach = pcl730_attach, - .detach = pcl730_detach, - .board_name = &boardtypes[0].name, - .num_names = ARRAY_SIZE(boardtypes), - .offset = sizeof(struct pcl730_board), -}; - -static int __init driver_pcl730_init_module(void) -{ - return comedi_driver_register(&driver_pcl730); -} - -static void __exit driver_pcl730_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl730); -} - -module_init(driver_pcl730_init_module); -module_exit(driver_pcl730_cleanup_module); - static int pcl730_do_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { @@ -177,6 +144,34 @@ static int pcl730_detach(struct comedi_device *dev) return 0; } +static const struct pcl730_board boardtypes[] = { + { "pcl730", PCL730_SIZE, }, + { "iso730", PCL730_SIZE, }, + { "acl7130", ACL7130_SIZE, }, +}; + +static struct comedi_driver driver_pcl730 = { + .driver_name = "pcl730", + .module = THIS_MODULE, + .attach = pcl730_attach, + .detach = pcl730_detach, + .board_name = &boardtypes[0].name, + .num_names = ARRAY_SIZE(boardtypes), + .offset = sizeof(struct pcl730_board), +}; + +static int __init driver_pcl730_init_module(void) +{ + return comedi_driver_register(&driver_pcl730); +} +module_init(driver_pcl730_init_module); + +static void __exit driver_pcl730_cleanup_module(void) +{ + comedi_driver_unregister(&driver_pcl730); +} +module_exit(driver_pcl730_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 92bc80dfbbc79dad7a7bd3dd3aa0348ad6a667f9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 16:17:22 -0700 Subject: staging: comedi: refactor pcl812 driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 555d0df..85463e2 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -316,10 +316,6 @@ static const struct comedi_lrange range_a821pgh_ai = { 4, { } }; -static int pcl812_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcl812_detach(struct comedi_device *dev); - struct pcl812_board { const char *name; /* board name */ @@ -340,88 +336,8 @@ struct pcl812_board { unsigned char haveMPC508; /* 1=board use MPC508A multiplexor */ }; -static const struct pcl812_board boardtypes[] = { - {"pcl812", boardPCL812, 16, 0, 2, 16, 16, 0x0fff, - 33000, 500, &range_bipolar10, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, - {"pcl812pg", boardPCL812PG, 16, 0, 2, 16, 16, 0x0fff, - 33000, 500, &range_pcl812pg_ai, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, - {"acl8112pg", boardPCL812PG, 16, 0, 2, 16, 16, 0x0fff, - 10000, 500, &range_pcl812pg_ai, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, - {"acl8112dg", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, - 10000, 500, &range_acl8112dg_ai, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 1}, - {"acl8112hg", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, - 10000, 500, &range_acl8112hg_ai, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 1}, - {"a821pgl", boardA821, 16, 8, 1, 16, 16, 0x0fff, - 10000, 500, &range_pcl813b_ai, &range_unipolar5, - 0x000c, 0x00, PCLx1x_IORANGE, 0}, - {"a821pglnda", boardA821, 16, 8, 0, 0, 0, 0x0fff, - 10000, 500, &range_pcl813b_ai, NULL, - 0x000c, 0x00, PCLx1x_IORANGE, 0}, - {"a821pgh", boardA821, 16, 8, 1, 16, 16, 0x0fff, - 10000, 500, &range_a821pgh_ai, &range_unipolar5, - 0x000c, 0x00, PCLx1x_IORANGE, 0}, - {"a822pgl", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, - 10000, 500, &range_acl8112dg_ai, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, - {"a822pgh", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, - 10000, 500, &range_acl8112hg_ai, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, - {"a823pgl", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, - 8000, 500, &range_acl8112dg_ai, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, - {"a823pgh", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, - 8000, 500, &range_acl8112hg_ai, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, - {"pcl813", boardPCL813, 32, 0, 0, 0, 0, 0x0fff, - 0, 0, &range_pcl813b_ai, NULL, - 0x0000, 0x00, PCLx1x_IORANGE, 0}, - {"pcl813b", boardPCL813B, 32, 0, 0, 0, 0, 0x0fff, - 0, 0, &range_pcl813b_ai, NULL, - 0x0000, 0x00, PCLx1x_IORANGE, 0}, - {"acl8113", boardACL8113, 32, 0, 0, 0, 0, 0x0fff, - 0, 0, &range_acl8113_1_ai, NULL, - 0x0000, 0x00, PCLx1x_IORANGE, 0}, - {"iso813", boardISO813, 32, 0, 0, 0, 0, 0x0fff, - 0, 0, &range_iso813_1_ai, NULL, - 0x0000, 0x00, PCLx1x_IORANGE, 0}, - {"acl8216", boardACL8216, 16, 8, 2, 16, 16, 0xffff, - 10000, 500, &range_pcl813b2_ai, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 1}, - {"a826pg", boardACL8216, 16, 8, 2, 16, 16, 0xffff, - 10000, 500, &range_pcl813b2_ai, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, -}; - #define this_board ((const struct pcl812_board *)dev->board_ptr) -static struct comedi_driver driver_pcl812 = { - .driver_name = "pcl812", - .module = THIS_MODULE, - .attach = pcl812_attach, - .detach = pcl812_detach, - .board_name = &boardtypes[0].name, - .num_names = ARRAY_SIZE(boardtypes), - .offset = sizeof(struct pcl812_board), -}; - -static int __init driver_pcl812_init_module(void) -{ - return comedi_driver_register(&driver_pcl812); -} - -static void __exit driver_pcl812_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl812); -} - -module_init(driver_pcl812_init_module); -module_exit(driver_pcl812_cleanup_module); - struct pcl812_private { unsigned char valid; /* =1 device is OK */ @@ -1355,9 +1271,6 @@ static void pcl812_reset(struct comedi_device *dev) #endif } -/* -============================================================================== -*/ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) { int ret, subdev; @@ -1701,9 +1614,6 @@ no_dma: return 0; } -/* -============================================================================== - */ static int pcl812_detach(struct comedi_device *dev) { @@ -1714,6 +1624,85 @@ static int pcl812_detach(struct comedi_device *dev) return 0; } +static const struct pcl812_board boardtypes[] = { + {"pcl812", boardPCL812, 16, 0, 2, 16, 16, 0x0fff, + 33000, 500, &range_bipolar10, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, + {"pcl812pg", boardPCL812PG, 16, 0, 2, 16, 16, 0x0fff, + 33000, 500, &range_pcl812pg_ai, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, + {"acl8112pg", boardPCL812PG, 16, 0, 2, 16, 16, 0x0fff, + 10000, 500, &range_pcl812pg_ai, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, + {"acl8112dg", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, + 10000, 500, &range_acl8112dg_ai, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 1}, + {"acl8112hg", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, + 10000, 500, &range_acl8112hg_ai, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 1}, + {"a821pgl", boardA821, 16, 8, 1, 16, 16, 0x0fff, + 10000, 500, &range_pcl813b_ai, &range_unipolar5, + 0x000c, 0x00, PCLx1x_IORANGE, 0}, + {"a821pglnda", boardA821, 16, 8, 0, 0, 0, 0x0fff, + 10000, 500, &range_pcl813b_ai, NULL, + 0x000c, 0x00, PCLx1x_IORANGE, 0}, + {"a821pgh", boardA821, 16, 8, 1, 16, 16, 0x0fff, + 10000, 500, &range_a821pgh_ai, &range_unipolar5, + 0x000c, 0x00, PCLx1x_IORANGE, 0}, + {"a822pgl", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, + 10000, 500, &range_acl8112dg_ai, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, + {"a822pgh", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, + 10000, 500, &range_acl8112hg_ai, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, + {"a823pgl", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, + 8000, 500, &range_acl8112dg_ai, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, + {"a823pgh", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, + 8000, 500, &range_acl8112hg_ai, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, + {"pcl813", boardPCL813, 32, 0, 0, 0, 0, 0x0fff, + 0, 0, &range_pcl813b_ai, NULL, + 0x0000, 0x00, PCLx1x_IORANGE, 0}, + {"pcl813b", boardPCL813B, 32, 0, 0, 0, 0, 0x0fff, + 0, 0, &range_pcl813b_ai, NULL, + 0x0000, 0x00, PCLx1x_IORANGE, 0}, + {"acl8113", boardACL8113, 32, 0, 0, 0, 0, 0x0fff, + 0, 0, &range_acl8113_1_ai, NULL, + 0x0000, 0x00, PCLx1x_IORANGE, 0}, + {"iso813", boardISO813, 32, 0, 0, 0, 0, 0x0fff, + 0, 0, &range_iso813_1_ai, NULL, + 0x0000, 0x00, PCLx1x_IORANGE, 0}, + {"acl8216", boardACL8216, 16, 8, 2, 16, 16, 0xffff, + 10000, 500, &range_pcl813b2_ai, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 1}, + {"a826pg", boardACL8216, 16, 8, 2, 16, 16, 0xffff, + 10000, 500, &range_pcl813b2_ai, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, +}; + +static struct comedi_driver driver_pcl812 = { + .driver_name = "pcl812", + .module = THIS_MODULE, + .attach = pcl812_attach, + .detach = pcl812_detach, + .board_name = &boardtypes[0].name, + .num_names = ARRAY_SIZE(boardtypes), + .offset = sizeof(struct pcl812_board), +}; + +static int __init driver_pcl812_init_module(void) +{ + return comedi_driver_register(&driver_pcl812); +} +module_init(driver_pcl812_init_module); + +static void __exit driver_pcl812_cleanup_module(void) +{ + comedi_driver_unregister(&driver_pcl812); +} +module_exit(driver_pcl812_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 34023cd12b5cca3aafb08972defa9f4671c168ce Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 16:13:37 -0700 Subject: staging: comedi: refactor pcl816 driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index bf7b262..bccbb23 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -125,62 +125,14 @@ struct pcl816_board { int i8254_osc_base; /* 1/frequency of on board oscilator in ns */ }; -static const struct pcl816_board boardtypes[] = { - {"pcl816", 8, 16, 10000, 1, 16, 16, &range_pcl816, - &range_pcl816, PCLx1x_RANGE, - 0x00fc, /* IRQ mask */ - 0x0a, /* DMA mask */ - 0xffff, /* 16-bit card */ - 0xffff, /* D/A maxdata */ - 1024, - 1, /* ao chan list */ - 100}, - {"pcl814b", 8, 16, 10000, 1, 16, 16, &range_pcl816, - &range_pcl816, PCLx1x_RANGE, - 0x00fc, - 0x0a, - 0x3fff, /* 14 bit card */ - 0x3fff, - 1024, - 1, - 100}, -}; - #define devpriv ((struct pcl816_private *)dev->private) #define this_board ((const struct pcl816_board *)dev->board_ptr) -static int pcl816_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcl816_detach(struct comedi_device *dev); - #ifdef unused static int RTC_lock; /* RTC lock */ static int RTC_timer_lock; /* RTC int lock */ #endif -static struct comedi_driver driver_pcl816 = { - .driver_name = "pcl816", - .module = THIS_MODULE, - .attach = pcl816_attach, - .detach = pcl816_detach, - .board_name = &boardtypes[0].name, - .num_names = ARRAY_SIZE(boardtypes), - .offset = sizeof(struct pcl816_board), -}; - -static int __init driver_pcl816_init_module(void) -{ - return comedi_driver_register(&driver_pcl816); -} - -static void __exit driver_pcl816_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl816); -} - -module_init(driver_pcl816_init_module); -module_exit(driver_pcl816_cleanup_module); - struct pcl816_private { unsigned int dma; /* used DMA, 0=don't use DMA */ @@ -1108,12 +1060,6 @@ static void free_resources(struct comedi_device *dev) /* printk("free_resource() end\n"); */ } -/* -============================================================================== - - Initialization - -*/ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) { int ret; @@ -1339,10 +1285,6 @@ case COMEDI_SUBD_DO: return 0; } -/* -============================================================================== - Removes device - */ static int pcl816_detach(struct comedi_device *dev) { DEBUG(printk(KERN_INFO "comedi%d: pcl816: remove\n", dev->minor);) @@ -1354,6 +1296,49 @@ static int pcl816_detach(struct comedi_device *dev) return 0; } +static const struct pcl816_board boardtypes[] = { + {"pcl816", 8, 16, 10000, 1, 16, 16, &range_pcl816, + &range_pcl816, PCLx1x_RANGE, + 0x00fc, /* IRQ mask */ + 0x0a, /* DMA mask */ + 0xffff, /* 16-bit card */ + 0xffff, /* D/A maxdata */ + 1024, + 1, /* ao chan list */ + 100}, + {"pcl814b", 8, 16, 10000, 1, 16, 16, &range_pcl816, + &range_pcl816, PCLx1x_RANGE, + 0x00fc, + 0x0a, + 0x3fff, /* 14 bit card */ + 0x3fff, + 1024, + 1, + 100}, +}; + +static struct comedi_driver driver_pcl816 = { + .driver_name = "pcl816", + .module = THIS_MODULE, + .attach = pcl816_attach, + .detach = pcl816_detach, + .board_name = &boardtypes[0].name, + .num_names = ARRAY_SIZE(boardtypes), + .offset = sizeof(struct pcl816_board), +}; + +static int __init driver_pcl816_init_module(void) +{ + return comedi_driver_register(&driver_pcl816); +} +module_init(driver_pcl816_init_module); + +static void __exit driver_pcl816_cleanup_module(void) +{ + comedi_driver_unregister(&driver_pcl816); +} +module_exit(driver_pcl816_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From f6aafa10def97020437bab02444da4cdeb92d5d9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 16:09:11 -0700 Subject: staging: comedi: refactor pcl818 driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index 0272491..8dbefc5 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -247,10 +247,6 @@ static const struct comedi_lrange range718_bipolar0_5 = static const struct comedi_lrange range718_unipolar2 = { 1, {UNI_RANGE(2),} }; static const struct comedi_lrange range718_unipolar1 = { 1, {BIP_RANGE(1),} }; -static int pcl818_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcl818_detach(struct comedi_device *dev); - #ifdef unused static int RTC_lock; /* RTC lock */ static int RTC_timer_lock; /* RTC int lock */ @@ -277,54 +273,6 @@ struct pcl818_board { int is_818; }; -static const struct pcl818_board boardtypes[] = { - {"pcl818l", 4, 16, 8, 25000, 1, 16, 16, &range_pcl818l_l_ai, - &range_unipolar5, PCLx1x_RANGE, 0x00fc, - 0x0a, 0xfff, 0xfff, 0, 1}, - {"pcl818h", 9, 16, 8, 10000, 1, 16, 16, &range_pcl818h_ai, - &range_unipolar5, PCLx1x_RANGE, 0x00fc, - 0x0a, 0xfff, 0xfff, 0, 1}, - {"pcl818hd", 9, 16, 8, 10000, 1, 16, 16, &range_pcl818h_ai, - &range_unipolar5, PCLx1x_RANGE, 0x00fc, - 0x0a, 0xfff, 0xfff, 1, 1}, - {"pcl818hg", 12, 16, 8, 10000, 1, 16, 16, &range_pcl818hg_ai, - &range_unipolar5, PCLx1x_RANGE, 0x00fc, - 0x0a, 0xfff, 0xfff, 1, 1}, - {"pcl818", 9, 16, 8, 10000, 2, 16, 16, &range_pcl818h_ai, - &range_unipolar5, PCLx1x_RANGE, 0x00fc, - 0x0a, 0xfff, 0xfff, 0, 1}, - {"pcl718", 1, 16, 8, 16000, 2, 16, 16, &range_unipolar5, - &range_unipolar5, PCLx1x_RANGE, 0x00fc, - 0x0a, 0xfff, 0xfff, 0, 0}, - /* pcm3718 */ - {"pcm3718", 9, 16, 8, 10000, 0, 16, 16, &range_pcl818h_ai, - &range_unipolar5, PCLx1x_RANGE, 0x00fc, - 0x0a, 0xfff, 0xfff, 0, 1 /* XXX ? */ }, -}; - -static struct comedi_driver driver_pcl818 = { - .driver_name = "pcl818", - .module = THIS_MODULE, - .attach = pcl818_attach, - .detach = pcl818_detach, - .board_name = &boardtypes[0].name, - .num_names = ARRAY_SIZE(boardtypes), - .offset = sizeof(struct pcl818_board), -}; - -static int __init driver_pcl818_init_module(void) -{ - return comedi_driver_register(&driver_pcl818); -} - -static void __exit driver_pcl818_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl818); -} - -module_init(driver_pcl818_init_module); -module_exit(driver_pcl818_cleanup_module); - struct pcl818_private { unsigned int dma; /* used DMA, 0=don't use DMA */ @@ -1722,12 +1670,6 @@ static void free_resources(struct comedi_device *dev) /* printk("free_resource() end\n"); */ } -/* -============================================================================== - - Initialization - -*/ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) { int ret; @@ -2018,10 +1960,6 @@ no_dma: return 0; } -/* -============================================================================== - Removes device - */ static int pcl818_detach(struct comedi_device *dev) { /* printk("comedi%d: pcl818: remove\n", dev->minor); */ @@ -2029,6 +1967,53 @@ static int pcl818_detach(struct comedi_device *dev) return 0; } +static const struct pcl818_board boardtypes[] = { + {"pcl818l", 4, 16, 8, 25000, 1, 16, 16, &range_pcl818l_l_ai, + &range_unipolar5, PCLx1x_RANGE, 0x00fc, + 0x0a, 0xfff, 0xfff, 0, 1}, + {"pcl818h", 9, 16, 8, 10000, 1, 16, 16, &range_pcl818h_ai, + &range_unipolar5, PCLx1x_RANGE, 0x00fc, + 0x0a, 0xfff, 0xfff, 0, 1}, + {"pcl818hd", 9, 16, 8, 10000, 1, 16, 16, &range_pcl818h_ai, + &range_unipolar5, PCLx1x_RANGE, 0x00fc, + 0x0a, 0xfff, 0xfff, 1, 1}, + {"pcl818hg", 12, 16, 8, 10000, 1, 16, 16, &range_pcl818hg_ai, + &range_unipolar5, PCLx1x_RANGE, 0x00fc, + 0x0a, 0xfff, 0xfff, 1, 1}, + {"pcl818", 9, 16, 8, 10000, 2, 16, 16, &range_pcl818h_ai, + &range_unipolar5, PCLx1x_RANGE, 0x00fc, + 0x0a, 0xfff, 0xfff, 0, 1}, + {"pcl718", 1, 16, 8, 16000, 2, 16, 16, &range_unipolar5, + &range_unipolar5, PCLx1x_RANGE, 0x00fc, + 0x0a, 0xfff, 0xfff, 0, 0}, + /* pcm3718 */ + {"pcm3718", 9, 16, 8, 10000, 0, 16, 16, &range_pcl818h_ai, + &range_unipolar5, PCLx1x_RANGE, 0x00fc, + 0x0a, 0xfff, 0xfff, 0, 1 /* XXX ? */ }, +}; + +static struct comedi_driver driver_pcl818 = { + .driver_name = "pcl818", + .module = THIS_MODULE, + .attach = pcl818_attach, + .detach = pcl818_detach, + .board_name = &boardtypes[0].name, + .num_names = ARRAY_SIZE(boardtypes), + .offset = sizeof(struct pcl818_board), +}; + +static int __init driver_pcl818_init_module(void) +{ + return comedi_driver_register(&driver_pcl818); +} +module_init(driver_pcl818_init_module); + +static void __exit driver_pcl818_cleanup_module(void) +{ + comedi_driver_unregister(&driver_pcl818); +} +module_exit(driver_pcl818_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 5f01bd51f1f079399f9a3c1951e1be86502f7bbc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 15:54:00 -0700 Subject: staging: comedi: refactor pcm3724 driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c index 4601703..88a354b 100644 --- a/drivers/staging/comedi/drivers/pcm3724.c +++ b/drivers/staging/comedi/drivers/pcm3724.c @@ -62,10 +62,6 @@ Copy/pasted/hacked from pcm724.c #define CR_A_MODE(a) ((a)<<5) #define CR_CW 0x80 -static int pcm3724_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcm3724_detach(struct comedi_device *dev); - struct pcm3724_board { const char *name; /* driver name */ int dio; /* num of DIO */ @@ -80,35 +76,8 @@ struct priv_pcm3724 { int dio_2; }; -static const struct pcm3724_board boardtypes[] = { - {"pcm3724", 48, 2, 0x00fc, PCM3724_SIZE,}, -}; - #define this_board ((const struct pcm3724_board *)dev->board_ptr) -static struct comedi_driver driver_pcm3724 = { - .driver_name = "pcm3724", - .module = THIS_MODULE, - .attach = pcm3724_attach, - .detach = pcm3724_detach, - .board_name = &boardtypes[0].name, - .num_names = ARRAY_SIZE(boardtypes), - .offset = sizeof(struct pcm3724_board), -}; - -static int __init driver_pcm3724_init_module(void) -{ - return comedi_driver_register(&driver_pcm3724); -} - -static void __exit driver_pcm3724_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcm3724); -} - -module_init(driver_pcm3724_init_module); -module_exit(driver_pcm3724_cleanup_module); - /* (setq c-basic-offset 8) */ static int subdev_8255_cb(int dir, int port, int data, unsigned long arg) @@ -318,6 +287,32 @@ static int pcm3724_detach(struct comedi_device *dev) return 0; } +static const struct pcm3724_board boardtypes[] = { + { "pcm3724", 48, 2, 0x00fc, PCM3724_SIZE, }, +}; + +static struct comedi_driver driver_pcm3724 = { + .driver_name = "pcm3724", + .module = THIS_MODULE, + .attach = pcm3724_attach, + .detach = pcm3724_detach, + .board_name = &boardtypes[0].name, + .num_names = ARRAY_SIZE(boardtypes), + .offset = sizeof(struct pcm3724_board), +}; + +static int __init driver_pcm3724_init_module(void) +{ + return comedi_driver_register(&driver_pcm3724); +} +module_init(driver_pcm3724_init_module); + +static void __exit driver_pcm3724_cleanup_module(void) +{ + comedi_driver_unregister(&driver_pcm3724); +} +module_exit(driver_pcm3724_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From f3ebaf4b51811feaa94de99e0517fc3a797cc3fb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 15:50:41 -0700 Subject: staging: comedi: refactor pcm3730 driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcm3730.c b/drivers/staging/comedi/drivers/pcm3730.c index bada6b2..3428993 100644 --- a/drivers/staging/comedi/drivers/pcm3730.c +++ b/drivers/staging/comedi/drivers/pcm3730.c @@ -28,29 +28,6 @@ Configuration options: #define PCM3730_DIB 2 #define PCM3730_DIC 3 -static int pcm3730_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcm3730_detach(struct comedi_device *dev); -static struct comedi_driver driver_pcm3730 = { - .driver_name = "pcm3730", - .module = THIS_MODULE, - .attach = pcm3730_attach, - .detach = pcm3730_detach, -}; - -static int __init driver_pcm3730_init_module(void) -{ - return comedi_driver_register(&driver_pcm3730); -} - -static void __exit driver_pcm3730_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcm3730); -} - -module_init(driver_pcm3730_init_module); -module_exit(driver_pcm3730_cleanup_module); - static int pcm3730_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -166,6 +143,25 @@ static int pcm3730_detach(struct comedi_device *dev) return 0; } +static struct comedi_driver driver_pcm3730 = { + .driver_name = "pcm3730", + .module = THIS_MODULE, + .attach = pcm3730_attach, + .detach = pcm3730_detach, +}; + +static int __init driver_pcm3730_init_module(void) +{ + return comedi_driver_register(&driver_pcm3730); +} +module_init(driver_pcm3730_init_module); + +static void __exit driver_pcm3730_cleanup_module(void) +{ + comedi_driver_unregister(&driver_pcm3730); +} +module_exit(driver_pcm3730_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 3496cb9fac149ce5a17a048c020224a964224558 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 15:48:07 -0700 Subject: staging: comedi: refactor pcmad driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c index 23b3d77..fe8ef66 100644 --- a/drivers/staging/comedi/drivers/pcmad.c +++ b/drivers/staging/comedi/drivers/pcmad.c @@ -57,19 +57,8 @@ struct pcmad_board_struct { const char *name; int n_ai_bits; }; -static const struct pcmad_board_struct pcmad_boards[] = { - { - .name = "pcmad12", - .n_ai_bits = 12, - }, - { - .name = "pcmad16", - .n_ai_bits = 16, - }, -}; #define this_board ((const struct pcmad_board_struct *)(dev->board_ptr)) -#define n_pcmad_boards ARRAY_SIZE(pcmad_boards) struct pcmad_priv_struct { int differential; @@ -77,31 +66,6 @@ struct pcmad_priv_struct { }; #define devpriv ((struct pcmad_priv_struct *)dev->private) -static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int pcmad_detach(struct comedi_device *dev); -static struct comedi_driver driver_pcmad = { - .driver_name = "pcmad", - .module = THIS_MODULE, - .attach = pcmad_attach, - .detach = pcmad_detach, - .board_name = &pcmad_boards[0].name, - .num_names = n_pcmad_boards, - .offset = sizeof(pcmad_boards[0]), -}; - -static int __init driver_pcmad_init_module(void) -{ - return comedi_driver_register(&driver_pcmad); -} - -static void __exit driver_pcmad_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcmad); -} - -module_init(driver_pcmad_init_module); -module_exit(driver_pcmad_cleanup_module); - #define TIMEOUT 100 static int pcmad_ai_insn_read(struct comedi_device *dev, @@ -188,6 +152,37 @@ static int pcmad_detach(struct comedi_device *dev) return 0; } +static const struct pcmad_board_struct pcmad_boards[] = { + { + .name = "pcmad12", + .n_ai_bits = 12, + }, { + .name = "pcmad16", + .n_ai_bits = 16, + }, +}; +static struct comedi_driver driver_pcmad = { + .driver_name = "pcmad", + .module = THIS_MODULE, + .attach = pcmad_attach, + .detach = pcmad_detach, + .board_name = &pcmad_boards[0].name, + .num_names = ARRAY_SIZE(pcmad_boards), + .offset = sizeof(pcmad_boards[0]), +}; + +static int __init driver_pcmad_init_module(void) +{ + return comedi_driver_register(&driver_pcmad); +} +module_init(driver_pcmad_init_module); + +static void __exit driver_pcmad_cleanup_module(void) +{ + comedi_driver_unregister(&driver_pcmad); +} +module_exit(driver_pcmad_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 924f4685f47f160ddb0927c0ccb012ccf615a644 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 15:44:02 -0700 Subject: staging: comedi: refactor pcmda12 driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c index 0e9ffa2..4846d98 100644 --- a/drivers/staging/comedi/drivers/pcmda12.c +++ b/drivers/staging/comedi/drivers/pcmda12.c @@ -80,12 +80,6 @@ static const struct comedi_lrange pcmda12_ranges = { } }; -static const struct pcmda12_board pcmda12_boards[] = { - { - .name = "pcmda12", - }, -}; - /* * Useful for shorthand access to the particular board structure */ @@ -99,57 +93,77 @@ struct pcmda12_private { #define devpriv ((struct pcmda12_private *)(dev->private)) -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int pcmda12_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcmda12_detach(struct comedi_device *dev); +static void zero_chans(struct comedi_device *dev) +{ /* sets up an + ASIC chip to defaults */ + int i; + for (i = 0; i < CHANS; ++i) { +/* /\* do this as one instruction?? *\/ */ +/* outw(0, LSB_PORT(chan)); */ + outb(0, LSB_PORT(i)); + outb(0, MSB_PORT(i)); + } + inb(LSB_PORT(0)); /* update chans. */ +} -static void zero_chans(struct comedi_device *dev); +static int 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); -static struct comedi_driver driver = { - .driver_name = "pcmda12", - .module = THIS_MODULE, - .attach = pcmda12_attach, - .detach = pcmda12_detach, -/* It is not necessary to implement the following members if you are - * writing a driver for a ISA PnP or PCI card */ - /* Most drivers will support multiple types of boards by - * having an array of board structures. These were defined - * in pcmda12_boards[] above. Note that the element 'name' - * was first in the structure -- Comedi uses this fact to - * extract the name of the board without knowing any details - * about the structure except for its length. - * When a device is attached (by comedi_config), the name - * of the device is given to Comedi, and Comedi tries to - * match it by going through the list of board names. If - * there is a match, the address of the pointer is put - * into dev->board_ptr and driver->attach() is called. - * - * Note that these are not necessary if you can determine - * the type of board in software. ISA PnP, PCI, and PCMCIA - * devices are such boards. - */ - .board_name = &pcmda12_boards[0].name, - .offset = sizeof(struct pcmda12_board), - .num_names = ARRAY_SIZE(pcmda12_boards), -}; + /* 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) { -static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); +/* /\* do this as one instruction?? *\/ */ +/* outw(data[i], LSB_PORT(chan)); */ + + /* Need to do this as two instructions due to 8-bit bus?? */ + /* first, load the low byte */ + outb(LSB(data[i]), LSB_PORT(chan)); + /* next, write the high byte */ + outb(MSB(data[i]), MSB_PORT(chan)); + + /* save shadow register */ + devpriv->ao_readback[chan] = data[i]; + + if (!devpriv->simultaneous_xfer_mode) + inb(LSB_PORT(chan)); + } + + /* return the number of samples 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->ao_readback. + However, since this driver supports simultaneous xfer then sometimes + this function actually accomplishes work. + + Simultaneaous xfer mode is accomplished by loading ALL the values + you want for AO in all the channels, then READing off one of the AO + registers to initiate the instantaneous simultaneous update of all + DAC outputs, which makes all AO channels update simultaneously. + This is useful for some control applications, I would imagine. +*/ static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); + struct comedi_insn *insn, unsigned int *data) +{ + int i; + int chan = CR_CHAN(insn->chanspec); + + for (i = 0; i < insn->n; i++) { + if (devpriv->simultaneous_xfer_mode) + inb(LSB_PORT(chan)); + /* read back shadow register */ + data[i] = devpriv->ao_readback[chan]; + } + + return i; +} -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ static int pcmda12_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -213,14 +227,6 @@ static int pcmda12_attach(struct comedi_device *dev, return 1; } -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ static int pcmda12_detach(struct comedi_device *dev) { printk(KERN_INFO @@ -230,92 +236,32 @@ static int pcmda12_detach(struct comedi_device *dev) return 0; } -static void zero_chans(struct comedi_device *dev) -{ /* sets up an - ASIC chip to defaults */ - int i; - for (i = 0; i < CHANS; ++i) { -/* /\* do this as one instruction?? *\/ */ -/* outw(0, LSB_PORT(chan)); */ - outb(0, LSB_PORT(i)); - outb(0, MSB_PORT(i)); - } - inb(LSB_PORT(0)); /* update chans. */ -} - -static int 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); - - /* 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) { - -/* /\* do this as one instruction?? *\/ */ -/* outw(data[i], LSB_PORT(chan)); */ - - /* Need to do this as two instructions due to 8-bit bus?? */ - /* first, load the low byte */ - outb(LSB(data[i]), LSB_PORT(chan)); - /* next, write the high byte */ - outb(MSB(data[i]), MSB_PORT(chan)); - - /* save shadow register */ - devpriv->ao_readback[chan] = data[i]; - - if (!devpriv->simultaneous_xfer_mode) - inb(LSB_PORT(chan)); - } - - /* return the number of samples 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->ao_readback. - However, since this driver supports simultaneous xfer then sometimes - this function actually accomplishes work. - - Simultaneaous xfer mode is accomplished by loading ALL the values - you want for AO in all the channels, then READing off one of the AO - registers to initiate the instantaneous simultaneous update of all - DAC outputs, which makes all AO channels update simultaneously. - This is useful for some control applications, I would imagine. -*/ -static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - int i; - int chan = CR_CHAN(insn->chanspec); - - for (i = 0; i < insn->n; i++) { - if (devpriv->simultaneous_xfer_mode) - inb(LSB_PORT(chan)); - /* read back shadow register */ - data[i] = devpriv->ao_readback[chan]; - } +static const struct pcmda12_board pcmda12_boards[] = { + { + .name = "pcmda12", + }, +}; - return i; -} +static struct comedi_driver driver = { + .driver_name = "pcmda12", + .module = THIS_MODULE, + .attach = pcmda12_attach, + .detach = pcmda12_detach, + .board_name = &pcmda12_boards[0].name, + .offset = sizeof(struct pcmda12_board), + .num_names = ARRAY_SIZE(pcmda12_boards), +}; -/* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. - */ static int __init driver_init_module(void) { return comedi_driver_register(&driver); } +module_init(driver_init_module); static void __exit driver_cleanup_module(void) { comedi_driver_unregister(&driver); } - -module_init(driver_init_module); module_exit(driver_cleanup_module); MODULE_AUTHOR("Comedi http://www.comedi.org"); -- cgit v0.10.2 From b2bb98e179cb06590aa86be5ff12e53ab382c926 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 15:39:37 -0700 Subject: staging: comedi: refactor pcmmio driver to remove forward declarations Refactor the switch_page and pcmmio_stop_intr functions to avoid needing the forward declarations. Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index eddac00..e05d157 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -145,13 +145,6 @@ Configuration Options: #define PAGE_ENAB 2 #define PAGE_INT_ID 3 -static int ai_rinsn(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); -static int ao_rinsn(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); -static int ao_winsn(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - /* * Board descriptions for two imaginary boards. Describing the * boards in this way is optional, and completely driver-dependent. @@ -190,23 +183,6 @@ static const struct comedi_lrange ranges_ao = { RANGE(-2.5, 2.5), RANGE(-2.5, 7.5)} }; -static const struct pcmmio_board pcmmio_boards[] = { - { - .name = "pcmmio", - .dio_num_asics = 1, - .dio_num_ports = 6, - .total_iosize = 32, - .ai_bits = 16, - .ao_bits = 16, - .n_ai_chans = 16, - .n_ao_chans = 8, - .ai_range_table = &ranges_ai, - .ao_range_table = &ranges_ao, - .ai_rinsn = ai_rinsn, - .ao_rinsn = ao_rinsn, - .ao_winsn = ao_winsn}, -}; - /* * Useful for shorthand access to the particular board structure */ @@ -293,312 +269,6 @@ struct pcmmio_private { */ #define devpriv ((struct pcmmio_private *)dev->private) #define subpriv ((struct pcmmio_subdev_private *)s->private) -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int pcmmio_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcmmio_detach(struct comedi_device *dev); - -static struct comedi_driver driver = { - .driver_name = "pcmmio", - .module = THIS_MODULE, - .attach = pcmmio_attach, - .detach = pcmmio_detach, -/* It is not necessary to implement the following members if you are - * writing a driver for a ISA PnP or PCI card */ - /* Most drivers will support multiple types of boards by - * having an array of board structures. These were defined - * in pcmmio_boards[] above. Note that the element 'name' - * was first in the structure -- Comedi uses this fact to - * extract the name of the board without knowing any details - * about the structure except for its length. - * When a device is attached (by comedi_config), the name - * of the device is given to Comedi, and Comedi tries to - * match it by going through the list of board names. If - * there is a match, the address of the pointer is put - * into dev->board_ptr and driver->attach() is called. - * - * Note that these are not necessary if you can determine - * the type of board in software. ISA PnP, PCI, and PCMCIA - * devices are such boards. - */ - .board_name = &pcmmio_boards[0].name, - .offset = sizeof(struct pcmmio_board), - .num_names = ARRAY_SIZE(pcmmio_boards), -}; - -static int pcmmio_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int pcmmio_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static irqreturn_t interrupt_pcmmio(int irq, void *d); -static void pcmmio_stop_intr(struct comedi_device *, struct comedi_subdevice *); -static int pcmmio_cancel(struct comedi_device *dev, struct comedi_subdevice *s); -static int pcmmio_cmd(struct comedi_device *dev, struct comedi_subdevice *s); -static int pcmmio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_cmd *cmd); - -/* some helper functions to deal with specifics of this device's registers */ -/* sets up/clears ASIC chips to defaults */ -static void init_asics(struct comedi_device *dev); -static void switch_page(struct comedi_device *dev, int asic, int page); -#ifdef notused -static void lock_port(struct comedi_device *dev, int asic, int port); -static void unlock_port(struct comedi_device *dev, int asic, int port); -#endif - -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ -static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - int sdev_no, chans_left, n_dio_subdevs, n_subdevs, port, asic, - thisasic_chanct = 0; - unsigned long iobase; - unsigned int irq[MAX_ASICS]; - - iobase = it->options[0]; - irq[0] = it->options[1]; - - printk(KERN_INFO "comedi%d: %s: io: %lx attaching...\n", dev->minor, - driver.driver_name, iobase); - - dev->iobase = iobase; - - if (!iobase || !request_region(iobase, - thisboard->total_iosize, - driver.driver_name)) { - printk(KERN_ERR "comedi%d: I/O port conflict\n", dev->minor); - return -EIO; - } - -/* - * Initialize dev->board_name. Note that we can use the "thisboard" - * macro now, since we just initialized it in the last line. - */ - dev->board_name = thisboard->name; - -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_private(dev, sizeof(struct pcmmio_private)) < 0) { - printk(KERN_ERR "comedi%d: cannot allocate private data structure\n", - dev->minor); - return -ENOMEM; - } - - for (asic = 0; asic < MAX_ASICS; ++asic) { - devpriv->asics[asic].num = asic; - devpriv->asics[asic].iobase = - dev->iobase + 16 + asic * ASIC_IOSIZE; - /* - * this gets actually set at the end of this function when we - * request_irqs - */ - devpriv->asics[asic].irq = 0; - spin_lock_init(&devpriv->asics[asic].spinlock); - } - - chans_left = CHANS_PER_ASIC * thisboard->dio_num_asics; - n_dio_subdevs = CALC_N_DIO_SUBDEVS(chans_left); - n_subdevs = n_dio_subdevs + 2; - devpriv->sprivs = - kcalloc(n_subdevs, sizeof(struct pcmmio_subdev_private), - GFP_KERNEL); - if (!devpriv->sprivs) { - printk(KERN_ERR "comedi%d: cannot allocate subdevice private data structures\n", - dev->minor); - return -ENOMEM; - } - /* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - * - * Allocate 1 AI + 1 AO + 2 DIO subdevs (24 lines per DIO) - */ - if (alloc_subdevices(dev, n_subdevs) < 0) { - printk(KERN_ERR "comedi%d: cannot allocate subdevice data structures\n", - dev->minor); - return -ENOMEM; - } - - /* First, AI */ - sdev_no = 0; - s = dev->subdevices + sdev_no; - s->private = devpriv->sprivs + sdev_no; - s->maxdata = (1 << thisboard->ai_bits) - 1; - s->range_table = thisboard->ai_range_table; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; - s->type = COMEDI_SUBD_AI; - s->n_chan = thisboard->n_ai_chans; - s->len_chanlist = s->n_chan; - s->insn_read = thisboard->ai_rinsn; - subpriv->iobase = dev->iobase + 0; - /* initialize the resource enable register by clearing it */ - outb(0, subpriv->iobase + 3); - outb(0, subpriv->iobase + 4 + 3); - - /* Next, AO */ - ++sdev_no; - s = dev->subdevices + sdev_no; - s->private = devpriv->sprivs + sdev_no; - s->maxdata = (1 << thisboard->ao_bits) - 1; - s->range_table = thisboard->ao_range_table; - s->subdev_flags = SDF_READABLE; - s->type = COMEDI_SUBD_AO; - s->n_chan = thisboard->n_ao_chans; - s->len_chanlist = s->n_chan; - s->insn_read = thisboard->ao_rinsn; - s->insn_write = thisboard->ao_winsn; - subpriv->iobase = dev->iobase + 8; - /* initialize the resource enable register by clearing it */ - outb(0, subpriv->iobase + 3); - outb(0, subpriv->iobase + 4 + 3); - - ++sdev_no; - port = 0; - asic = 0; - for (; sdev_no < (int)dev->n_subdevices; ++sdev_no) { - int byte_no; - - s = dev->subdevices + sdev_no; - s->private = devpriv->sprivs + sdev_no; - s->maxdata = 1; - s->range_table = &range_digital; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->type = COMEDI_SUBD_DIO; - s->insn_bits = pcmmio_dio_insn_bits; - s->insn_config = pcmmio_dio_insn_config; - s->n_chan = min(chans_left, MAX_CHANS_PER_SUBDEV); - subpriv->dio.intr.asic = -1; - subpriv->dio.intr.first_chan = -1; - subpriv->dio.intr.asic_chan = -1; - subpriv->dio.intr.num_asic_chans = -1; - subpriv->dio.intr.active = 0; - s->len_chanlist = 1; - - /* save the ioport address for each 'port' of 8 channels in the - subdevice */ - for (byte_no = 0; byte_no < PORTS_PER_SUBDEV; ++byte_no, ++port) { - if (port >= PORTS_PER_ASIC) { - port = 0; - ++asic; - thisasic_chanct = 0; - } - subpriv->iobases[byte_no] = - devpriv->asics[asic].iobase + port; - - if (thisasic_chanct < - CHANS_PER_PORT * INTR_PORTS_PER_ASIC - && subpriv->dio.intr.asic < 0) { - /* - * this is an interrupt subdevice, - * so setup the struct - */ - subpriv->dio.intr.asic = asic; - subpriv->dio.intr.active = 0; - subpriv->dio.intr.stop_count = 0; - subpriv->dio.intr.first_chan = byte_no * 8; - subpriv->dio.intr.asic_chan = thisasic_chanct; - subpriv->dio.intr.num_asic_chans = - s->n_chan - subpriv->dio.intr.first_chan; - s->cancel = pcmmio_cancel; - s->do_cmd = pcmmio_cmd; - s->do_cmdtest = pcmmio_cmdtest; - s->len_chanlist = - subpriv->dio.intr.num_asic_chans; - } - thisasic_chanct += CHANS_PER_PORT; - } - spin_lock_init(&subpriv->dio.intr.spinlock); - - chans_left -= s->n_chan; - - if (!chans_left) { - /* - * reset the asic to our first asic, - * to do intr subdevs - */ - asic = 0; - port = 0; - } - - } - - init_asics(dev); /* clear out all the registers, basically */ - - for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) { - if (irq[asic] - && request_irq(irq[asic], interrupt_pcmmio, - IRQF_SHARED, thisboard->name, dev)) { - int i; - /* unroll the allocated irqs.. */ - for (i = asic - 1; i >= 0; --i) { - free_irq(irq[i], dev); - devpriv->asics[i].irq = irq[i] = 0; - } - irq[asic] = 0; - } - devpriv->asics[asic].irq = irq[asic]; - } - - dev->irq = irq[0]; /* - * grr.. wish comedi dev struct supported - * multiple irqs.. - */ - - if (irq[0]) { - printk(KERN_DEBUG "comedi%d: irq: %u\n", dev->minor, irq[0]); - if (thisboard->dio_num_asics == 2 && irq[1]) - printk(KERN_DEBUG "comedi%d: second ASIC irq: %u\n", - dev->minor, irq[1]); - } else { - printk(KERN_INFO "comedi%d: (IRQ mode disabled)\n", dev->minor); - } - - printk(KERN_INFO "comedi%d: attached\n", dev->minor); - - return 1; -} - -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int pcmmio_detach(struct comedi_device *dev) -{ - int i; - - printk(KERN_INFO "comedi%d: %s: remove\n", dev->minor, driver.driver_name); - if (dev->iobase) - release_region(dev->iobase, thisboard->total_iosize); - - for (i = 0; i < MAX_ASICS; ++i) { - if (devpriv && devpriv->asics[i].irq) - free_irq(devpriv->asics[i].irq, dev); - } - - if (devpriv && devpriv->sprivs) - kfree(devpriv->sprivs); - - return 0; -} /* DIO devices are slightly special. Although it is possible to * implement the insn_read/insn_write interface, it is much more @@ -751,6 +421,21 @@ static int pcmmio_dio_insn_config(struct comedi_device *dev, return insn->n; } +static void switch_page(struct comedi_device *dev, int asic, int page) +{ + if (asic < 0 || asic >= thisboard->dio_num_asics) + return; /* paranoia */ + if (page < 0 || page >= NUM_PAGES) + return; /* more paranoia */ + + devpriv->asics[asic].pagelock &= ~REG_PAGE_MASK; + devpriv->asics[asic].pagelock |= page << REG_PAGE_BITOFFSET; + + /* now write out the shadow register */ + outb(devpriv->asics[asic].pagelock, + devpriv->asics[asic].iobase + REG_PAGELOCK); +} + static void init_asics(struct comedi_device *dev) { /* sets up an ASIC chip to defaults */ @@ -788,21 +473,6 @@ static void init_asics(struct comedi_device *dev) } } -static void switch_page(struct comedi_device *dev, int asic, int page) -{ - if (asic < 0 || asic >= thisboard->dio_num_asics) - return; /* paranoia */ - if (page < 0 || page >= NUM_PAGES) - return; /* more paranoia */ - - devpriv->asics[asic].pagelock &= ~REG_PAGE_MASK; - devpriv->asics[asic].pagelock |= page << REG_PAGE_BITOFFSET; - - /* now write out the shadow register */ - outb(devpriv->asics[asic].pagelock, - devpriv->asics[asic].iobase + REG_PAGELOCK); -} - #ifdef notused static void lock_port(struct comedi_device *dev, int asic, int port) { @@ -831,6 +501,27 @@ static void unlock_port(struct comedi_device *dev, int asic, int port) } #endif /* notused */ +static void pcmmio_stop_intr(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + int nports, firstport, asic, port; + + asic = subpriv->dio.intr.asic; + if (asic < 0) + return; /* not an interrupt subdev */ + + subpriv->dio.intr.enabled_mask = 0; + subpriv->dio.intr.active = 0; + s->async->inttrig = 0; + nports = subpriv->dio.intr.num_asic_chans / CHANS_PER_PORT; + firstport = subpriv->dio.intr.asic_chan / CHANS_PER_PORT; + switch_page(dev, asic, PAGE_ENAB); + for (port = firstport; port < firstport + nports; ++port) { + /* disable all intrs for this subdev.. */ + outb(0, devpriv->asics[asic].iobase + REG_ENAB0 + port); + } +} + static irqreturn_t interrupt_pcmmio(int irq, void *d) { int asic, got1 = 0; @@ -981,35 +672,14 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d) } - } - } - - } - } - if (!got1) - return IRQ_NONE; /* interrupt from other source */ - return IRQ_HANDLED; -} - -static void pcmmio_stop_intr(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - int nports, firstport, asic, port; - - asic = subpriv->dio.intr.asic; - if (asic < 0) - return; /* not an interrupt subdev */ - - subpriv->dio.intr.enabled_mask = 0; - subpriv->dio.intr.active = 0; - s->async->inttrig = 0; - nports = subpriv->dio.intr.num_asic_chans / CHANS_PER_PORT; - firstport = subpriv->dio.intr.asic_chan / CHANS_PER_PORT; - switch_page(dev, asic, PAGE_ENAB); - for (port = firstport; port < firstport + nports; ++port) { - /* disable all intrs for this subdev.. */ - outb(0, devpriv->asics[asic].iobase + REG_ENAB0 + port); + } + } + + } } + if (!got1) + return IRQ_NONE; /* interrupt from other source */ + return IRQ_HANDLED; } static int pcmmio_start_intr(struct comedi_device *dev, @@ -1340,21 +1010,276 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, return n; } +static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + int sdev_no, chans_left, n_dio_subdevs, n_subdevs, port, asic, + thisasic_chanct = 0; + unsigned long iobase; + unsigned int irq[MAX_ASICS]; + + iobase = it->options[0]; + irq[0] = it->options[1]; + + printk(KERN_INFO "comedi%d: %s: io: %lx attaching...\n", dev->minor, + driver.driver_name, iobase); + + dev->iobase = iobase; + + if (!iobase || !request_region(iobase, + thisboard->total_iosize, + driver.driver_name)) { + printk(KERN_ERR "comedi%d: I/O port conflict\n", dev->minor); + return -EIO; + } + +/* + * Initialize dev->board_name. Note that we can use the "thisboard" + * macro now, since we just initialized it in the last line. + */ + dev->board_name = thisboard->name; + /* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. + * Allocate the private structure area. alloc_private() is a + * convenient macro defined in comedidev.h. */ + if (alloc_private(dev, sizeof(struct pcmmio_private)) < 0) { + printk(KERN_ERR "comedi%d: cannot allocate private data structure\n", + dev->minor); + return -ENOMEM; + } + + for (asic = 0; asic < MAX_ASICS; ++asic) { + devpriv->asics[asic].num = asic; + devpriv->asics[asic].iobase = + dev->iobase + 16 + asic * ASIC_IOSIZE; + /* + * this gets actually set at the end of this function when we + * request_irqs + */ + devpriv->asics[asic].irq = 0; + spin_lock_init(&devpriv->asics[asic].spinlock); + } + + chans_left = CHANS_PER_ASIC * thisboard->dio_num_asics; + n_dio_subdevs = CALC_N_DIO_SUBDEVS(chans_left); + n_subdevs = n_dio_subdevs + 2; + devpriv->sprivs = + kcalloc(n_subdevs, sizeof(struct pcmmio_subdev_private), + GFP_KERNEL); + if (!devpriv->sprivs) { + printk(KERN_ERR "comedi%d: cannot allocate subdevice private data structures\n", + dev->minor); + return -ENOMEM; + } + /* + * Allocate the subdevice structures. alloc_subdevice() is a + * convenient macro defined in comedidev.h. + * + * Allocate 1 AI + 1 AO + 2 DIO subdevs (24 lines per DIO) + */ + if (alloc_subdevices(dev, n_subdevs) < 0) { + printk(KERN_ERR "comedi%d: cannot allocate subdevice data structures\n", + dev->minor); + return -ENOMEM; + } + + /* First, AI */ + sdev_no = 0; + s = dev->subdevices + sdev_no; + s->private = devpriv->sprivs + sdev_no; + s->maxdata = (1 << thisboard->ai_bits) - 1; + s->range_table = thisboard->ai_range_table; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; + s->type = COMEDI_SUBD_AI; + s->n_chan = thisboard->n_ai_chans; + s->len_chanlist = s->n_chan; + s->insn_read = thisboard->ai_rinsn; + subpriv->iobase = dev->iobase + 0; + /* initialize the resource enable register by clearing it */ + outb(0, subpriv->iobase + 3); + outb(0, subpriv->iobase + 4 + 3); + + /* Next, AO */ + ++sdev_no; + s = dev->subdevices + sdev_no; + s->private = devpriv->sprivs + sdev_no; + s->maxdata = (1 << thisboard->ao_bits) - 1; + s->range_table = thisboard->ao_range_table; + s->subdev_flags = SDF_READABLE; + s->type = COMEDI_SUBD_AO; + s->n_chan = thisboard->n_ao_chans; + s->len_chanlist = s->n_chan; + s->insn_read = thisboard->ao_rinsn; + s->insn_write = thisboard->ao_winsn; + subpriv->iobase = dev->iobase + 8; + /* initialize the resource enable register by clearing it */ + outb(0, subpriv->iobase + 3); + outb(0, subpriv->iobase + 4 + 3); + + ++sdev_no; + port = 0; + asic = 0; + for (; sdev_no < (int)dev->n_subdevices; ++sdev_no) { + int byte_no; + + s = dev->subdevices + sdev_no; + s->private = devpriv->sprivs + sdev_no; + s->maxdata = 1; + s->range_table = &range_digital; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->type = COMEDI_SUBD_DIO; + s->insn_bits = pcmmio_dio_insn_bits; + s->insn_config = pcmmio_dio_insn_config; + s->n_chan = min(chans_left, MAX_CHANS_PER_SUBDEV); + subpriv->dio.intr.asic = -1; + subpriv->dio.intr.first_chan = -1; + subpriv->dio.intr.asic_chan = -1; + subpriv->dio.intr.num_asic_chans = -1; + subpriv->dio.intr.active = 0; + s->len_chanlist = 1; + + /* save the ioport address for each 'port' of 8 channels in the + subdevice */ + for (byte_no = 0; byte_no < PORTS_PER_SUBDEV; ++byte_no, ++port) { + if (port >= PORTS_PER_ASIC) { + port = 0; + ++asic; + thisasic_chanct = 0; + } + subpriv->iobases[byte_no] = + devpriv->asics[asic].iobase + port; + + if (thisasic_chanct < + CHANS_PER_PORT * INTR_PORTS_PER_ASIC + && subpriv->dio.intr.asic < 0) { + /* + * this is an interrupt subdevice, + * so setup the struct + */ + subpriv->dio.intr.asic = asic; + subpriv->dio.intr.active = 0; + subpriv->dio.intr.stop_count = 0; + subpriv->dio.intr.first_chan = byte_no * 8; + subpriv->dio.intr.asic_chan = thisasic_chanct; + subpriv->dio.intr.num_asic_chans = + s->n_chan - subpriv->dio.intr.first_chan; + s->cancel = pcmmio_cancel; + s->do_cmd = pcmmio_cmd; + s->do_cmdtest = pcmmio_cmdtest; + s->len_chanlist = + subpriv->dio.intr.num_asic_chans; + } + thisasic_chanct += CHANS_PER_PORT; + } + spin_lock_init(&subpriv->dio.intr.spinlock); + + chans_left -= s->n_chan; + + if (!chans_left) { + /* + * reset the asic to our first asic, + * to do intr subdevs + */ + asic = 0; + port = 0; + } + + } + + init_asics(dev); /* clear out all the registers, basically */ + + for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) { + if (irq[asic] + && request_irq(irq[asic], interrupt_pcmmio, + IRQF_SHARED, thisboard->name, dev)) { + int i; + /* unroll the allocated irqs.. */ + for (i = asic - 1; i >= 0; --i) { + free_irq(irq[i], dev); + devpriv->asics[i].irq = irq[i] = 0; + } + irq[asic] = 0; + } + devpriv->asics[asic].irq = irq[asic]; + } + + dev->irq = irq[0]; /* + * grr.. wish comedi dev struct supported + * multiple irqs.. + */ + + if (irq[0]) { + printk(KERN_DEBUG "comedi%d: irq: %u\n", dev->minor, irq[0]); + if (thisboard->dio_num_asics == 2 && irq[1]) + printk(KERN_DEBUG "comedi%d: second ASIC irq: %u\n", + dev->minor, irq[1]); + } else { + printk(KERN_INFO "comedi%d: (IRQ mode disabled)\n", dev->minor); + } + + printk(KERN_INFO "comedi%d: attached\n", dev->minor); + + return 1; +} + +static int pcmmio_detach(struct comedi_device *dev) +{ + int i; + + printk(KERN_INFO "comedi%d: %s: remove\n", dev->minor, driver.driver_name); + if (dev->iobase) + release_region(dev->iobase, thisboard->total_iosize); + + for (i = 0; i < MAX_ASICS; ++i) { + if (devpriv && devpriv->asics[i].irq) + free_irq(devpriv->asics[i].irq, dev); + } + + if (devpriv && devpriv->sprivs) + kfree(devpriv->sprivs); + + return 0; +} + +static const struct pcmmio_board pcmmio_boards[] = { + { + .name = "pcmmio", + .dio_num_asics = 1, + .dio_num_ports = 6, + .total_iosize = 32, + .ai_bits = 16, + .ao_bits = 16, + .n_ai_chans = 16, + .n_ao_chans = 8, + .ai_range_table = &ranges_ai, + .ao_range_table = &ranges_ao, + .ai_rinsn = ai_rinsn, + .ao_rinsn = ao_rinsn, + .ao_winsn = ao_winsn + }, +}; + +static struct comedi_driver driver = { + .driver_name = "pcmmio", + .module = THIS_MODULE, + .attach = pcmmio_attach, + .detach = pcmmio_detach, + .board_name = &pcmmio_boards[0].name, + .offset = sizeof(struct pcmmio_board), + .num_names = ARRAY_SIZE(pcmmio_boards), +}; + static int __init driver_init_module(void) { return comedi_driver_register(&driver); } +module_init(driver_init_module); static void __exit driver_cleanup_module(void) { comedi_driver_unregister(&driver); } - -module_init(driver_init_module); module_exit(driver_cleanup_module); MODULE_AUTHOR("Comedi http://www.comedi.org"); -- cgit v0.10.2 From 6b19f9c6bee7afcd1e5dee9528333b2aa52de404 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 15:28:57 -0700 Subject: staging: comedi: refactor pcmuio driver to remove forward declarations Refactor the switch_page and pcmuio_stop_intr functions to avoid needing the forward declarations. Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 661ba2e..de4f486 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -155,19 +155,6 @@ struct pcmuio_board { const int num_ports; }; -static const struct pcmuio_board pcmuio_boards[] = { - { - .name = "pcmuio48", - .num_asics = 1, - .num_ports = 6, - }, - { - .name = "pcmuio96", - .num_asics = 2, - .num_ports = 12, - }, -}; - /* * Useful for shorthand access to the particular board structure */ @@ -218,262 +205,6 @@ struct pcmuio_private { */ #define devpriv ((struct pcmuio_private *)dev->private) #define subpriv ((struct pcmuio_subdev_private *)s->private) -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int pcmuio_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcmuio_detach(struct comedi_device *dev); - -static struct comedi_driver driver = { - .driver_name = "pcmuio", - .module = THIS_MODULE, - .attach = pcmuio_attach, - .detach = pcmuio_detach, -/* It is not necessary to implement the following members if you are - * writing a driver for a ISA PnP or PCI card */ - /* Most drivers will support multiple types of boards by - * having an array of board structures. These were defined - * in pcmuio_boards[] above. Note that the element 'name' - * was first in the structure -- Comedi uses this fact to - * extract the name of the board without knowing any details - * about the structure except for its length. - * When a device is attached (by comedi_config), the name - * of the device is given to Comedi, and Comedi tries to - * match it by going through the list of board names. If - * there is a match, the address of the pointer is put - * into dev->board_ptr and driver->attach() is called. - * - * Note that these are not necessary if you can determine - * the type of board in software. ISA PnP, PCI, and PCMCIA - * devices are such boards. - */ - .board_name = &pcmuio_boards[0].name, - .offset = sizeof(struct pcmuio_board), - .num_names = ARRAY_SIZE(pcmuio_boards), -}; - -static int pcmuio_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int pcmuio_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static irqreturn_t interrupt_pcmuio(int irq, void *d); -static void pcmuio_stop_intr(struct comedi_device *, struct comedi_subdevice *); -static int pcmuio_cancel(struct comedi_device *dev, struct comedi_subdevice *s); -static int pcmuio_cmd(struct comedi_device *dev, struct comedi_subdevice *s); -static int pcmuio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_cmd *cmd); - -/* some helper functions to deal with specifics of this device's registers */ -static void init_asics(struct comedi_device *dev); /* sets up/clears ASIC chips to defaults */ -static void switch_page(struct comedi_device *dev, int asic, int page); -#ifdef notused -static void lock_port(struct comedi_device *dev, int asic, int port); -static void unlock_port(struct comedi_device *dev, int asic, int port); -#endif - -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ -static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - int sdev_no, chans_left, n_subdevs, port, asic, thisasic_chanct = 0; - unsigned long iobase; - unsigned int irq[MAX_ASICS]; - - iobase = it->options[0]; - irq[0] = it->options[1]; - irq[1] = it->options[2]; - - dev_dbg(dev->hw_dev, "comedi%d: %s: io: %lx attached\n", dev->minor, - driver.driver_name, iobase); - - dev->iobase = iobase; - - if (!iobase || !request_region(iobase, - thisboard->num_asics * ASIC_IOSIZE, - driver.driver_name)) { - dev_err(dev->hw_dev, "I/O port conflict\n"); - return -EIO; - } - -/* - * Initialize dev->board_name. Note that we can use the "thisboard" - * macro now, since we just initialized it in the last line. - */ - dev->board_name = thisboard->name; - -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_private(dev, sizeof(struct pcmuio_private)) < 0) { - dev_warn(dev->hw_dev, "cannot allocate private data structure\n"); - return -ENOMEM; - } - - for (asic = 0; asic < MAX_ASICS; ++asic) { - devpriv->asics[asic].num = asic; - devpriv->asics[asic].iobase = dev->iobase + asic * ASIC_IOSIZE; - devpriv->asics[asic].irq = 0; /* this gets actually set at the end of - this function when we - request_irqs */ - spin_lock_init(&devpriv->asics[asic].spinlock); - } - - chans_left = CHANS_PER_ASIC * thisboard->num_asics; - n_subdevs = CALC_N_SUBDEVS(chans_left); - devpriv->sprivs = - kcalloc(n_subdevs, sizeof(struct pcmuio_subdev_private), - GFP_KERNEL); - if (!devpriv->sprivs) { - dev_warn(dev->hw_dev, "cannot allocate subdevice private data structures\n"); - return -ENOMEM; - } - /* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - * - * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the - * 96-channel version of the board. - */ - if (alloc_subdevices(dev, n_subdevs) < 0) { - dev_dbg(dev->hw_dev, "cannot allocate subdevice data structures\n"); - return -ENOMEM; - } - - port = 0; - asic = 0; - for (sdev_no = 0; sdev_no < (int)dev->n_subdevices; ++sdev_no) { - int byte_no; - - s = dev->subdevices + sdev_no; - s->private = devpriv->sprivs + sdev_no; - s->maxdata = 1; - s->range_table = &range_digital; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->type = COMEDI_SUBD_DIO; - s->insn_bits = pcmuio_dio_insn_bits; - s->insn_config = pcmuio_dio_insn_config; - s->n_chan = min(chans_left, MAX_CHANS_PER_SUBDEV); - subpriv->intr.asic = -1; - subpriv->intr.first_chan = -1; - subpriv->intr.asic_chan = -1; - subpriv->intr.num_asic_chans = -1; - subpriv->intr.active = 0; - s->len_chanlist = 1; - - /* save the ioport address for each 'port' of 8 channels in the - subdevice */ - for (byte_no = 0; byte_no < PORTS_PER_SUBDEV; ++byte_no, ++port) { - if (port >= PORTS_PER_ASIC) { - port = 0; - ++asic; - thisasic_chanct = 0; - } - subpriv->iobases[byte_no] = - devpriv->asics[asic].iobase + port; - - if (thisasic_chanct < - CHANS_PER_PORT * INTR_PORTS_PER_ASIC - && subpriv->intr.asic < 0) { - /* this is an interrupt subdevice, so setup the struct */ - subpriv->intr.asic = asic; - subpriv->intr.active = 0; - subpriv->intr.stop_count = 0; - subpriv->intr.first_chan = byte_no * 8; - subpriv->intr.asic_chan = thisasic_chanct; - subpriv->intr.num_asic_chans = - s->n_chan - subpriv->intr.first_chan; - dev->read_subdev = s; - s->subdev_flags |= SDF_CMD_READ; - s->cancel = pcmuio_cancel; - s->do_cmd = pcmuio_cmd; - s->do_cmdtest = pcmuio_cmdtest; - s->len_chanlist = subpriv->intr.num_asic_chans; - } - thisasic_chanct += CHANS_PER_PORT; - } - spin_lock_init(&subpriv->intr.spinlock); - - chans_left -= s->n_chan; - - if (!chans_left) { - asic = 0; /* reset the asic to our first asic, to do intr subdevs */ - port = 0; - } - - } - - init_asics(dev); /* clear out all the registers, basically */ - - for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) { - if (irq[asic] - && request_irq(irq[asic], interrupt_pcmuio, - IRQF_SHARED, thisboard->name, dev)) { - int i; - /* unroll the allocated irqs.. */ - for (i = asic - 1; i >= 0; --i) { - free_irq(irq[i], dev); - devpriv->asics[i].irq = irq[i] = 0; - } - irq[asic] = 0; - } - devpriv->asics[asic].irq = irq[asic]; - } - - dev->irq = irq[0]; /* grr.. wish comedi dev struct supported multiple - irqs.. */ - - if (irq[0]) { - dev_dbg(dev->hw_dev, "irq: %u\n", irq[0]); - if (irq[1] && thisboard->num_asics == 2) - dev_dbg(dev->hw_dev, "second ASIC irq: %u\n", irq[1]); - } else { - dev_dbg(dev->hw_dev, "(IRQ mode disabled)\n"); - } - - - return 1; -} - -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int pcmuio_detach(struct comedi_device *dev) -{ - int i; - - dev_dbg(dev->hw_dev, "comedi%d: %s: remove\n", dev->minor, - driver.driver_name); - if (dev->iobase) - release_region(dev->iobase, ASIC_IOSIZE * thisboard->num_asics); - - for (i = 0; i < MAX_ASICS; ++i) { - if (devpriv->asics[i].irq) - free_irq(devpriv->asics[i].irq, dev); - } - - if (devpriv && devpriv->sprivs) - kfree(devpriv->sprivs); - - return 0; -} /* DIO devices are slightly special. Although it is possible to * implement the insn_read/insn_write interface, it is much more @@ -621,6 +352,21 @@ static int pcmuio_dio_insn_config(struct comedi_device *dev, return insn->n; } +static void switch_page(struct comedi_device *dev, int asic, int page) +{ + if (asic < 0 || asic >= thisboard->num_asics) + return; /* paranoia */ + if (page < 0 || page >= NUM_PAGES) + return; /* more paranoia */ + + devpriv->asics[asic].pagelock &= ~REG_PAGE_MASK; + devpriv->asics[asic].pagelock |= page << REG_PAGE_BITOFFSET; + + /* now write out the shadow register */ + outb(devpriv->asics[asic].pagelock, + dev->iobase + ASIC_IOSIZE * asic + REG_PAGELOCK); +} + static void init_asics(struct comedi_device *dev) { /* sets up an ASIC chip to defaults */ @@ -658,21 +404,6 @@ static void init_asics(struct comedi_device *dev) } } -static void switch_page(struct comedi_device *dev, int asic, int page) -{ - if (asic < 0 || asic >= thisboard->num_asics) - return; /* paranoia */ - if (page < 0 || page >= NUM_PAGES) - return; /* more paranoia */ - - devpriv->asics[asic].pagelock &= ~REG_PAGE_MASK; - devpriv->asics[asic].pagelock |= page << REG_PAGE_BITOFFSET; - - /* now write out the shadow register */ - outb(devpriv->asics[asic].pagelock, - dev->iobase + ASIC_IOSIZE * asic + REG_PAGELOCK); -} - #ifdef notused static void lock_port(struct comedi_device *dev, int asic, int port) { @@ -700,6 +431,27 @@ static void unlock_port(struct comedi_device *dev, int asic, int port) } #endif /* notused */ +static void pcmuio_stop_intr(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + int nports, firstport, asic, port; + + asic = subpriv->intr.asic; + if (asic < 0) + return; /* not an interrupt subdev */ + + subpriv->intr.enabled_mask = 0; + subpriv->intr.active = 0; + s->async->inttrig = 0; + nports = subpriv->intr.num_asic_chans / CHANS_PER_PORT; + firstport = subpriv->intr.asic_chan / CHANS_PER_PORT; + switch_page(dev, asic, PAGE_ENAB); + for (port = firstport; port < firstport + nports; ++port) { + /* disable all intrs for this subdev.. */ + outb(0, devpriv->asics[asic].iobase + REG_ENAB0 + port); + } +} + static irqreturn_t interrupt_pcmuio(int irq, void *d) { int asic, got1 = 0; @@ -852,27 +604,6 @@ static irqreturn_t interrupt_pcmuio(int irq, void *d) return IRQ_HANDLED; } -static void pcmuio_stop_intr(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - int nports, firstport, asic, port; - - asic = subpriv->intr.asic; - if (asic < 0) - return; /* not an interrupt subdev */ - - subpriv->intr.enabled_mask = 0; - subpriv->intr.active = 0; - s->async->inttrig = 0; - nports = subpriv->intr.num_asic_chans / CHANS_PER_PORT; - firstport = subpriv->intr.asic_chan / CHANS_PER_PORT; - switch_page(dev, asic, PAGE_ENAB); - for (port = firstport; port < firstport + nports; ++port) { - /* disable all intrs for this subdev.. */ - outb(0, devpriv->asics[asic].iobase + REG_ENAB0 + port); - } -} - static int pcmuio_start_intr(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -1014,21 +745,221 @@ pcmuio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, return comedi_pcm_cmdtest(dev, s, cmd); } +static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + int sdev_no, chans_left, n_subdevs, port, asic, thisasic_chanct = 0; + unsigned long iobase; + unsigned int irq[MAX_ASICS]; + + iobase = it->options[0]; + irq[0] = it->options[1]; + irq[1] = it->options[2]; + + dev_dbg(dev->hw_dev, "comedi%d: %s: io: %lx attached\n", dev->minor, + driver.driver_name, iobase); + + dev->iobase = iobase; + + if (!iobase || !request_region(iobase, + thisboard->num_asics * ASIC_IOSIZE, + driver.driver_name)) { + dev_err(dev->hw_dev, "I/O port conflict\n"); + return -EIO; + } + /* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. + * Initialize dev->board_name. Note that we can use the "thisboard" + * macro now, since we just initialized it in the last line. + */ + dev->board_name = thisboard->name; + +/* + * Allocate the private structure area. alloc_private() is a + * convenient macro defined in comedidev.h. */ + if (alloc_private(dev, sizeof(struct pcmuio_private)) < 0) { + dev_warn(dev->hw_dev, "cannot allocate private data structure\n"); + return -ENOMEM; + } + + for (asic = 0; asic < MAX_ASICS; ++asic) { + devpriv->asics[asic].num = asic; + devpriv->asics[asic].iobase = dev->iobase + asic * ASIC_IOSIZE; + devpriv->asics[asic].irq = 0; /* this gets actually set at the end of + this function when we + request_irqs */ + spin_lock_init(&devpriv->asics[asic].spinlock); + } + + chans_left = CHANS_PER_ASIC * thisboard->num_asics; + n_subdevs = CALC_N_SUBDEVS(chans_left); + devpriv->sprivs = + kcalloc(n_subdevs, sizeof(struct pcmuio_subdev_private), + GFP_KERNEL); + if (!devpriv->sprivs) { + dev_warn(dev->hw_dev, "cannot allocate subdevice private data structures\n"); + return -ENOMEM; + } + /* + * Allocate the subdevice structures. alloc_subdevice() is a + * convenient macro defined in comedidev.h. + * + * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the + * 96-channel version of the board. + */ + if (alloc_subdevices(dev, n_subdevs) < 0) { + dev_dbg(dev->hw_dev, "cannot allocate subdevice data structures\n"); + return -ENOMEM; + } + + port = 0; + asic = 0; + for (sdev_no = 0; sdev_no < (int)dev->n_subdevices; ++sdev_no) { + int byte_no; + + s = dev->subdevices + sdev_no; + s->private = devpriv->sprivs + sdev_no; + s->maxdata = 1; + s->range_table = &range_digital; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->type = COMEDI_SUBD_DIO; + s->insn_bits = pcmuio_dio_insn_bits; + s->insn_config = pcmuio_dio_insn_config; + s->n_chan = min(chans_left, MAX_CHANS_PER_SUBDEV); + subpriv->intr.asic = -1; + subpriv->intr.first_chan = -1; + subpriv->intr.asic_chan = -1; + subpriv->intr.num_asic_chans = -1; + subpriv->intr.active = 0; + s->len_chanlist = 1; + + /* save the ioport address for each 'port' of 8 channels in the + subdevice */ + for (byte_no = 0; byte_no < PORTS_PER_SUBDEV; ++byte_no, ++port) { + if (port >= PORTS_PER_ASIC) { + port = 0; + ++asic; + thisasic_chanct = 0; + } + subpriv->iobases[byte_no] = + devpriv->asics[asic].iobase + port; + + if (thisasic_chanct < + CHANS_PER_PORT * INTR_PORTS_PER_ASIC + && subpriv->intr.asic < 0) { + /* this is an interrupt subdevice, so setup the struct */ + subpriv->intr.asic = asic; + subpriv->intr.active = 0; + subpriv->intr.stop_count = 0; + subpriv->intr.first_chan = byte_no * 8; + subpriv->intr.asic_chan = thisasic_chanct; + subpriv->intr.num_asic_chans = + s->n_chan - subpriv->intr.first_chan; + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->cancel = pcmuio_cancel; + s->do_cmd = pcmuio_cmd; + s->do_cmdtest = pcmuio_cmdtest; + s->len_chanlist = subpriv->intr.num_asic_chans; + } + thisasic_chanct += CHANS_PER_PORT; + } + spin_lock_init(&subpriv->intr.spinlock); + + chans_left -= s->n_chan; + + if (!chans_left) { + asic = 0; /* reset the asic to our first asic, to do intr subdevs */ + port = 0; + } + + } + + init_asics(dev); /* clear out all the registers, basically */ + + for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) { + if (irq[asic] + && request_irq(irq[asic], interrupt_pcmuio, + IRQF_SHARED, thisboard->name, dev)) { + int i; + /* unroll the allocated irqs.. */ + for (i = asic - 1; i >= 0; --i) { + free_irq(irq[i], dev); + devpriv->asics[i].irq = irq[i] = 0; + } + irq[asic] = 0; + } + devpriv->asics[asic].irq = irq[asic]; + } + + dev->irq = irq[0]; /* grr.. wish comedi dev struct supported multiple + irqs.. */ + + if (irq[0]) { + dev_dbg(dev->hw_dev, "irq: %u\n", irq[0]); + if (irq[1] && thisboard->num_asics == 2) + dev_dbg(dev->hw_dev, "second ASIC irq: %u\n", irq[1]); + } else { + dev_dbg(dev->hw_dev, "(IRQ mode disabled)\n"); + } + + + return 1; +} + +static int pcmuio_detach(struct comedi_device *dev) +{ + int i; + + dev_dbg(dev->hw_dev, "comedi%d: %s: remove\n", dev->minor, + driver.driver_name); + if (dev->iobase) + release_region(dev->iobase, ASIC_IOSIZE * thisboard->num_asics); + + for (i = 0; i < MAX_ASICS; ++i) { + if (devpriv->asics[i].irq) + free_irq(devpriv->asics[i].irq, dev); + } + + if (devpriv && devpriv->sprivs) + kfree(devpriv->sprivs); + + return 0; +} + +static const struct pcmuio_board pcmuio_boards[] = { + { + .name = "pcmuio48", + .num_asics = 1, + .num_ports = 6, + }, { + .name = "pcmuio96", + .num_asics = 2, + .num_ports = 12, + }, +}; + +static struct comedi_driver driver = { + .driver_name = "pcmuio", + .module = THIS_MODULE, + .attach = pcmuio_attach, + .detach = pcmuio_detach, + .board_name = &pcmuio_boards[0].name, + .offset = sizeof(struct pcmuio_board), + .num_names = ARRAY_SIZE(pcmuio_boards), +}; + static int __init driver_init_module(void) { return comedi_driver_register(&driver); } +module_init(driver_init_module); static void __exit driver_cleanup_module(void) { comedi_driver_unregister(&driver); } - -module_init(driver_init_module); module_exit(driver_cleanup_module); MODULE_AUTHOR("Comedi http://www.comedi.org"); -- cgit v0.10.2 From 9a644c40a3f4165d4c03ba52f70e9f0488f4c993 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 15:18:23 -0700 Subject: staging: comedi: refactor poc driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/poc.c b/drivers/staging/comedi/drivers/poc.c index 831a576..e3690bb 100644 --- a/drivers/staging/comedi/drivers/poc.c +++ b/drivers/staging/comedi/drivers/poc.c @@ -41,20 +41,6 @@ Configuration options: #include -static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int poc_detach(struct comedi_device *dev); -static int readback_insn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int dac02_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int pcl733_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int pcl734_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - struct boarddef_struct { const char *name; unsigned int iosize; @@ -70,108 +56,9 @@ struct boarddef_struct { struct comedi_insn *, unsigned int *); const struct comedi_lrange *range; }; -static const struct boarddef_struct boards[] = { - { - .name = "dac02", - .iosize = 8, - /* .setup = dac02_setup, */ - .type = COMEDI_SUBD_AO, - .n_chan = 2, - .n_bits = 12, - .winsn = dac02_ao_winsn, - .rinsn = readback_insn, - .range = &range_unknown, - }, - { - .name = "pcl733", - .iosize = 4, - .type = COMEDI_SUBD_DI, - .n_chan = 32, - .n_bits = 1, - .insnbits = pcl733_insn_bits, - .range = &range_digital, - }, - { - .name = "pcl734", - .iosize = 4, - .type = COMEDI_SUBD_DO, - .n_chan = 32, - .n_bits = 1, - .insnbits = pcl734_insn_bits, - .range = &range_digital, - }, -}; -#define n_boards ARRAY_SIZE(boards) #define this_board ((const struct boarddef_struct *)dev->board_ptr) -static struct comedi_driver driver_poc = { - .driver_name = "poc", - .module = THIS_MODULE, - .attach = poc_attach, - .detach = poc_detach, - .board_name = &boards[0].name, - .num_names = n_boards, - .offset = sizeof(boards[0]), -}; - -static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - unsigned long iobase; - unsigned int iosize; - - iobase = it->options[0]; - printk(KERN_INFO "comedi%d: poc: using %s iobase 0x%lx\n", dev->minor, - this_board->name, iobase); - - dev->board_name = this_board->name; - - if (iobase == 0) { - printk(KERN_ERR "io base address required\n"); - return -EINVAL; - } - - iosize = this_board->iosize; - /* check if io addresses are available */ - if (!request_region(iobase, iosize, "dac02")) { - printk(KERN_ERR "I/O port conflict: failed to allocate ports " - "0x%lx to 0x%lx\n", iobase, iobase + iosize - 1); - return -EIO; - } - dev->iobase = iobase; - - if (alloc_subdevices(dev, 1) < 0) - return -ENOMEM; - if (alloc_private(dev, sizeof(unsigned int) * this_board->n_chan) < 0) - return -ENOMEM; - - /* analog output subdevice */ - s = dev->subdevices + 0; - s->type = this_board->type; - s->n_chan = this_board->n_chan; - s->maxdata = (1 << this_board->n_bits) - 1; - s->range_table = this_board->range; - s->insn_write = this_board->winsn; - s->insn_read = this_board->rinsn; - s->insn_bits = this_board->insnbits; - if (s->type == COMEDI_SUBD_AO || s->type == COMEDI_SUBD_DO) - s->subdev_flags = SDF_WRITABLE; - - return 0; -} - -static int poc_detach(struct comedi_device *dev) -{ - /* only free stuff if it has been allocated by _attach */ - if (dev->iobase) - release_region(dev->iobase, this_board->iosize); - - printk(KERN_INFO "comedi%d: dac02: remove\n", dev->minor); - - return 0; -} - static int readback_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { @@ -248,17 +135,113 @@ static int pcl734_insn_bits(struct comedi_device *dev, return 2; } +static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + unsigned long iobase; + unsigned int iosize; + + iobase = it->options[0]; + printk(KERN_INFO "comedi%d: poc: using %s iobase 0x%lx\n", dev->minor, + this_board->name, iobase); + + dev->board_name = this_board->name; + + if (iobase == 0) { + printk(KERN_ERR "io base address required\n"); + return -EINVAL; + } + + iosize = this_board->iosize; + /* check if io addresses are available */ + if (!request_region(iobase, iosize, "dac02")) { + printk(KERN_ERR "I/O port conflict: failed to allocate ports " + "0x%lx to 0x%lx\n", iobase, iobase + iosize - 1); + return -EIO; + } + dev->iobase = iobase; + + if (alloc_subdevices(dev, 1) < 0) + return -ENOMEM; + if (alloc_private(dev, sizeof(unsigned int) * this_board->n_chan) < 0) + return -ENOMEM; + + /* analog output subdevice */ + s = dev->subdevices + 0; + s->type = this_board->type; + s->n_chan = this_board->n_chan; + s->maxdata = (1 << this_board->n_bits) - 1; + s->range_table = this_board->range; + s->insn_write = this_board->winsn; + s->insn_read = this_board->rinsn; + s->insn_bits = this_board->insnbits; + if (s->type == COMEDI_SUBD_AO || s->type == COMEDI_SUBD_DO) + s->subdev_flags = SDF_WRITABLE; + + return 0; +} + +static int poc_detach(struct comedi_device *dev) +{ + /* only free stuff if it has been allocated by _attach */ + if (dev->iobase) + release_region(dev->iobase, this_board->iosize); + + printk(KERN_INFO "comedi%d: dac02: remove\n", dev->minor); + + return 0; +} + +static const struct boarddef_struct boards[] = { + { + .name = "dac02", + .iosize = 8, + /* .setup = dac02_setup, */ + .type = COMEDI_SUBD_AO, + .n_chan = 2, + .n_bits = 12, + .winsn = dac02_ao_winsn, + .rinsn = readback_insn, + .range = &range_unknown, + }, { + .name = "pcl733", + .iosize = 4, + .type = COMEDI_SUBD_DI, + .n_chan = 32, + .n_bits = 1, + .insnbits = pcl733_insn_bits, + .range = &range_digital, + }, { + .name = "pcl734", + .iosize = 4, + .type = COMEDI_SUBD_DO, + .n_chan = 32, + .n_bits = 1, + .insnbits = pcl734_insn_bits, + .range = &range_digital, + }, +}; + +static struct comedi_driver driver_poc = { + .driver_name = "poc", + .module = THIS_MODULE, + .attach = poc_attach, + .detach = poc_detach, + .board_name = &boards[0].name, + .num_names = ARRAY_SIZE(boards), + .offset = sizeof(boards[0]), +}; + static int __init driver_poc_init_module(void) { return comedi_driver_register(&driver_poc); } +module_init(driver_poc_init_module); static void __exit driver_poc_cleanup_module(void) { comedi_driver_unregister(&driver_poc); } - -module_init(driver_poc_init_module); module_exit(driver_poc_cleanup_module); MODULE_AUTHOR("Comedi http://www.comedi.org"); -- cgit v0.10.2 From 6beb8160ea04a7891d5102f86104f75c0db05d15 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 15:09:49 -0700 Subject: staging: comedi: partial refactor of the rtd520 driver to remove forward declarations Move the struct comedi_driver MODULE_DEVICE_TABLE to the end of the source. The attach and detach functions are not moved yet because patch is pretty messy and not reviewable. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 0b7ff76d..1559d57 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -328,14 +328,6 @@ static const struct rtdBoard rtd520Boards[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(rtd520_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_RTD, 0x7520) }, - { PCI_DEVICE(PCI_VENDOR_ID_RTD, 0x4520) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, rtd520_pci_table); - /* * Useful for shorthand access to the particular board structure */ @@ -705,22 +697,6 @@ struct rtdPrivate { #define RtdDma1Status(dev) \ readb(devpriv->lcfg+LCFG_DMACSR1) -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attac/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int rtd_detach(struct comedi_device *dev); - -static struct comedi_driver rtd520Driver = { - .driver_name = DRV_NAME, - .module = THIS_MODULE, - .attach = rtd_attach, - .detach = rtd_detach, -}; - static int rtd_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); static int rtd_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, @@ -2348,10 +2324,13 @@ static int rtd_dio_insn_config(struct comedi_device *dev, return 1; } -/* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. - */ +static struct comedi_driver rtd520Driver = { + .driver_name = DRV_NAME, + .module = THIS_MODULE, + .attach = rtd_attach, + .detach = rtd_detach, +}; + static int __devinit rtd520Driver_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { @@ -2363,10 +2342,17 @@ static void __devexit rtd520Driver_pci_remove(struct pci_dev *dev) comedi_pci_auto_unconfig(dev); } +static DEFINE_PCI_DEVICE_TABLE(rtd520_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_RTD, 0x7520) }, + { PCI_DEVICE(PCI_VENDOR_ID_RTD, 0x4520) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, rtd520_pci_table); + static struct pci_driver rtd520Driver_pci_driver = { - .id_table = rtd520_pci_table, - .probe = &rtd520Driver_pci_probe, - .remove = __devexit_p(&rtd520Driver_pci_remove) + .id_table = rtd520_pci_table, + .probe = &rtd520Driver_pci_probe, + .remove = __devexit_p(&rtd520Driver_pci_remove) }; static int __init rtd520Driver_init_module(void) @@ -2380,14 +2366,13 @@ static int __init rtd520Driver_init_module(void) rtd520Driver_pci_driver.name = (char *)rtd520Driver.driver_name; return pci_register_driver(&rtd520Driver_pci_driver); } +module_init(rtd520Driver_init_module); static void __exit rtd520Driver_cleanup_module(void) { pci_unregister_driver(&rtd520Driver_pci_driver); comedi_driver_unregister(&rtd520Driver); } - -module_init(rtd520Driver_init_module); module_exit(rtd520Driver_cleanup_module); MODULE_AUTHOR("Comedi http://www.comedi.org"); -- cgit v0.10.2 From 69d7c49ea35cf3cba98549134ffec131c53dd865 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 14:52:53 -0700 Subject: staging: comedi: refactor rti800 driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c index 72042b8..9e082b3 100644 --- a/drivers/staging/comedi/drivers/rti800.c +++ b/drivers/staging/comedi/drivers/rti800.c @@ -138,39 +138,8 @@ struct rti800_board { int has_ao; }; -static const struct rti800_board boardtypes[] = { - {"rti800", 0}, - {"rti815", 1}, -}; - #define this_board ((const struct rti800_board *)dev->board_ptr) -static int rti800_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int rti800_detach(struct comedi_device *dev); -static struct comedi_driver driver_rti800 = { - .driver_name = "rti800", - .module = THIS_MODULE, - .attach = rti800_attach, - .detach = rti800_detach, - .num_names = ARRAY_SIZE(boardtypes), - .board_name = &boardtypes[0].name, - .offset = sizeof(struct rti800_board), -}; - -static int __init driver_rti800_init_module(void) -{ - return comedi_driver_register(&driver_rti800); -} - -static void __exit driver_rti800_cleanup_module(void) -{ - comedi_driver_unregister(&driver_rti800); -} - -module_init(driver_rti800_init_module); -module_exit(driver_rti800_cleanup_module); - static irqreturn_t rti800_interrupt(int irq, void *dev); struct rti800_private { @@ -487,6 +456,33 @@ static int rti800_detach(struct comedi_device *dev) return 0; } +static const struct rti800_board boardtypes[] = { + { "rti800", 0 }, + { "rti815", 1 }, +}; + +static struct comedi_driver driver_rti800 = { + .driver_name = "rti800", + .module = THIS_MODULE, + .attach = rti800_attach, + .detach = rti800_detach, + .num_names = ARRAY_SIZE(boardtypes), + .board_name = &boardtypes[0].name, + .offset = sizeof(struct rti800_board), +}; + +static int __init driver_rti800_init_module(void) +{ + return comedi_driver_register(&driver_rti800); +} +module_init(driver_rti800_init_module); + +static void __exit driver_rti800_cleanup_module(void) +{ + comedi_driver_unregister(&driver_rti800); +} +module_exit(driver_rti800_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From cb5f523779953d61221885988cecda0a2bc702cc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 14:48:28 -0700 Subject: staging: comedi: refactor rti802 driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c index f59cb11..21baf1a 100644 --- a/drivers/staging/comedi/drivers/rti802.c +++ b/drivers/staging/comedi/drivers/rti802.c @@ -47,29 +47,6 @@ Configuration Options: #define RTI802_DATALOW 1 #define RTI802_DATAHIGH 2 -static int rti802_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int rti802_detach(struct comedi_device *dev); -static struct comedi_driver driver_rti802 = { - .driver_name = "rti802", - .module = THIS_MODULE, - .attach = rti802_attach, - .detach = rti802_detach, -}; - -static int __init driver_rti802_init_module(void) -{ - return comedi_driver_register(&driver_rti802); -} - -static void __exit driver_rti802_cleanup_module(void) -{ - comedi_driver_unregister(&driver_rti802); -} - -module_init(driver_rti802_init_module); -module_exit(driver_rti802_cleanup_module); - struct rti802_private { enum { dac_2comp, dac_straight @@ -162,6 +139,25 @@ static int rti802_detach(struct comedi_device *dev) return 0; } +static struct comedi_driver driver_rti802 = { + .driver_name = "rti802", + .module = THIS_MODULE, + .attach = rti802_attach, + .detach = rti802_detach, +}; + +static int __init driver_rti802_init_module(void) +{ + return comedi_driver_register(&driver_rti802); +} +module_init(driver_rti802_init_module); + +static void __exit driver_rti802_cleanup_module(void) +{ + comedi_driver_unregister(&driver_rti802); +} +module_exit(driver_rti802_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From e9a4a7fb4cf632b43f1207395f2ae64ba5a64f65 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 14:45:19 -0700 Subject: staging: comedi: refactor s526 driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 2b34dae..ffe4362 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -230,287 +230,6 @@ struct s526_private { */ #define devpriv ((struct s526_private *)dev->private) -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int s526_detach(struct comedi_device *dev); -static struct comedi_driver driver_s526 = { - .driver_name = "s526", - .module = THIS_MODULE, - .attach = s526_attach, - .detach = s526_detach, -/* It is not necessary to implement the following members if you are - * writing a driver for a ISA PnP or PCI card */ - /* Most drivers will support multiple types of boards by - * having an array of board structures. These were defined - * in s526_boards[] above. Note that the element 'name' - * was first in the structure -- Comedi uses this fact to - * extract the name of the board without knowing any details - * about the structure except for its length. - * When a device is attached (by comedi_config), the name - * of the device is given to Comedi, and Comedi tries to - * match it by going through the list of board names. If - * there is a match, the address of the pointer is put - * into dev->board_ptr and driver->attach() is called. - * - * Note that these are not necessary if you can determine - * the type of board in software. ISA PnP, PCI, and PCMCIA - * devices are such boards. - */ - .board_name = &s526_boards[0].name, - .offset = sizeof(struct s526_board), - .num_names = ARRAY_SIZE(s526_boards), -}; - -static int s526_gpct_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); -static int s526_gpct_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int s526_gpct_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); -static int s526_ai_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int s526_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int s526_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int s526_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int s526_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int s526_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ -static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - int iobase; - int i, n; -/* short value; */ -/* int subdev_channel = 0; */ - union cmReg cmReg; - - printk(KERN_INFO "comedi%d: s526: ", dev->minor); - - iobase = it->options[0]; - if (!iobase || !request_region(iobase, S526_IOSIZE, thisboard->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]))); - } - ***/ - -/* - * Initialize dev->board_name. Note that we can use the "thisboard" - * macro now, since we just initialized it in the last line. - */ - dev->board_ptr = &s526_boards[0]; - - dev->board_name = thisboard->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; - -/* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - */ - dev->n_subdevices = 4; - if (alloc_subdevices(dev, dev->n_subdevices) < 0) - return -ENOMEM; - - s = dev->subdevices + 0; - /* 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 = thisboard->gpct_chans; - 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->insn_read = s526_ai_rinsn; - s->insn_config = s526_ai_insn_config; - - s = dev->subdevices + 2; - /* analog output subdevice */ - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE; - s->n_chan = 4; - s->maxdata = 0xffff; - s->range_table = &range_bipolar10; - s->insn_write = s526_ao_winsn; - s->insn_read = s526_ao_rinsn; - - s = dev->subdevices + 3; - /* digital i/o subdevice */ - if (thisboard->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)); - } - - 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))); - -#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; -} - -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int s526_detach(struct comedi_device *dev) -{ - printk(KERN_INFO "comedi%d: s526: remove\n", dev->minor); - - if (dev->iobase > 0) - release_region(dev->iobase, S526_IOSIZE); - - return 0; -} - static int s526_gpct_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -1023,21 +742,232 @@ static int s526_dio_insn_config(struct comedi_device *dev, return 1; } +static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + int iobase; + int i, n; +/* short value; */ +/* int subdev_channel = 0; */ + union cmReg cmReg; + + printk(KERN_INFO "comedi%d: s526: ", dev->minor); + + iobase = it->options[0]; + if (!iobase || !request_region(iobase, S526_IOSIZE, thisboard->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]))); + } + ***/ + +/* + * Initialize dev->board_name. Note that we can use the "thisboard" + * macro now, since we just initialized it in the last line. + */ + dev->board_ptr = &s526_boards[0]; + + dev->board_name = thisboard->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; + /* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. + * Allocate the subdevice structures. alloc_subdevice() is a + * convenient macro defined in comedidev.h. */ + dev->n_subdevices = 4; + if (alloc_subdevices(dev, dev->n_subdevices) < 0) + return -ENOMEM; + + s = dev->subdevices + 0; + /* 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 = thisboard->gpct_chans; + 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->insn_read = s526_ai_rinsn; + s->insn_config = s526_ai_insn_config; + + s = dev->subdevices + 2; + /* analog output subdevice */ + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->range_table = &range_bipolar10; + s->insn_write = s526_ao_winsn; + s->insn_read = s526_ao_rinsn; + + s = dev->subdevices + 3; + /* digital i/o subdevice */ + if (thisboard->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)); + } + + 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))); + +#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; +} + +static int s526_detach(struct comedi_device *dev) +{ + printk(KERN_INFO "comedi%d: s526: remove\n", dev->minor); + + if (dev->iobase > 0) + release_region(dev->iobase, S526_IOSIZE); + + return 0; +} + +static struct comedi_driver driver_s526 = { + .driver_name = "s526", + .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), +}; + static int __init driver_s526_init_module(void) { return comedi_driver_register(&driver_s526); } +module_init(driver_s526_init_module); static void __exit driver_s526_cleanup_module(void) { comedi_driver_unregister(&driver_s526); } - -module_init(driver_s526_init_module); module_exit(driver_s526_cleanup_module); MODULE_AUTHOR("Comedi http://www.comedi.org"); -- cgit v0.10.2 From cb1648b46c362d18e5bd7398fb6643071a3745bb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 27 Apr 2012 14:36:26 -0700 Subject: staging: comedi: refactor serial2002 driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index d880c2f..a034b10 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -43,20 +43,10 @@ Status: in development #include #include -/* - * 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 serial2002_board { const char *name; }; -static const struct serial2002_board serial2002_boards[] = { - { - .name = "serial2002"} -}; - /* * Useful for shorthand access to the particular board structure */ @@ -89,35 +79,6 @@ struct serial2002_private { */ #define devpriv ((struct serial2002_private *)dev->private) -static int serial2002_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int serial2002_detach(struct comedi_device *dev); -struct comedi_driver driver_serial2002 = { - .driver_name = "serial2002", - .module = THIS_MODULE, - .attach = serial2002_attach, - .detach = serial2002_detach, - .board_name = &serial2002_boards[0].name, - .offset = sizeof(struct serial2002_board), - .num_names = ARRAY_SIZE(serial2002_boards), -}; - -static int serial2002_di_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int serial2002_do_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int serial2002_ai_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int serial2002_ao_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int serial2002_ao_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - struct serial_data { enum { is_invalid, is_digital, is_channel } kind; int index; @@ -901,17 +862,32 @@ static int serial2002_detach(struct comedi_device *dev) return 0; } +static const struct serial2002_board serial2002_boards[] = { + { + .name = "serial2002" + }, +}; + +struct comedi_driver driver_serial2002 = { + .driver_name = "serial2002", + .module = THIS_MODULE, + .attach = serial2002_attach, + .detach = serial2002_detach, + .board_name = &serial2002_boards[0].name, + .offset = sizeof(struct serial2002_board), + .num_names = ARRAY_SIZE(serial2002_boards), +}; + static int __init driver_serial2002_init_module(void) { return comedi_driver_register(&driver_serial2002); } +module_init(driver_serial2002_init_module); static void __exit driver_serial2002_cleanup_module(void) { comedi_driver_unregister(&driver_serial2002); } - -module_init(driver_serial2002_init_module); module_exit(driver_serial2002_cleanup_module); MODULE_AUTHOR("Comedi http://www.comedi.org"); -- cgit v0.10.2 From ed7dcb47f6f83923476942ad08be4fd6c2fef8b4 Mon Sep 17 00:00:00 2001 From: Tomas Melin Date: Sat, 28 Apr 2012 18:50:46 +0300 Subject: Staging: Comedi adv_pci1710 : Corrected over 80 column warnings Various comments and code lines longer than 80 chars fixed in file adv_pci1710.c. Signed-off-by: Tomas Melin Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index dc762e7..9eaae0d 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -674,7 +674,9 @@ static void interrupt_pci1710_every_sample(void *d) s->async->buf_int_count, s->async->buf_int_ptr, s->async->buf_user_count, s->async->buf_user_ptr); DPRINTK("adv_pci1710 EDBG: EOS2\n"); - if ((!devpriv->neverending_ai) && (devpriv->ai_act_scan >= devpriv->ai_scans)) { /* all data sampled */ + if ((!devpriv->neverending_ai) && + (devpriv->ai_act_scan >= devpriv->ai_scans)) { + /* all data sampled */ pci171x_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA; comedi_event(dev, s); @@ -802,8 +804,8 @@ static irqreturn_t interrupt_service_pci1710(int irq, void *d) irq); if (!dev->attached) /* is device attached? */ return IRQ_NONE; /* no, exit */ - - if (!(inw(dev->iobase + PCI171x_STATUS) & Status_IRQ)) /* is this interrupt from our board? */ + /* is this interrupt from our board? */ + if (!(inw(dev->iobase + PCI171x_STATUS) & Status_IRQ)) return IRQ_NONE; /* no, exit */ DPRINTK("adv_pci1710 EDBG: interrupt_service_pci1710() ST: %4x\n", @@ -812,7 +814,7 @@ static irqreturn_t interrupt_service_pci1710(int irq, void *d) if (devpriv->ai_et) { /* Switch from initial TRIG_EXT to TRIG_xxx. */ devpriv->ai_et = 0; devpriv->CntrlReg &= Control_CNT0; - devpriv->CntrlReg |= Control_SW; /* set software trigger */ + devpriv->CntrlReg |= Control_SW; /* set software trigger */ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); devpriv->CntrlReg = devpriv->ai_et_CntrlReg; outb(0, dev->iobase + PCI171x_CLRFIFO); @@ -863,7 +865,8 @@ static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev, devpriv->neverending_ai = 0; devpriv->CntrlReg &= Control_CNT0; - if ((devpriv->ai_flags & TRIG_WAKE_EOS)) { /* don't we want wake up every scan? devpriv->ai_eos=1; */ + /* don't we want wake up every scan? devpriv->ai_eos=1; */ + if ((devpriv->ai_flags & TRIG_WAKE_EOS)) { devpriv->ai_eos = 1; } else { devpriv->CntrlReg |= Control_ONEFH; @@ -980,13 +983,13 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, #ifdef PCI171X_EXTDEBUG pci171x_cmdtest_out(1, cmd); #endif - DPRINTK - ("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=1\n", - err); + DPRINTK( + "adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=1\n", + err); return 1; } - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* step2: make sure trigger srcs are unique and mutually compatible */ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) { cmd->start_src = TRIG_NOW; @@ -1013,9 +1016,9 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, #ifdef PCI171X_EXTDEBUG pci171x_cmdtest_out(2, cmd); #endif - DPRINTK - ("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=2\n", - err); + DPRINTK( + "adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=2\n", + err); return 2; } @@ -1063,9 +1066,9 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, #ifdef PCI171X_EXTDEBUG pci171x_cmdtest_out(3, cmd); #endif - DPRINTK - ("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=3\n", - err); + DPRINTK( + "adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=3\n", + err); return 3; } -- cgit v0.10.2 From 3c5510ba5091f3d7be338875c84451b07a3dd498 Mon Sep 17 00:00:00 2001 From: Ravishankar Karkala Mallikarjunayya Date: Thu, 26 Apr 2012 15:32:17 +0530 Subject: Staging: comedi: fix line over 80 character issue in cb_pcidda.c This is a patch to the cb_pcidda.c file that fixes up a line over 80 character warning found by the checkpatch.pl tool Signed-off-by: Ravishankar Karkala Mallikarjunayya Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 41e06c1..38efb4a 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -51,9 +51,12 @@ Please report success/failure with other different cards to #include "comedi_pci.h" #include "8255.h" -#define PCI_VENDOR_ID_CB 0x1307 /* PCI vendor number of ComputerBoards */ + +/* PCI vendor number of ComputerBoards */ +#define PCI_VENDOR_ID_CB 0x1307 #define EEPROM_SIZE 128 /* number of entries in eeprom */ -#define MAX_AO_CHANNELS 8 /* maximum number of ao channels for supported boards */ +/* maximum number of ao channels for supported boards */ +#define MAX_AO_CHANNELS 8 /* PCI-DDA base addresses */ #define DIGITALIO_BADRINDEX 2 @@ -94,20 +97,26 @@ Please report success/failure with other different cards to #define DACALIBRATION1 4 /* D/A CALIBRATION REGISTER 1 */ /* write bits */ -#define SERIAL_IN_BIT 0x1 /* serial data input for eeprom, caldacs, reference dac */ +/* serial data input for eeprom, caldacs, reference dac */ +#define SERIAL_IN_BIT 0x1 #define CAL_CHANNEL_MASK (0x7 << 1) #define CAL_CHANNEL_BITS(channel) (((channel) << 1) & CAL_CHANNEL_MASK) /* read bits */ #define CAL_COUNTER_MASK 0x1f -#define CAL_COUNTER_OVERFLOW_BIT 0x20 /* calibration counter overflow status bit */ -#define AO_BELOW_REF_BIT 0x40 /* analog output is less than reference dac voltage */ +/* calibration counter overflow status bit */ +#define CAL_COUNTER_OVERFLOW_BIT 0x20 +/* analog output is less than reference dac voltage */ +#define AO_BELOW_REF_BIT 0x40 #define SERIAL_OUT_BIT 0x80 /* serial data out, for reading from eeprom */ #define DACALIBRATION2 6 /* D/A CALIBRATION REGISTER 2 */ #define SELECT_EEPROM_BIT 0x1 /* send serial data in to eeprom */ -#define DESELECT_REF_DAC_BIT 0x2 /* don't send serial data to MAX542 reference dac */ -#define DESELECT_CALDAC_BIT(n) (0x4 << (n)) /* don't send serial data to caldac n */ -#define DUMMY_BIT 0x40 /* manual says to set this bit with no explanation */ +/* don't send serial data to MAX542 reference dac */ +#define DESELECT_REF_DAC_BIT 0x2 +/* don't send serial data to caldac n */ +#define DESELECT_CALDAC_BIT(n) (0x4 << (n)) +/* manual says to set this bit with no explanation */ +#define DUMMY_BIT 0x40 #define DADATA 8 /* FIRST D/A DATA REGISTER (0) */ @@ -212,9 +221,12 @@ MODULE_DEVICE_TABLE(pci, cb_pcidda_pci_table); */ #define thisboard ((const struct cb_pcidda_board *)dev->board_ptr) -/* 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. */ +/* + * 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 cb_pcidda_private { int data; @@ -227,8 +239,10 @@ struct cb_pcidda_private { /* unsigned long control_status; */ /* unsigned long adc_fifo; */ - unsigned int dac_cal1_bits; /* bits last written to da calibration register 1 */ - unsigned int ao_range[MAX_AO_CHANNELS]; /* current range settings for output channels */ + /* bits last written to da calibration register 1 */ + unsigned int dac_cal1_bits; + /* current range settings for output channels */ + unsigned int ao_range[MAX_AO_CHANNELS]; u16 eeprom_data[EEPROM_SIZE]; /* software copy of board's eeprom */ }; @@ -377,7 +391,8 @@ found: dev_dbg(dev->hw_dev, "eeprom:\n"); for (index = 0; index < EEPROM_SIZE; index++) { devpriv->eeprom_data[index] = cb_pcidda_read_eeprom(dev, index); - dev_dbg(dev->hw_dev, "%i:0x%x\n", index, devpriv->eeprom_data[index]); + dev_dbg(dev->hw_dev, "%i:0x%x\n", index, + devpriv->eeprom_data[index]); } /* set calibrations dacs */ @@ -484,7 +499,10 @@ static int cb_pcidda_ai_cmdtest(struct comedi_device *dev, if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* + * step 2: make sure trigger sources are unique and mutually + * compatible + */ /* note that mutual compatibility is not an issue here */ if (cmd->scan_begin_src != TRIG_TIMER @@ -696,8 +714,10 @@ static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev, unsigned int i; unsigned int cal2_bits; unsigned int value; - const int max_num_caldacs = 4; /* one caldac for every two dac channels */ - const int read_instruction = 0x6; /* bits to send to tell eeprom we want to read */ + /* one caldac for every two dac channels */ + const int max_num_caldacs = 4; + /* bits to send to tell eeprom we want to read */ + const int read_instruction = 0x6; const int instruction_length = 3; const int address_length = 8; @@ -729,9 +749,11 @@ static void cb_pcidda_write_caldac(struct comedi_device *dev, { unsigned int cal2_bits; unsigned int i; - const int num_channel_bits = 3; /* caldacs use 3 bit channel specification */ + /* caldacs use 3 bit channel specification */ + const int num_channel_bits = 3; const int num_caldac_bits = 8; /* 8 bit calibration dacs */ - const int max_num_caldacs = 4; /* one caldac for every two dac channels */ + /* one caldac for every two dac channels */ + const int max_num_caldacs = 4; /* write 3 bit channel */ cb_pcidda_serial_out(dev, channel, num_channel_bits); @@ -790,14 +812,20 @@ static unsigned int offset_eeprom_address(unsigned int ao_channel, return 0x7 + 2 * range + 12 * ao_channel; } -/* returns eeprom address that provides gain calibration for given ao channel and range */ +/* + * returns eeprom address that provides gain calibration for given ao + * channel and range + */ static unsigned int gain_eeprom_address(unsigned int ao_channel, unsigned int range) { return 0x8 + 2 * range + 12 * ao_channel; } -/* returns upper byte of eeprom entry, which gives the coarse adjustment values */ +/* + * returns upper byte of eeprom entry, which gives the coarse adjustment + * values + */ static unsigned int eeprom_coarse_byte(unsigned int word) { return (word >> 8) & 0xff; @@ -815,7 +843,7 @@ static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel, { unsigned int coarse_offset, fine_offset, coarse_gain, fine_gain; - /* remember range so we can tell when we need to readjust calibration */ + /* remember range so we can tell when we need to readjust calibration */ devpriv->ao_range[channel] = range; /* get values from eeprom data */ -- cgit v0.10.2 From ac971c948598b1ca6638ae7a89d3e237b90ad02b Mon Sep 17 00:00:00 2001 From: Ravishankar Karkala Mallikarjunayya Date: Thu, 26 Apr 2012 15:32:18 +0530 Subject: Staging: comedi: fix line over 80 character issue in daqboard2000.c This is a patch to the daqboard2000.c file that fixes up a line over 80 character warning found by the checkpatch.pl tool. Signed-off-by: Ravishankar Karkala Mallikarjunayya Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 952b081..480f418 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -411,9 +411,12 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev, DAQBOARD2000_AcqResetScanListFifo | DAQBOARD2000_AcqResetResultsFifo | DAQBOARD2000_AcqResetConfigPipe; - /* If pacer clock is not set to some high value (> 10 us), we - risk multiple samples to be put into the result FIFO. */ - fpga->acqPacerClockDivLow = 1000000; /* 1 second, should be long enough */ + /* + * 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; gain = CR_RANGE(insn->chanspec); -- cgit v0.10.2 From 190908ba6dd1e17f00cb7f403d31c19feeeb63bf Mon Sep 17 00:00:00 2001 From: Ravishankar Karkala Mallikarjunayya Date: Thu, 26 Apr 2012 15:32:19 +0530 Subject: Staging: comedi: fix line over 80 character issue in cb_pcimdas.c. This is a patch to the cb_pcimdas.c file that fixes up a line over 80 character warning found by the checkpatch.pl tool. Signed-off-by: Ravishankar Karkala Mallikarjunayya Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index f92b800..842d99d 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -139,9 +139,12 @@ MODULE_DEVICE_TABLE(pci, cb_pcimdas_pci_table); */ #define thisboard ((const struct cb_pcimdas_board *)dev->board_ptr) -/* 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. */ +/* + * 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 cb_pcimdas_private { int data; @@ -317,7 +320,8 @@ found: s->subdev_flags = SDF_WRITABLE; s->n_chan = thisboard->ao_nchan; s->maxdata = 1 << thisboard->ao_bits; - s->range_table = &range_unknown; /* ranges are hardware settable, but not software readable. */ + /* ranges are hardware settable, but not software readable. */ + s->range_table = &range_unknown; s->insn_write = &cb_pcimdas_ao_winsn; s->insn_read = &cb_pcimdas_ao_rinsn; @@ -402,7 +406,10 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, outb(0x01, devpriv->BADR3 + 6); /* set bursting off, conversions on */ outb(0x00, devpriv->BADR3 + 7); /* set range to 10V. UP/BP is controlled by a switch on the board */ - /* write channel limits to multiplexer, set Low (bits 0-3) and High (bits 4-7) channels to chan. */ + /* + * write channel limits to multiplexer, set Low (bits 0-3) and + * High (bits 4-7) channels to chan. + */ chanlims = chan | (chan << 4); outb(chanlims, devpriv->BADR3 + 0); -- cgit v0.10.2 From 949fd38c7b22168bc16fea100a51c8d4a3eab144 Mon Sep 17 00:00:00 2001 From: Ravishankar Karkala Mallikarjunayya Date: Thu, 26 Apr 2012 15:32:20 +0530 Subject: Staging: comedi: fix line over 80 character issue in ni_at_a2150.c This is a patch to the ni_at_a2150.c file that fixes up a line over 80 character warning found by the checkpatch.pl tool. Signed-off-by: Ravishankar Karkala Mallikarjunayya Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index c25e44c..4fc469d 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -539,7 +539,10 @@ static int a2150_ai_cmdtest(struct comedi_device *dev, if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* + * step 2: make sure trigger sources are unique and mutually + * compatible + */ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) err++; @@ -771,7 +774,10 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, /* start acquisition for soft trigger */ outw(0, dev->iobase + FIFO_START_REG); - /* there is a 35.6 sample delay for data to get through the antialias filter */ + /* + * there is a 35.6 sample delay for data to get through the + * antialias filter + */ for (n = 0; n < filter_delay; n++) { for (i = 0; i < timeout; i++) { if (inw(dev->iobase + STATUS_REG) & FNE_BIT) @@ -812,8 +818,10 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, return n; } -/* sets bits in devpriv->clock_bits to nearest approximation of requested period, - * adjusts requested period to actual timing. */ +/* + * sets bits in devpriv->clock_bits to nearest approximation of requested + * period, adjusts requested period to actual timing. + */ static int a2150_get_timing(struct comedi_device *dev, unsigned int *period, int flags) { -- cgit v0.10.2 From f316983fe033ba090b2f82fb9912aae9412d2372 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 30 Apr 2012 16:06:12 +0200 Subject: staging: iio: adc: convert ADI drivers to use kfifo. sw_ring is depreciated and therefore won't move out of staging. Prerequisite for lifting affected drivers is to convert them to kfifo. Update copyright. Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 9ae5467..2490dd2 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -25,7 +25,7 @@ config AD7606 depends on GPIOLIB select IIO_BUFFER select IIO_TRIGGER - select IIO_SW_RING + select IIO_KFIFO_BUF help Say yes here to build support for Analog Devices: ad7606, ad7606-6, ad7606-4 analog to digital converters (ADC). @@ -63,7 +63,7 @@ config AD799X_RING_BUFFER bool "Analog Devices AD799x: use ring buffer" depends on AD799X select IIO_BUFFER - select IIO_SW_RING + select IIO_KFIFO_BUF help Say yes here to include ring buffer support in the AD799X ADC driver. @@ -72,7 +72,7 @@ config AD7476 tristate "Analog Devices AD7475/6/7/8 AD7466/7/8 and AD7495 ADC driver" depends on SPI select IIO_BUFFER - select IIO_SW_RING + select IIO_KFIFO_BUF select IIO_TRIGGER help Say yes here to build support for Analog Devices @@ -87,7 +87,7 @@ config AD7887 tristate "Analog Devices AD7887 ADC driver" depends on SPI select IIO_BUFFER - select IIO_SW_RING + select IIO_KFIFO_BUF select IIO_TRIGGER help Say yes here to build support for Analog Devices @@ -113,7 +113,7 @@ config AD7793 tristate "Analog Devices AD7792 AD7793 ADC driver" depends on SPI select IIO_BUFFER - select IIO_SW_RING + select IIO_KFIFO_BUF select IIO_TRIGGER help Say yes here to build support for Analog Devices @@ -135,7 +135,7 @@ config AD7192 tristate "Analog Devices AD7190 AD7192 AD7195 ADC driver" depends on SPI select IIO_BUFFER - select IIO_SW_RING + select IIO_KFIFO_BUF select IIO_TRIGGER help Say yes here to build support for Analog Devices AD7190, diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 7b44705..d5655e3 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -1,7 +1,7 @@ /* * AD7190 AD7192 AD7195 SPI ADC driver * - * Copyright 2011 Analog Devices Inc. + * Copyright 2011-2012 Analog Devices Inc. * * Licensed under the GPL-2. */ @@ -20,7 +20,7 @@ #include #include #include -#include "../ring_sw.h" +#include #include #include @@ -544,7 +544,7 @@ static int ad7192_register_ring_funcs_and_init(struct iio_dev *indio_dev) { int ret; - indio_dev->buffer = iio_sw_rb_allocate(indio_dev); + indio_dev->buffer = iio_kfifo_allocate(indio_dev); if (!indio_dev->buffer) { ret = -ENOMEM; goto error_ret; @@ -557,7 +557,7 @@ static int ad7192_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->id); if (indio_dev->pollfunc == NULL) { ret = -ENOMEM; - goto error_deallocate_sw_rb; + goto error_deallocate_kfifo; } /* Ring buffer functions - here trigger setup related */ @@ -567,8 +567,8 @@ static int ad7192_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->modes |= INDIO_BUFFER_TRIGGERED; return 0; -error_deallocate_sw_rb: - iio_sw_rb_free(indio_dev->buffer); +error_deallocate_kfifo: + iio_kfifo_free(indio_dev->buffer); error_ret: return ret; } @@ -576,7 +576,7 @@ error_ret: static void ad7192_ring_cleanup(struct iio_dev *indio_dev) { iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); + iio_kfifo_free(indio_dev->buffer); } /** diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c index 943caa3..908a3e5 100644 --- a/drivers/staging/iio/adc/ad7298_ring.c +++ b/drivers/staging/iio/adc/ad7298_ring.c @@ -1,7 +1,7 @@ /* * AD7298 SPI ADC driver * - * Copyright 2011 Analog Devices Inc. + * Copyright 2011-2012 Analog Devices Inc. * * Licensed under the GPL-2. */ @@ -13,7 +13,7 @@ #include #include -#include "../ring_sw.h" +#include #include #include "ad7298.h" @@ -118,7 +118,7 @@ int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev) { int ret; - indio_dev->buffer = iio_sw_rb_allocate(indio_dev); + indio_dev->buffer = iio_kfifo_allocate(indio_dev); if (!indio_dev->buffer) { ret = -ENOMEM; goto error_ret; @@ -132,7 +132,7 @@ int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev) if (indio_dev->pollfunc == NULL) { ret = -ENOMEM; - goto error_deallocate_sw_rb; + goto error_deallocate_kfifo; } /* Ring buffer functions - here trigger setup related */ @@ -143,8 +143,8 @@ int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->modes |= INDIO_BUFFER_TRIGGERED; return 0; -error_deallocate_sw_rb: - iio_sw_rb_free(indio_dev->buffer); +error_deallocate_kfifo: + iio_kfifo_free(indio_dev->buffer); error_ret: return ret; } @@ -152,5 +152,5 @@ error_ret: void ad7298_ring_cleanup(struct iio_dev *indio_dev) { iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); + iio_kfifo_free(indio_dev->buffer); } diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c index 51403892..383611b 100644 --- a/drivers/staging/iio/adc/ad7476_ring.c +++ b/drivers/staging/iio/adc/ad7476_ring.c @@ -1,5 +1,5 @@ /* - * Copyright 2010 Analog Devices Inc. + * Copyright 2010-2012 Analog Devices Inc. * Copyright (C) 2008 Jonathan Cameron * * Licensed under the GPL-2 or later. @@ -15,7 +15,7 @@ #include #include -#include "../ring_sw.h" +#include #include #include "ad7476.h" @@ -63,7 +63,7 @@ int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev) struct ad7476_state *st = iio_priv(indio_dev); int ret = 0; - indio_dev->buffer = iio_sw_rb_allocate(indio_dev); + indio_dev->buffer = iio_kfifo_allocate(indio_dev); if (!indio_dev->buffer) { ret = -ENOMEM; goto error_ret; @@ -78,7 +78,7 @@ int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->id); if (indio_dev->pollfunc == NULL) { ret = -ENOMEM; - goto error_deallocate_sw_rb; + goto error_deallocate_kfifo; } /* Ring buffer functions - here trigger setup related */ @@ -89,8 +89,8 @@ int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->modes |= INDIO_BUFFER_TRIGGERED; return 0; -error_deallocate_sw_rb: - iio_sw_rb_free(indio_dev->buffer); +error_deallocate_kfifo: + iio_kfifo_free(indio_dev->buffer); error_ret: return ret; } @@ -98,5 +98,5 @@ error_ret: void ad7476_ring_cleanup(struct iio_dev *indio_dev) { iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); + iio_kfifo_free(indio_dev->buffer); } diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c index 3dd9602..24ce8fc 100644 --- a/drivers/staging/iio/adc/ad7606_ring.c +++ b/drivers/staging/iio/adc/ad7606_ring.c @@ -1,5 +1,5 @@ /* - * Copyright 2011 Analog Devices Inc. + * Copyright 2011-2012 Analog Devices Inc. * * Licensed under the GPL-2. * @@ -13,7 +13,7 @@ #include #include -#include "../ring_sw.h" +#include #include #include "ad7606.h" @@ -102,7 +102,7 @@ int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev) struct ad7606_state *st = iio_priv(indio_dev); int ret; - indio_dev->buffer = iio_sw_rb_allocate(indio_dev); + indio_dev->buffer = iio_kfifo_allocate(indio_dev); if (!indio_dev->buffer) { ret = -ENOMEM; goto error_ret; @@ -117,13 +117,13 @@ int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->id); if (indio_dev->pollfunc == NULL) { ret = -ENOMEM; - goto error_deallocate_sw_rb; + goto error_deallocate_kfifo; } /* Ring buffer functions - here trigger setup related */ indio_dev->setup_ops = &ad7606_ring_setup_ops; - indio_dev->buffer->scan_timestamp = true ; + indio_dev->buffer->scan_timestamp = true; INIT_WORK(&st->poll_work, &ad7606_poll_bh_to_ring); @@ -131,8 +131,8 @@ int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->modes |= INDIO_BUFFER_TRIGGERED; return 0; -error_deallocate_sw_rb: - iio_sw_rb_free(indio_dev->buffer); +error_deallocate_kfifo: + iio_kfifo_free(indio_dev->buffer); error_ret: return ret; } @@ -140,5 +140,5 @@ error_ret: void ad7606_ring_cleanup(struct iio_dev *indio_dev) { iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); + iio_kfifo_free(indio_dev->buffer); } diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index 8ffdd80..61df796 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -1,7 +1,7 @@ /* * AD7792/AD7793 SPI ADC driver * - * Copyright 2011 Analog Devices Inc. + * Copyright 2011-2012 Analog Devices Inc. * * Licensed under the GPL-2. */ @@ -21,7 +21,7 @@ #include #include #include -#include "../ring_sw.h" +#include #include #include @@ -409,7 +409,7 @@ static int ad7793_register_ring_funcs_and_init(struct iio_dev *indio_dev) { int ret; - indio_dev->buffer = iio_sw_rb_allocate(indio_dev); + indio_dev->buffer = iio_kfifo_allocate(indio_dev); if (!indio_dev->buffer) { ret = -ENOMEM; goto error_ret; @@ -422,7 +422,7 @@ static int ad7793_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->id); if (indio_dev->pollfunc == NULL) { ret = -ENOMEM; - goto error_deallocate_sw_rb; + goto error_deallocate_kfifo; } /* Ring buffer functions - here trigger setup related */ @@ -432,8 +432,8 @@ static int ad7793_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->modes |= INDIO_BUFFER_TRIGGERED; return 0; -error_deallocate_sw_rb: - iio_sw_rb_free(indio_dev->buffer); +error_deallocate_kfifo: + iio_kfifo_free(indio_dev->buffer); error_ret: return ret; } @@ -441,7 +441,7 @@ error_ret: static void ad7793_ring_cleanup(struct iio_dev *indio_dev) { iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); + iio_kfifo_free(indio_dev->buffer); } /** diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c index f1846db..fd91384 100644 --- a/drivers/staging/iio/adc/ad7887_ring.c +++ b/drivers/staging/iio/adc/ad7887_ring.c @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Analog Devices Inc. + * Copyright 2010-2012 Analog Devices Inc. * Copyright (C) 2008 Jonathan Cameron * * Licensed under the GPL-2. @@ -14,7 +14,7 @@ #include #include -#include "../ring_sw.h" +#include #include #include "ad7887.h" @@ -114,7 +114,7 @@ int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev) { int ret; - indio_dev->buffer = iio_sw_rb_allocate(indio_dev); + indio_dev->buffer = iio_kfifo_allocate(indio_dev); if (!indio_dev->buffer) { ret = -ENOMEM; goto error_ret; @@ -127,7 +127,7 @@ int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->id); if (indio_dev->pollfunc == NULL) { ret = -ENOMEM; - goto error_deallocate_sw_rb; + goto error_deallocate_kfifo; } /* Ring buffer functions - here trigger setup related */ indio_dev->setup_ops = &ad7887_ring_setup_ops; @@ -136,8 +136,8 @@ int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->modes |= INDIO_BUFFER_TRIGGERED; return 0; -error_deallocate_sw_rb: - iio_sw_rb_free(indio_dev->buffer); +error_deallocate_kfifo: + iio_kfifo_free(indio_dev->buffer); error_ret: return ret; } @@ -145,5 +145,5 @@ error_ret: void ad7887_ring_cleanup(struct iio_dev *indio_dev) { iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); + iio_kfifo_free(indio_dev->buffer); } diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c index 18366b5..1c7ff44 100644 --- a/drivers/staging/iio/adc/ad799x_ring.c +++ b/drivers/staging/iio/adc/ad799x_ring.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Michael Hennerich, Analog Devices Inc. + * Copyright (C) 2010-2012 Michael Hennerich, Analog Devices Inc. * Copyright (C) 2008-2010 Jonathan Cameron * * This program is free software; you can redistribute it and/or modify @@ -18,7 +18,7 @@ #include #include -#include "../ring_sw.h" +#include #include #include "ad799x.h" @@ -120,7 +120,7 @@ int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev) { int ret = 0; - indio_dev->buffer = iio_sw_rb_allocate(indio_dev); + indio_dev->buffer = iio_kfifo_allocate(indio_dev); if (!indio_dev->buffer) { ret = -ENOMEM; goto error_ret; @@ -134,7 +134,7 @@ int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->id); if (indio_dev->pollfunc == NULL) { ret = -ENOMEM; - goto error_deallocate_sw_rb; + goto error_deallocate_kfifo; } /* Ring buffer functions - here trigger setup related */ @@ -145,8 +145,8 @@ int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->modes |= INDIO_BUFFER_TRIGGERED; return 0; -error_deallocate_sw_rb: - iio_sw_rb_free(indio_dev->buffer); +error_deallocate_kfifo: + iio_kfifo_free(indio_dev->buffer); error_ret: return ret; } @@ -154,5 +154,5 @@ error_ret: void ad799x_ring_cleanup(struct iio_dev *indio_dev) { iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); + iio_kfifo_free(indio_dev->buffer); } -- cgit v0.10.2 From 589b3d06fd159774f9f5c3639d8d5d938670c019 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 30 Apr 2012 07:41:36 -0700 Subject: staging: rtl8192u Fix typos. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192u/r8180_93cx6.c b/drivers/staging/rtl8192u/r8180_93cx6.c index 8878cfe..0e8ff75 100644 --- a/drivers/staging/rtl8192u/r8180_93cx6.c +++ b/drivers/staging/rtl8192u/r8180_93cx6.c @@ -14,7 +14,7 @@ Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. - We want to tanks the Authors of those projects and the Ndiswrapper + We want to thanks the Authors of those projects and the Ndiswrapper project Authors. */ diff --git a/drivers/staging/rtl8192u/r8180_93cx6.h b/drivers/staging/rtl8192u/r8180_93cx6.h index fb3ac97..3527d32 100644 --- a/drivers/staging/rtl8192u/r8180_93cx6.h +++ b/drivers/staging/rtl8192u/r8180_93cx6.h @@ -7,7 +7,7 @@ Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - We want to tanks the Authors of such projects and the Ndiswrapper project Authors. + We want to thanks the Authors of such projects and the Ndiswrapper project Authors. */ /*This files contains card eeprom (93c46 or 93c56) programming routines*/ diff --git a/drivers/staging/rtl8192u/r8192U.h b/drivers/staging/rtl8192u/r8192U.h index 43d459d..adeb724 100644 --- a/drivers/staging/rtl8192u/r8192U.h +++ b/drivers/staging/rtl8192u/r8192U.h @@ -11,7 +11,7 @@ Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - We want to tanks the Authors of those projects and the Ndiswrapper + We want to thanks the Authors of those projects and the Ndiswrapper project Authors. */ @@ -98,7 +98,7 @@ do { if(rt_global_debug_component & component) \ #define COMP_INIT BIT2 // during driver initialization / halt / reset. -#define COMP_RECV BIT3 // Reveive part data path. +#define COMP_RECV BIT3 // Revive part data path. #define COMP_SEND BIT4 // Send part path. #define COMP_IO BIT5 // I/O Related. Added by Annie, 2006-03-02. #define COMP_POWER BIT6 // 802.11 Power Save mode or System/Device Power state related. @@ -322,7 +322,7 @@ typedef struct _tx_fwinfo_819x_usb { u8 TxSubCarrier:2; // This is used for legacy OFDM rate only. u8 STBC:2; u8 AllowAggregation:1; - u8 RtsHT:1; //Interpre RtsRate field as high throughput data rate + u8 RtsHT:1; //Interprete RtsRate field as high throughput data rate u8 RtsShort:1; //Short PLCP for CCK, or short GI for 11n MCS u8 RtsBandwidth:1; // This is used for HT MCS rate only. u8 RtsSubcarrier:2; // This is used for legacy OFDM rate only. diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 9c00865..be86045 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -203,7 +203,7 @@ static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv) { Dot11d_Init(ieee); ieee->bGlobalDomain = false; - //acturally 8225 & 8256 rf chip only support B,G,24N mode + //actually 8225 & 8256 rf chip only support B,G,24N mode if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256)) { min_chan = 1; @@ -1103,7 +1103,7 @@ inline u16 rtl8192_rate2rate(short rate) } -/* The protype of rx_isr has changed since one verion of Linux Kernel */ +/* The prototype of rx_isr has changed since one version of Linux Kernel */ static void rtl8192_rx_isr(struct urb *urb) { struct sk_buff *skb = (struct sk_buff *) urb->context; @@ -1476,7 +1476,7 @@ static void rtl8192_tx_isr(struct urb *tx_urb) if(tcb_desc->queue_index != TXCMD_QUEUE) { if(tx_urb->status == 0) { dev->trans_start = jiffies; - // As act as station mode, destion shall be unicast address. + // As act as station mode, destination shall be unicast address. //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom); //priv->ieee80211->stats.tx_packets++; priv->stats.txoktotal++; @@ -1522,13 +1522,13 @@ static void rtl8192_tx_isr(struct urb *tx_urb) else if ((skb_queue_len(&priv->ieee80211->skb_drv_aggQ[queue_index])!= 0)&&\ (!(priv->ieee80211->queue_stop))) { // Tx Driver Aggregation process - /* The driver will aggregation the packets according to the following stets + /* The driver will aggregation the packets according to the following stats * 1. check whether there's tx irq available, for it's a completion return * function, it should contain enough tx irq; - * 2. check pakcet type; + * 2. check packet type; * 3. initialize sendlist, check whether the to-be send packet no greater than 1 - * 4. aggregation the packets, and fill firmware info and tx desc to it, etc. - * 5. check whehter the packet could be sent, otherwise just insert to wait head + * 4. aggregates the packets, and fill firmware info and tx desc to it, etc. + * 5. check whether the packet could be sent, otherwise just insert to wait head * */ skb = skb_dequeue(&priv->ieee80211->skb_drv_aggQ[queue_index]); if(!check_nic_enough_desc(dev, queue_index)) { @@ -2447,7 +2447,7 @@ static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv, return 0; } -/* handle manage frame frame beacon and probe response */ +/* handle and manage frame from beacon and probe response */ static int rtl8192_handle_beacon(struct net_device * dev, struct ieee80211_beacon * beacon, struct ieee80211_network * network) @@ -2625,7 +2625,7 @@ bool GetHalfNmodeSupportByAPs819xUsb(struct net_device* dev) void rtl8192_refresh_supportrate(struct r8192_priv* priv) { struct ieee80211_device* ieee = priv->ieee80211; - //we donot consider set support rate for ABG mode, only HT MCS rate is set here. + //we do not consider set support rate for ABG mode, only HT MCS rate is set here. if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G) { memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16); @@ -2780,10 +2780,10 @@ static void rtl8192_init_priv_variable(struct net_device* dev) priv->TransmitConfig = // TCR_DurProcMode | //for RTL8185B, duration setting by HW //? TCR_DISReqQsize | - (TCR_MXDMA_2048<ShortRetryLimit<LongRetryLimit<bInHctTest) pHalData->ReceiveConfig = pHalData->CSMethod | @@ -3437,7 +3437,7 @@ if(Adapter->ResetProgress == RESET_TYPE_NORESET) { // User disable RF via registry. RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n")); MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW); - // Those action will be discard in MgntActSet_RF_State because off the same state + // Those action will be discard in MgntActSet_RF_State because of the same state for(eRFPath = 0; eRFPath NumTotalRFPath; eRFPath++) PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0); } @@ -3458,7 +3458,7 @@ if(Adapter->ResetProgress == RESET_TYPE_NORESET) if(pHalData->eRFPowerState == eRfOff) { MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason); - // Those action will be discard in MgntActSet_RF_State because off the same state + // Those action will be discard in MgntActSet_RF_State because of the same state for(eRFPath = 0; eRFPath NumTotalRFPath; eRFPath++) PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0); } @@ -3586,7 +3586,7 @@ TxCheckStuck(struct net_device *dev) //unsigned long flags; // - // Decide Stuch threshold according to current power save mode + // Decide such threshold according to current power save mode // // RT_TRACE(COMP_RESET, " ==> TxCheckStuck()\n"); @@ -3745,7 +3745,7 @@ rtl819x_ifcheck_resetornot(struct net_device *dev) // Driver should not check RX stuck in IBSS mode because it is required to // set Check BSSID in order to send beacon, however, if check BSSID is - // set, STA cannot hear any packet a all. Emily, 2008.04.12 + // set, STA cannot hear any packet at all. Emily, 2008.04.12 RxResetType = RxCheckStuck(dev); } if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL) @@ -3962,7 +3962,7 @@ RESET_START: up(&priv->wx_sem); RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__); //rtl8192_irq_disable(dev); - RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__); + RT_TRACE(COMP_RESET,"%s():===========>start up the driver\n",__FUNCTION__); reset_status = _rtl8192_up(dev); RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__); @@ -4155,7 +4155,7 @@ extern void rtl819x_watchdog_wqcallback(struct work_struct *work) void watch_dog_timer_callback(unsigned long data) { struct r8192_priv *priv = ieee80211_priv((struct net_device *) data); - //printk("===============>watch_dog timer\n"); + //printk("===============>watch_dog timer\n"); queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq, 0); mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME)); } @@ -4170,7 +4170,7 @@ int _rtl8192_up(struct net_device *dev) init_status = rtl8192_adapter_start(dev); if(!init_status) { - RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n", __FUNCTION__); + RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization failed!\n", __FUNCTION__); priv->up=priv->ieee80211->ieee_up = 0; return -EAGAIN; } @@ -4256,7 +4256,7 @@ int rtl8192_down(struct net_device *dev) skb_queue_purge(&priv->ieee80211->skb_drv_aggQ [i]); } - //as cancel_delayed_work will del work->timer, so if work is not definedas struct delayed_work, it will corrupt + //as cancel_delayed_work will del work->timer, so if work is not defined as struct delayed_work, it will corrupt // flush_scheduled_work(); rtl8192_cancel_deferred_work(priv); deinit_hal_dm(dev); @@ -4516,7 +4516,7 @@ u8 HwRateToMRate90(bool bIsHT, u8 rate) /** * Function: UpdateRxPktTimeStamp - * Overview: Recored down the TSF time stamp when receiving a packet + * Overview: Record down the TSF time stamp when receiving a packet * * Input: * PADAPTER Adapter @@ -4556,9 +4556,9 @@ long rtl819x_translate_todbm(u8 signal_strength_index )// 0-100 index. } -/* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to +/* 2008/01/22 MH We can not declare RSSI/EVM total value of sliding window to be a local static. Otherwise, it may increase when we return from S3/S4. The - value will be kept in memory or disk. We must delcare the value in adapter + value will be kept in memory or disk. We must declare the value in adapter and it will be reinitialized when return from S3/S4. */ void rtl8192_process_phyinfo(struct r8192_priv * priv,u8* buffer, struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats) { @@ -5091,7 +5091,7 @@ static void rtl8192_query_rxphystatus( tmp_rxevm = pofdm_buf->rxevm_X[i]; rx_evmX = (char)(tmp_rxevm); - // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment + // Do not use shift operation like "rx_evmX >>= 1" because the compiler of free build environment // fill most significant bit to "zero" when doing shifting operation which may change a negative // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore. rx_evmX /= 2; //dbm @@ -5171,7 +5171,7 @@ void TranslateRxSignalStuff819xUsb(struct sk_buff *skb, type = WLAN_FC_GET_TYPE(fc); praddr = hdr->addr1; - /* Check if the received packet is acceptabe. */ + /* Check if the received packet is acceptable. */ bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) && (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3)) && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV)); @@ -5211,7 +5211,7 @@ void TranslateRxSignalStuff819xUsb(struct sk_buff *skb, /** * Function: UpdateReceivedRateHistogramStatistics -* Overview: Recored down the received data rate +* Overview: Record down the received data rate * * Input: * struct net_device *dev @@ -5401,7 +5401,7 @@ void query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, } #ifdef USB_RX_AGGREGATION_SUPPORT - /* for the rx aggregated sub frame, the redundant space truelly contained in the packet */ + /* for the rx aggregated sub frame, the redundant space truly contained in the packet */ if(bIsRxAggrSubframe) { skb_pull(skb, 8); } @@ -5480,7 +5480,7 @@ void rtl8192_rx_nomal(struct sk_buff* skb) PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, false); } #endif - /* Process the MPDU recevied */ + /* Process the MPDU received */ skb_trim(skb, skb->len - 4/*sCrcLng*/); rx_pkt_len = skb->len; @@ -5538,7 +5538,7 @@ void rtl8192_rx_nomal(struct sk_buff* skb) if(PacketLength > agg_skb->len) { break; } - /* Process the MPDU recevied */ + /* Process the MPDU received */ skb = dev_alloc_skb(PacketLength); memcpy(skb_put(skb,PacketLength),agg_skb->data, PacketLength); skb_trim(skb, skb->len - 4/*sCrcLng*/); diff --git a/drivers/staging/rtl8192u/r8192U_dm.c b/drivers/staging/rtl8192u/r8192U_dm.c index 2dde9fa..3f79e61 100644 --- a/drivers/staging/rtl8192u/r8192U_dm.c +++ b/drivers/staging/rtl8192u/r8192U_dm.c @@ -38,7 +38,7 @@ static u32 edca_setting_UL[HT_IOT_PEER_MAX] = /*------------------------Define global variable-----------------------------*/ // Debug variable ? dig_t dm_digtable; -// Store current shoftware write register content for MAC PHY. +// Store current software write register content for MAC PHY. u8 dm_shadow[16][256] = {{0}}; // For Dynamic Rx Path Selection by Signal Strength DRxPathSel DM_RxPathSelTable; @@ -119,7 +119,7 @@ static void dm_pd_th(struct net_device *dev); static void dm_cs_ratio(struct net_device *dev); static void dm_init_ctstoself(struct net_device *dev); -// DM --> EDCA turboe mode control +// DM --> EDCA turbo mode control static void dm_check_edca_turbo(struct net_device *dev); // DM --> HW RF control @@ -348,7 +348,7 @@ extern void init_rate_adaptive(struct net_device * dev) * * Revised History: * When Who Remark - * 05/26/08 amy Create version 0 proting from windows code. + * 05/26/08 amy Create version 0 porting from windows code. * *---------------------------------------------------------------------------*/ static void dm_check_rate_adaptive(struct net_device * dev) @@ -543,7 +543,7 @@ static u32 OFDMSwingTable[OFDM_Table_Length] = { 0x5a400169, // 3, +3db 0x50800142, // 4, +2db 0x47c0011f, // 5, +1db - 0x40000100, // 6, +0db ===> default, upper for higher temprature, lower for low temprature + 0x40000100, // 6, +0db ===> default, upper for higher temperature, lower for low temperature 0x390000e4, // 7, -1db 0x32c000cb, // 8, -2db 0x2d4000b5, // 9, -3db @@ -678,7 +678,7 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) { write_nic_byte(dev, 0x1ba, 0); viviflag = FALSE; - RT_TRACE(COMP_POWER_TRACKING, "we filted this data\n"); + RT_TRACE(COMP_POWER_TRACKING, "we filtered the data\n"); for(k = 0;k < 5; k++) tmp_report[k] = 0; break; @@ -864,14 +864,14 @@ static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev) RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d \n", tmpRegA); if(tmpRegA < 3 || tmpRegA > 13) return; - if(tmpRegA >= 12) // if over 12, TP will be bad when high temprature + if(tmpRegA >= 12) // if over 12, TP will be bad when high temperature tmpRegA = 12; RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d \n", tmpRegA); priv->ThermalMeter[0] = ThermalMeterVal; //We use fixed value by Bryant's suggestion priv->ThermalMeter[1] = ThermalMeterVal; //We use fixed value by Bryant's suggestion - //Get current RF-A temprature index - if(priv->ThermalMeter[0] >= (u8)tmpRegA) //lower temprature + //Get current RF-A temperature index + if(priv->ThermalMeter[0] >= (u8)tmpRegA) //lower temperature { tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0]-(u8)tmpRegA); tmpCCK40Mindex = tmpCCK20Mindex - 6; @@ -885,7 +885,7 @@ static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev) else { tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]); - if(tmpval >= 6) // higher temprature + if(tmpval >= 6) // higher temperature tmpOFDMindex = tmpCCK20Mindex = 0; // max to +6dB else tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval; @@ -1457,9 +1457,9 @@ static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); - // Tx Power tracking by Theremal Meter require Firmware R/W 3-wire. This mechanism + // Tx Power tracking by Thermal Meter require Firmware R/W 3-wire. This mechanism // can be enabled only when Firmware R/W 3-wire is enabled. Otherwise, frequent r/w - // 3-wire by driver cause RF goes into wrong state. + // 3-wire by driver causes RF to go into a wrong state. if(priv->ieee80211->FwRWRF) priv->btxpower_tracking = TRUE; else @@ -1520,7 +1520,7 @@ static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev) if(!TM_Trigger) { - //Attention!! You have to wirte all 12bits data to RF, or it may cause RF to crash + //Attention!! You have to write all 12bits data to RF, or it may cause RF to crash //actually write reg0x02 bit1=0, then bit1=1. //DbgPrint("Trigger ThermalMeter, write RF reg0x2 = 0x4d to 0x4f\n"); rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); @@ -1744,7 +1744,7 @@ extern void dm_restore_dynamic_mechanism_state(struct net_device *dev) write_nic_dword(dev, RATR0, ratr_value); write_nic_byte(dev, UFWP, 1); } - //Resore TX Power Tracking Index + //Restore TX Power Tracking Index if(priv->btxpower_trackingInit && priv->btxpower_tracking){ dm_txpower_reset_recovery(dev); } @@ -2031,7 +2031,7 @@ static void dm_dig_init(struct net_device *dev) dm_digtable.dbg_mode = DM_DBG_OFF; //off=by real rssi value, on=by DM_DigTable.Rssi_val for new dig dm_digtable.dig_algorithm_switch = 0; - /* 2007/10/04 MH Define init gain threshol. */ + /* 2007/10/04 MH Define init gain threshold. */ dm_digtable.dig_state = DM_STA_DIG_MAX; dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX; dm_digtable.initialgain_lowerbound_state = false; @@ -2097,7 +2097,7 @@ static void dm_ctrl_initgain_byrssi_by_driverrssi( return; //DbgPrint("Dig by Sw Rssi \n"); - if(dm_digtable.dig_algorithm_switch) // if swithed algorithm, we have to disable FW Dig. + if(dm_digtable.dig_algorithm_switch) // if switched algorithm, we have to disable FW Dig. fw_dig = 0; if(fw_dig <= 3) // execute several times to make sure the FW Dig is disabled {// FW DIG Off @@ -2160,7 +2160,7 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( /*DbgPrint("DIG Check\n\r RSSI=%d LOW=%d HIGH=%d STATE=%d", pHalData->UndecoratedSmoothedPWDB, DM_DigTable.RssiLowThresh, DM_DigTable.RssiHighThresh, DM_DigTable.Dig_State);*/ - /* 1. When RSSI decrease, We have to judge if it is smaller than a treshold + /* 1. When RSSI decrease, We have to judge if it is smaller than a threshold and then execute below step. */ if ((priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh)) { @@ -2220,7 +2220,7 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( } - /* 2. When RSSI increase, We have to judge if it is larger than a treshold + /* 2. When RSSI increase, We have to judge if it is larger than a threshold and then execute below step. */ if ((priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) ) { @@ -2329,7 +2329,7 @@ static void dm_ctrl_initgain_byrssi_highpwr( } /* 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if - it is larger than a treshold and then execute below step. */ + it is larger than a threshold and then execute below step. */ // 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue. if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh) { @@ -2841,8 +2841,8 @@ static void dm_check_rfctrl_gpio(struct net_device * dev) { //struct r8192_priv *priv = ieee80211_priv(dev); - // Walk around for DTM test, we will not enable HW - radio on/off because r/w - // page 1 register before Lextra bus is enabled cause system fails when resuming + // Work around for DTM test, we will not enable HW - radio on/off because r/w + // page 1 register before extra bus is enabled causing system fails when resuming // from S4. 20080218, Emily // Stop to execute workitem to prevent S3/S4 bug. @@ -3377,13 +3377,13 @@ extern void dm_fsync_timer_callback(unsigned long data) { u32 DiffNum = priv->rateCountDiffRecord - rate_count_diff; - // Contiune count + // Continue count if(DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold) priv->ContiuneDiffCount++; else priv->ContiuneDiffCount = 0; - // Contiune count over + // Continue count over if(priv->ContiuneDiffCount >=2) { bSwitchFromCountDiff = true; @@ -3392,7 +3392,7 @@ extern void dm_fsync_timer_callback(unsigned long data) } else { - // Stop contiune count + // Stop continue count priv->ContiuneDiffCount = 0; } @@ -3523,7 +3523,7 @@ static void dm_StartSWFsync(struct net_device *dev) RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__); // Initial rate record to zero, start to record. priv->rate_record = 0; - // Initial contiune diff count to zero, start to record. + // Initial continue diff count to zero, start to record. priv->ContiuneDiffCount = 0; priv->rateCountDiffRecord = 0; priv->bswitch_fsync = false; @@ -3875,7 +3875,7 @@ static void dm_send_rssi_tofw(struct net_device *dev) // If we test chariot, we should stop the TX command ? // Because 92E will always silent reset when we send tx command. We use register - // 0x1e0(byte) to botify driver. + // 0x1e0(byte) to notify driver. write_nic_byte(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb); return; tx_cmd.Op = TXCMD_SET_RX_RSSI; diff --git a/drivers/staging/rtl8192u/r8192U_hw.h b/drivers/staging/rtl8192u/r8192U_hw.h index e89aaf7..b0ee4dd 100644 --- a/drivers/staging/rtl8192u/r8192U_hw.h +++ b/drivers/staging/rtl8192u/r8192U_hw.h @@ -10,7 +10,7 @@ Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. - We want to tanks the Authors of those projects + We want to thanks the Authors of those projects and the Ndiswrapper project Authors. */ diff --git a/drivers/staging/rtl8192u/r8192U_wx.c b/drivers/staging/rtl8192u/r8192U_wx.c index 981de9b..2ce0fc8 100644 --- a/drivers/staging/rtl8192u/r8192U_wx.c +++ b/drivers/staging/rtl8192u/r8192U_wx.c @@ -13,7 +13,7 @@ Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. - We want to tanks the Authors of those projects and the Ndiswrapper + We want to thanks the Authors of those projects and the Ndiswrapper project Authors. */ @@ -256,7 +256,7 @@ static int r8192_wx_get_ap_status(struct net_device *dev, //count the length of input ssid for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++); - //search for the correspoding info which is received + //search for the corresponding info which is received list_for_each_entry(target, &ieee->network_list, list) { if ( (target->ssid_len == name_len) && (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){ @@ -419,7 +419,7 @@ static int rtl8180_wx_get_range(struct net_device *dev, range->max_qual.updated = 7; /* Updated all three */ range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */ - /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ + /* TODO: Find real 'good' to 'bad' threshold value for RSSI */ range->avg_qual.level = 20 + -98; range->avg_qual.noise = 0; range->avg_qual.updated = 7; /* Updated all three */ @@ -1047,7 +1047,7 @@ static iw_handler r8192_wx_handlers[] = #else NULL, #endif - dummy, /* SIOCGIWAPLIST -- depricated */ + dummy, /* SIOCGIWAPLIST -- deprecated */ r8192_wx_set_scan, /* SIOCSIWSCAN */ r8192_wx_get_scan, /* SIOCGIWSCAN */ r8192_wx_set_essid, /* SIOCSIWESSID */ diff --git a/drivers/staging/rtl8192u/r8192U_wx.h b/drivers/staging/rtl8192u/r8192U_wx.h index f4cf280..1388664 100644 --- a/drivers/staging/rtl8192u/r8192U_wx.h +++ b/drivers/staging/rtl8192u/r8192U_wx.h @@ -7,7 +7,7 @@ Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - We want to tanks the Authors of such projects and the Ndiswrapper project Authors. + We want to thanks the Authors of such projects and the Ndiswrapper project Authors. */ /* this file (will) contains wireless extension handlers*/ diff --git a/drivers/staging/rtl8192u/r819xU_HTType.h b/drivers/staging/rtl8192u/r819xU_HTType.h index 2ac4216..e07f8b1 100644 --- a/drivers/staging/rtl8192u/r819xU_HTType.h +++ b/drivers/staging/rtl8192u/r819xU_HTType.h @@ -211,7 +211,7 @@ typedef struct _RT_HIGH_THROUGHPUT{ u8 bEnableHT; u8 bCurrentHTSupport; - u8 bRegBW40MHz; // Tx 40MHz channel capablity + u8 bRegBW40MHz; // Tx 40MHz channel capability u8 bCurBW40MHz; // Tx 40MHz channel capability u8 bRegShortGI40MHz; // Tx Short GI for 40Mhz diff --git a/drivers/staging/rtl8192u/r819xU_cmdpkt.c b/drivers/staging/rtl8192u/r819xU_cmdpkt.c index 9348f42..ec1eeb7 100644 --- a/drivers/staging/rtl8192u/r819xU_cmdpkt.c +++ b/drivers/staging/rtl8192u/r819xU_cmdpkt.c @@ -157,7 +157,7 @@ SendTxCommandPacket( seg_ptr = skb_put(skb, buffer_len); /* * Transform from little endian to big endian - * and pending zero + * and pending zero */ memcpy(seg_ptr,codevirtualaddress,buffer_len); tcb_desc->txbuf_size= (u16)buffer_len; @@ -718,15 +718,15 @@ cmpk_message_handle_rx( /* 2. Read virtual address from RFD. */ pcmd_buff = pstats->virtual_address; - /* 3. Read command pakcet element id and length. */ + /* 3. Read command packet element id and length. */ element_id = pcmd_buff[0]; /*RT_TRACE(COMP_SEND, DebugLevel, ("\n\r[CMPK]-->element ID=%d Len=%d", element_id, total_length));*/ - /* 4. Check every received command packet conent according to different + /* 4. Check every received command packet content according to different element type. Because FW may aggregate RX command packet to minimize transmit time between DRV and FW.*/ - // Add a counter to prevent to locked in the loop too long + // Add a counter to prevent the lock in the loop to be to long while (total_length > 0 || exe_cnt++ >100) { /* 2007/01/17 MH We support aggregation of different cmd in the same packet. */ diff --git a/drivers/staging/rtl8192u/r819xU_firmware.c b/drivers/staging/rtl8192u/r819xU_firmware.c index 4bb5fff..fe5776d 100644 --- a/drivers/staging/rtl8192u/r819xU_firmware.c +++ b/drivers/staging/rtl8192u/r819xU_firmware.c @@ -275,11 +275,11 @@ bool init_firmware(struct net_device *dev) /* * Download boot, main, and data image for System reset. - * Download data image for firmware reseta + * Download data image for firmware reset */ for(init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; init_step++) { /* - * Open Image file, and map file to contineous memory if open file success. + * Open Image file, and map file to continuous memory if open file success. * or read image file from array. Default load from IMG file */ if(rst_opt == OPT_SYSTEM_RESET) { diff --git a/drivers/staging/rtl8192u/r819xU_phy.c b/drivers/staging/rtl8192u/r819xU_phy.c index c4586b0..636d6fd 100644 --- a/drivers/staging/rtl8192u/r819xU_phy.c +++ b/drivers/staging/rtl8192u/r819xU_phy.c @@ -40,7 +40,7 @@ static u32 RF_CHANNEL_TABLE_ZEBRA[] = { * and do register read/write * input: u32 dwBitMask //taget bit pos in the addr to be modified * output: none - * return: u32 return the shift bit bit position of the mask + * return: u32 return the shift bit position of the mask * ****************************************************************************/ u32 rtl8192_CalculateBitShift(u32 dwBitMask) { @@ -176,7 +176,7 @@ u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x1); - // TODO: we should not delay such a long time. Ask help from SD3 + // TODO: we should not delay such a long time. Ask help from SD3 msleep(1); ret = rtl8192_QueryBBReg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData); @@ -252,7 +252,7 @@ void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E eRFPath NewOffset = Offset; } - // Put write addr in [5:0] and write data in [31:16] + // Put write addr in [5:0] and write data in [31:16] DataAndAddr = (Data<<16) | (NewOffset&0x3f); // Write Operation @@ -525,7 +525,7 @@ void rtl8192_phy_configmac(struct net_device* dev) } /****************************************************************************** - *function: This function do dirty work + *function: This function does dirty work * input: dev * output: none * return: none @@ -578,7 +578,7 @@ void rtl8192_phyConfigBB(struct net_device* dev, u8 ConfigType) void rtl8192_InitBBRFRegDef(struct net_device* dev) { struct r8192_priv *priv = ieee80211_priv(dev); -// RF Interface Sowrtware Control +// RF Interface Software Control priv->PHYRegDef[RF90_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 LSBs if read 32-bit from 0x870 priv->PHYRegDef[RF90_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) priv->PHYRegDef[RF90_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 LSBs if read 32-bit from 0x874 @@ -602,7 +602,7 @@ void rtl8192_InitBBRFRegDef(struct net_device* dev) priv->PHYRegDef[RF90_PATH_C].rfintfe = rFPGA0_XC_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86A (16-bit for 0x86A) priv->PHYRegDef[RF90_PATH_D].rfintfe = rFPGA0_XD_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86C (16-bit for 0x86E) - //Addr of LSSI. Wirte RF register by driver + //Addr of LSSI. Write RF register by driver priv->PHYRegDef[RF90_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; //LSSI Parameter priv->PHYRegDef[RF90_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter; priv->PHYRegDef[RF90_PATH_C].rf3wireOffset = rFPGA0_XC_LSSIParameter; @@ -1384,7 +1384,7 @@ u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, u8* stage, u } /****************************************************************************** - *function: This function does acturally set channel work + *function: This function does actually set channel work * input: struct net_device *dev * u8 channel * output: none @@ -1425,7 +1425,7 @@ void rtl8192_SwChnl_WorkItem(struct net_device *dev) } /****************************************************************************** - *function: This function scheduled actural workitem to set channel + *function: This function scheduled actual workitem to set channel * input: net_device dev * u8 channel //channel to set * output: none diff --git a/drivers/staging/rtl8192u/r819xU_phyreg.h b/drivers/staging/rtl8192u/r819xU_phyreg.h index 06b0b53..50f24dc 100644 --- a/drivers/staging/rtl8192u/r819xU_phyreg.h +++ b/drivers/staging/rtl8192u/r819xU_phyreg.h @@ -443,7 +443,7 @@ #define bCCKRxIG 0x7f00 #define bCCKLNAPolarity 0x800000 #define bCCKRx1stGain 0x7f0000 -#define bCCKRFExtend 0x20000000 //CCK Rx Iinital gain polarity +#define bCCKRFExtend 0x20000000 //CCK Rx inital gain polarity #define bCCKRxAGCSatLevel 0x1f000000 #define bCCKRxAGCSatCount 0xe0 #define bCCKRxRFSettle 0x1f //AGCsamp_dly -- cgit v0.10.2 From ffc2825c2942b57c5dbfbcb3ad798696438aed62 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 1 May 2012 18:23:38 -0400 Subject: Staging: mei: move the mei code out of staging It's been cleaned up, and there's nothing else left to do, so move it out of staging into drivers/misc/ where all can use it now. Cc: Tomas Winkler Cc: Oren Weil Cc: Alan Cox Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index c779509..c910428 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -506,4 +506,5 @@ source "drivers/misc/ti-st/Kconfig" source "drivers/misc/lis3lv02d/Kconfig" source "drivers/misc/carma/Kconfig" source "drivers/misc/altera-stapl/Kconfig" +source "drivers/misc/mei/Kconfig" endmenu diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 3e1d801..0f6af6a 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -49,3 +49,4 @@ obj-y += carma/ obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/ obj-$(CONFIG_MAX8997_MUIC) += max8997-muic.o +obj-$(CONFIG_INTEL_MEI) += mei/ diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig new file mode 100644 index 0000000..47d78a7 --- /dev/null +++ b/drivers/misc/mei/Kconfig @@ -0,0 +1,28 @@ +config INTEL_MEI + tristate "Intel Management Engine Interface (Intel MEI)" + depends on X86 && PCI && EXPERIMENTAL && WATCHDOG_CORE + help + The Intel Management Engine (Intel ME) provides Manageability, + Security and Media services for system containing Intel chipsets. + if selected /dev/mei misc device will be created. + + Supported Chipsets are: + 7 Series Chipset Family + 6 Series Chipset Family + 5 Series Chipset Family + 4 Series Chipset Family + Mobile 4 Series Chipset Family + ICH9 + 82946GZ/GL + 82G35 Express + 82Q963/Q965 + 82P965/G965 + Mobile PM965/GM965 + Mobile GME965/GLE960 + 82Q35 Express + 82G33/G31/P35/P31 Express + 82Q33 Express + 82X38/X48 Express + + For more information see + diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile new file mode 100644 index 0000000..57168db --- /dev/null +++ b/drivers/misc/mei/Makefile @@ -0,0 +1,11 @@ +# +# Makefile - Intel Management Engine Interface (Intel MEI) Linux driver +# Copyright (c) 2010-2011, Intel Corporation. +# +obj-$(CONFIG_INTEL_MEI) += mei.o +mei-objs := init.o +mei-objs += interrupt.o +mei-objs += interface.o +mei-objs += iorw.o +mei-objs += main.o +mei-objs += wd.o diff --git a/drivers/misc/mei/TODO b/drivers/misc/mei/TODO new file mode 100644 index 0000000..fc26601 --- /dev/null +++ b/drivers/misc/mei/TODO @@ -0,0 +1,10 @@ +TODO: + - Cleanup and split the timer function +Upon Unstaging: + - move mei.h to include/linux/mei.h + - Documentation/ioctl/ioctl-number.txt + - move mei.txt under Documentation/mei/ + - move mei-amt-version.c under Documentation/mei + - add hostprogs-y for mei-amt-version.c + - drop mei_version.h + - Updated MAINTAINERS diff --git a/drivers/misc/mei/hw.h b/drivers/misc/mei/hw.h new file mode 100644 index 0000000..24c4c96 --- /dev/null +++ b/drivers/misc/mei/hw.h @@ -0,0 +1,332 @@ +/* + * + * Intel Management Engine Interface (Intel MEI) Linux driver + * Copyright (c) 2003-2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef _MEI_HW_TYPES_H_ +#define _MEI_HW_TYPES_H_ + +#include + +/* + * Timeouts + */ +#define MEI_INTEROP_TIMEOUT (HZ * 7) +#define MEI_CONNECT_TIMEOUT 3 /* at least 2 seconds */ + +#define CONNECT_TIMEOUT 15 /* HPS definition */ +#define INIT_CLIENTS_TIMEOUT 15 /* HPS definition */ + +#define IAMTHIF_STALL_TIMER 12 /* seconds */ +#define IAMTHIF_READ_TIMER 10000 /* ms */ + +/* + * Internal Clients Number + */ +#define MEI_WD_HOST_CLIENT_ID 1 +#define MEI_IAMTHIF_HOST_CLIENT_ID 2 + +/* + * MEI device IDs + */ +#define MEI_DEV_ID_82946GZ 0x2974 /* 82946GZ/GL */ +#define MEI_DEV_ID_82G35 0x2984 /* 82G35 Express */ +#define MEI_DEV_ID_82Q965 0x2994 /* 82Q963/Q965 */ +#define MEI_DEV_ID_82G965 0x29A4 /* 82P965/G965 */ + +#define MEI_DEV_ID_82GM965 0x2A04 /* Mobile PM965/GM965 */ +#define MEI_DEV_ID_82GME965 0x2A14 /* Mobile GME965/GLE960 */ + +#define MEI_DEV_ID_ICH9_82Q35 0x29B4 /* 82Q35 Express */ +#define MEI_DEV_ID_ICH9_82G33 0x29C4 /* 82G33/G31/P35/P31 Express */ +#define MEI_DEV_ID_ICH9_82Q33 0x29D4 /* 82Q33 Express */ +#define MEI_DEV_ID_ICH9_82X38 0x29E4 /* 82X38/X48 Express */ +#define MEI_DEV_ID_ICH9_3200 0x29F4 /* 3200/3210 Server */ + +#define MEI_DEV_ID_ICH9_6 0x28B4 /* Bearlake */ +#define MEI_DEV_ID_ICH9_7 0x28C4 /* Bearlake */ +#define MEI_DEV_ID_ICH9_8 0x28D4 /* Bearlake */ +#define MEI_DEV_ID_ICH9_9 0x28E4 /* Bearlake */ +#define MEI_DEV_ID_ICH9_10 0x28F4 /* Bearlake */ + +#define MEI_DEV_ID_ICH9M_1 0x2A44 /* Cantiga */ +#define MEI_DEV_ID_ICH9M_2 0x2A54 /* Cantiga */ +#define MEI_DEV_ID_ICH9M_3 0x2A64 /* Cantiga */ +#define MEI_DEV_ID_ICH9M_4 0x2A74 /* Cantiga */ + +#define MEI_DEV_ID_ICH10_1 0x2E04 /* Eaglelake */ +#define MEI_DEV_ID_ICH10_2 0x2E14 /* Eaglelake */ +#define MEI_DEV_ID_ICH10_3 0x2E24 /* Eaglelake */ +#define MEI_DEV_ID_ICH10_4 0x2E34 /* Eaglelake */ + +#define MEI_DEV_ID_IBXPK_1 0x3B64 /* Calpella */ +#define MEI_DEV_ID_IBXPK_2 0x3B65 /* Calpella */ + +#define MEI_DEV_ID_CPT_1 0x1C3A /* Cougerpoint */ +#define MEI_DEV_ID_PBG_1 0x1D3A /* PBG */ + +#define MEI_DEV_ID_PPT_1 0x1E3A /* Pantherpoint PPT */ +#define MEI_DEV_ID_PPT_2 0x1CBA /* Pantherpoint PPT */ +#define MEI_DEV_ID_PPT_3 0x1DBA /* Pantherpoint PPT */ + + +/* + * MEI HW Section + */ + +/* MEI registers */ +/* H_CB_WW - Host Circular Buffer (CB) Write Window register */ +#define H_CB_WW 0 +/* H_CSR - Host Control Status register */ +#define H_CSR 4 +/* ME_CB_RW - ME Circular Buffer Read Window register (read only) */ +#define ME_CB_RW 8 +/* ME_CSR_HA - ME Control Status Host Access register (read only) */ +#define ME_CSR_HA 0xC + + +/* register bits of H_CSR (Host Control Status register) */ +/* Host Circular Buffer Depth - maximum number of 32-bit entries in CB */ +#define H_CBD 0xFF000000 +/* Host Circular Buffer Write Pointer */ +#define H_CBWP 0x00FF0000 +/* Host Circular Buffer Read Pointer */ +#define H_CBRP 0x0000FF00 +/* Host Reset */ +#define H_RST 0x00000010 +/* Host Ready */ +#define H_RDY 0x00000008 +/* Host Interrupt Generate */ +#define H_IG 0x00000004 +/* Host Interrupt Status */ +#define H_IS 0x00000002 +/* Host Interrupt Enable */ +#define H_IE 0x00000001 + + +/* register bits of ME_CSR_HA (ME Control Status Host Access register) */ +/* ME CB (Circular Buffer) Depth HRA (Host Read Access) - host read only +access to ME_CBD */ +#define ME_CBD_HRA 0xFF000000 +/* ME CB Write Pointer HRA - host read only access to ME_CBWP */ +#define ME_CBWP_HRA 0x00FF0000 +/* ME CB Read Pointer HRA - host read only access to ME_CBRP */ +#define ME_CBRP_HRA 0x0000FF00 +/* ME Reset HRA - host read only access to ME_RST */ +#define ME_RST_HRA 0x00000010 +/* ME Ready HRA - host read only access to ME_RDY */ +#define ME_RDY_HRA 0x00000008 +/* ME Interrupt Generate HRA - host read only access to ME_IG */ +#define ME_IG_HRA 0x00000004 +/* ME Interrupt Status HRA - host read only access to ME_IS */ +#define ME_IS_HRA 0x00000002 +/* ME Interrupt Enable HRA - host read only access to ME_IE */ +#define ME_IE_HRA 0x00000001 + +/* + * MEI Version + */ +#define HBM_MINOR_VERSION 0 +#define HBM_MAJOR_VERSION 1 +#define HBM_TIMEOUT 1 /* 1 second */ + +/* Host bus message command opcode */ +#define MEI_HBM_CMD_OP_MSK 0x7f +/* Host bus message command RESPONSE */ +#define MEI_HBM_CMD_RES_MSK 0x80 + +/* + * MEI Bus Message Command IDs + */ +#define HOST_START_REQ_CMD 0x01 +#define HOST_START_RES_CMD 0x81 + +#define HOST_STOP_REQ_CMD 0x02 +#define HOST_STOP_RES_CMD 0x82 + +#define ME_STOP_REQ_CMD 0x03 + +#define HOST_ENUM_REQ_CMD 0x04 +#define HOST_ENUM_RES_CMD 0x84 + +#define HOST_CLIENT_PROPERTIES_REQ_CMD 0x05 +#define HOST_CLIENT_PROPERTIES_RES_CMD 0x85 + +#define CLIENT_CONNECT_REQ_CMD 0x06 +#define CLIENT_CONNECT_RES_CMD 0x86 + +#define CLIENT_DISCONNECT_REQ_CMD 0x07 +#define CLIENT_DISCONNECT_RES_CMD 0x87 + +#define MEI_FLOW_CONTROL_CMD 0x08 + +/* + * MEI Stop Reason + * used by hbm_host_stop_request.reason + */ +enum mei_stop_reason_types { + DRIVER_STOP_REQUEST = 0x00, + DEVICE_D1_ENTRY = 0x01, + DEVICE_D2_ENTRY = 0x02, + DEVICE_D3_ENTRY = 0x03, + SYSTEM_S1_ENTRY = 0x04, + SYSTEM_S2_ENTRY = 0x05, + SYSTEM_S3_ENTRY = 0x06, + SYSTEM_S4_ENTRY = 0x07, + SYSTEM_S5_ENTRY = 0x08 +}; + +/* + * Client Connect Status + * used by hbm_client_connect_response.status + */ +enum client_connect_status_types { + CCS_SUCCESS = 0x00, + CCS_NOT_FOUND = 0x01, + CCS_ALREADY_STARTED = 0x02, + CCS_OUT_OF_RESOURCES = 0x03, + CCS_MESSAGE_SMALL = 0x04 +}; + +/* + * Client Disconnect Status + */ +enum client_disconnect_status_types { + CDS_SUCCESS = 0x00 +}; + +/* + * MEI BUS Interface Section + */ +struct mei_msg_hdr { + u32 me_addr:8; + u32 host_addr:8; + u32 length:9; + u32 reserved:6; + u32 msg_complete:1; +} __packed; + + +struct mei_bus_message { + u8 hbm_cmd; + u8 data[0]; +} __packed; + +struct hbm_version { + u8 minor_version; + u8 major_version; +} __packed; + +struct hbm_host_version_request { + u8 hbm_cmd; + u8 reserved; + struct hbm_version host_version; +} __packed; + +struct hbm_host_version_response { + u8 hbm_cmd; + u8 host_version_supported; + struct hbm_version me_max_version; +} __packed; + +struct hbm_host_stop_request { + u8 hbm_cmd; + u8 reason; + u8 reserved[2]; +} __packed; + +struct hbm_host_stop_response { + u8 hbm_cmd; + u8 reserved[3]; +} __packed; + +struct hbm_me_stop_request { + u8 hbm_cmd; + u8 reason; + u8 reserved[2]; +} __packed; + +struct hbm_host_enum_request { + u8 hbm_cmd; + u8 reserved[3]; +} __packed; + +struct hbm_host_enum_response { + u8 hbm_cmd; + u8 reserved[3]; + u8 valid_addresses[32]; +} __packed; + +struct mei_client_properties { + uuid_le protocol_name; + u8 protocol_version; + u8 max_number_of_connections; + u8 fixed_address; + u8 single_recv_buf; + u32 max_msg_length; +} __packed; + +struct hbm_props_request { + u8 hbm_cmd; + u8 address; + u8 reserved[2]; +} __packed; + + +struct hbm_props_response { + u8 hbm_cmd; + u8 address; + u8 status; + u8 reserved[1]; + struct mei_client_properties client_properties; +} __packed; + +struct hbm_client_connect_request { + u8 hbm_cmd; + u8 me_addr; + u8 host_addr; + u8 reserved; +} __packed; + +struct hbm_client_connect_response { + u8 hbm_cmd; + u8 me_addr; + u8 host_addr; + u8 status; +} __packed; + +struct hbm_client_disconnect_request { + u8 hbm_cmd; + u8 me_addr; + u8 host_addr; + u8 reserved[1]; +} __packed; + +#define MEI_FC_MESSAGE_RESERVED_LENGTH 5 + +struct hbm_flow_control { + u8 hbm_cmd; + u8 me_addr; + u8 host_addr; + u8 reserved[MEI_FC_MESSAGE_RESERVED_LENGTH]; +} __packed; + +struct mei_me_client { + struct mei_client_properties props; + u8 client_id; + u8 mei_flow_ctrl_creds; +} __packed; + + +#endif diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c new file mode 100644 index 0000000..afb0a58 --- /dev/null +++ b/drivers/misc/mei/init.c @@ -0,0 +1,735 @@ +/* + * + * Intel Management Engine Interface (Intel MEI) Linux driver + * Copyright (c) 2003-2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include + +#include "mei_dev.h" +#include "hw.h" +#include "interface.h" +#include "mei.h" + +const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac, + 0xa8, 0x46, 0xe0, 0xff, 0x65, + 0x81, 0x4c); + +/** + * mei_io_list_init - Sets up a queue list. + * + * @list: An instance io list structure + * @dev: the device structure + */ +void mei_io_list_init(struct mei_io_list *list) +{ + /* initialize our queue list */ + INIT_LIST_HEAD(&list->mei_cb.cb_list); +} + +/** + * mei_io_list_flush - removes list entry belonging to cl. + * + * @list: An instance of our list structure + * @cl: private data of the file object + */ +void mei_io_list_flush(struct mei_io_list *list, struct mei_cl *cl) +{ + struct mei_cl_cb *pos; + struct mei_cl_cb *next; + + list_for_each_entry_safe(pos, next, &list->mei_cb.cb_list, cb_list) { + if (pos->file_private) { + struct mei_cl *cl_tmp; + cl_tmp = (struct mei_cl *)pos->file_private; + if (mei_cl_cmp_id(cl, cl_tmp)) + list_del(&pos->cb_list); + } + } +} +/** + * mei_cl_flush_queues - flushes queue lists belonging to cl. + * + * @dev: the device structure + * @cl: private data of the file object + */ +int mei_cl_flush_queues(struct mei_cl *cl) +{ + if (!cl || !cl->dev) + return -EINVAL; + + dev_dbg(&cl->dev->pdev->dev, "remove list entry belonging to cl\n"); + mei_io_list_flush(&cl->dev->read_list, cl); + mei_io_list_flush(&cl->dev->write_list, cl); + mei_io_list_flush(&cl->dev->write_waiting_list, cl); + mei_io_list_flush(&cl->dev->ctrl_wr_list, cl); + mei_io_list_flush(&cl->dev->ctrl_rd_list, cl); + mei_io_list_flush(&cl->dev->amthi_cmd_list, cl); + mei_io_list_flush(&cl->dev->amthi_read_complete_list, cl); + return 0; +} + + + +/** + * mei_reset_iamthif_params - initializes mei device iamthif + * + * @dev: the device structure + */ +static void mei_reset_iamthif_params(struct mei_device *dev) +{ + /* reset iamthif parameters. */ + dev->iamthif_current_cb = NULL; + dev->iamthif_msg_buf_size = 0; + dev->iamthif_msg_buf_index = 0; + dev->iamthif_canceled = false; + dev->iamthif_ioctl = false; + dev->iamthif_state = MEI_IAMTHIF_IDLE; + dev->iamthif_timer = 0; +} + +/** + * init_mei_device - allocates and initializes the mei device structure + * + * @pdev: The pci device structure + * + * returns The mei_device_device pointer on success, NULL on failure. + */ +struct mei_device *mei_device_init(struct pci_dev *pdev) +{ + struct mei_device *dev; + + dev = kzalloc(sizeof(struct mei_device), GFP_KERNEL); + if (!dev) + return NULL; + + /* setup our list array */ + INIT_LIST_HEAD(&dev->file_list); + INIT_LIST_HEAD(&dev->wd_cl.link); + INIT_LIST_HEAD(&dev->iamthif_cl.link); + mutex_init(&dev->device_lock); + init_waitqueue_head(&dev->wait_recvd_msg); + init_waitqueue_head(&dev->wait_stop_wd); + dev->mei_state = MEI_INITIALIZING; + dev->iamthif_state = MEI_IAMTHIF_IDLE; + dev->wd_interface_reg = false; + + + mei_io_list_init(&dev->read_list); + mei_io_list_init(&dev->write_list); + mei_io_list_init(&dev->write_waiting_list); + mei_io_list_init(&dev->ctrl_wr_list); + mei_io_list_init(&dev->ctrl_rd_list); + mei_io_list_init(&dev->amthi_cmd_list); + mei_io_list_init(&dev->amthi_read_complete_list); + dev->pdev = pdev; + return dev; +} + +/** + * mei_hw_init - initializes host and fw to start work. + * + * @dev: the device structure + * + * returns 0 on success, <0 on failure. + */ +int mei_hw_init(struct mei_device *dev) +{ + int err = 0; + int ret; + + mutex_lock(&dev->device_lock); + + dev->host_hw_state = mei_hcsr_read(dev); + dev->me_hw_state = mei_mecsr_read(dev); + dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, mestate = 0x%08x.\n", + dev->host_hw_state, dev->me_hw_state); + + /* acknowledge interrupt and stop interupts */ + if ((dev->host_hw_state & H_IS) == H_IS) + mei_reg_write(dev, H_CSR, dev->host_hw_state); + + dev->recvd_msg = false; + dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n"); + + mei_reset(dev, 1); + + dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", + dev->host_hw_state, dev->me_hw_state); + + /* wait for ME to turn on ME_RDY */ + if (!dev->recvd_msg) { + mutex_unlock(&dev->device_lock); + err = wait_event_interruptible_timeout(dev->wait_recvd_msg, + dev->recvd_msg, MEI_INTEROP_TIMEOUT); + mutex_lock(&dev->device_lock); + } + + if (err <= 0 && !dev->recvd_msg) { + dev->mei_state = MEI_DISABLED; + dev_dbg(&dev->pdev->dev, + "wait_event_interruptible_timeout failed" + "on wait for ME to turn on ME_RDY.\n"); + ret = -ENODEV; + goto out; + } + + if (!(((dev->host_hw_state & H_RDY) == H_RDY) && + ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA))) { + dev->mei_state = MEI_DISABLED; + dev_dbg(&dev->pdev->dev, + "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", + dev->host_hw_state, dev->me_hw_state); + + if (!(dev->host_hw_state & H_RDY)) + dev_dbg(&dev->pdev->dev, "host turn off H_RDY.\n"); + + if (!(dev->me_hw_state & ME_RDY_HRA)) + dev_dbg(&dev->pdev->dev, "ME turn off ME_RDY.\n"); + + dev_err(&dev->pdev->dev, "link layer initialization failed.\n"); + ret = -ENODEV; + goto out; + } + + if (dev->version.major_version != HBM_MAJOR_VERSION || + dev->version.minor_version != HBM_MINOR_VERSION) { + dev_dbg(&dev->pdev->dev, "MEI start failed.\n"); + ret = -ENODEV; + goto out; + } + + dev->recvd_msg = false; + dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", + dev->host_hw_state, dev->me_hw_state); + dev_dbg(&dev->pdev->dev, "ME turn on ME_RDY and host turn on H_RDY.\n"); + dev_dbg(&dev->pdev->dev, "link layer has been established.\n"); + dev_dbg(&dev->pdev->dev, "MEI start success.\n"); + ret = 0; + +out: + mutex_unlock(&dev->device_lock); + return ret; +} + +/** + * mei_hw_reset - resets fw via mei csr register. + * + * @dev: the device structure + * @interrupts_enabled: if interrupt should be enabled after reset. + */ +static void mei_hw_reset(struct mei_device *dev, int interrupts_enabled) +{ + dev->host_hw_state |= (H_RST | H_IG); + + if (interrupts_enabled) + mei_enable_interrupts(dev); + else + mei_disable_interrupts(dev); +} + +/** + * mei_reset - resets host and fw. + * + * @dev: the device structure + * @interrupts_enabled: if interrupt should be enabled after reset. + */ +void mei_reset(struct mei_device *dev, int interrupts_enabled) +{ + struct mei_cl *cl_pos = NULL; + struct mei_cl *cl_next = NULL; + struct mei_cl_cb *cb_pos = NULL; + struct mei_cl_cb *cb_next = NULL; + bool unexpected; + + if (dev->mei_state == MEI_RECOVERING_FROM_RESET) { + dev->need_reset = true; + return; + } + + unexpected = (dev->mei_state != MEI_INITIALIZING && + dev->mei_state != MEI_DISABLED && + dev->mei_state != MEI_POWER_DOWN && + dev->mei_state != MEI_POWER_UP); + + dev->host_hw_state = mei_hcsr_read(dev); + + dev_dbg(&dev->pdev->dev, "before reset host_hw_state = 0x%08x.\n", + dev->host_hw_state); + + mei_hw_reset(dev, interrupts_enabled); + + dev->host_hw_state &= ~H_RST; + dev->host_hw_state |= H_IG; + + mei_hcsr_set(dev); + + dev_dbg(&dev->pdev->dev, "currently saved host_hw_state = 0x%08x.\n", + dev->host_hw_state); + + dev->need_reset = false; + + if (dev->mei_state != MEI_INITIALIZING) { + if (dev->mei_state != MEI_DISABLED && + dev->mei_state != MEI_POWER_DOWN) + dev->mei_state = MEI_RESETING; + + list_for_each_entry_safe(cl_pos, + cl_next, &dev->file_list, link) { + cl_pos->state = MEI_FILE_DISCONNECTED; + cl_pos->mei_flow_ctrl_creds = 0; + cl_pos->read_cb = NULL; + cl_pos->timer_count = 0; + } + /* remove entry if already in list */ + dev_dbg(&dev->pdev->dev, "list del iamthif and wd file list.\n"); + mei_remove_client_from_file_list(dev, + dev->wd_cl.host_client_id); + + mei_remove_client_from_file_list(dev, + dev->iamthif_cl.host_client_id); + + mei_reset_iamthif_params(dev); + dev->wd_due_counter = 0; + dev->extra_write_index = 0; + } + + dev->me_clients_num = 0; + dev->rd_msg_hdr = 0; + dev->stop = false; + dev->wd_pending = false; + + /* update the state of the registers after reset */ + dev->host_hw_state = mei_hcsr_read(dev); + dev->me_hw_state = mei_mecsr_read(dev); + + dev_dbg(&dev->pdev->dev, "after reset host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", + dev->host_hw_state, dev->me_hw_state); + + if (unexpected) + dev_warn(&dev->pdev->dev, "unexpected reset.\n"); + + /* Wake up all readings so they can be interrupted */ + list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { + if (waitqueue_active(&cl_pos->rx_wait)) { + dev_dbg(&dev->pdev->dev, "Waking up client!\n"); + wake_up_interruptible(&cl_pos->rx_wait); + } + } + /* remove all waiting requests */ + list_for_each_entry_safe(cb_pos, cb_next, + &dev->write_list.mei_cb.cb_list, cb_list) { + list_del(&cb_pos->cb_list); + mei_free_cb_private(cb_pos); + } +} + + + +/** + * host_start_message - mei host sends start message. + * + * @dev: the device structure + * + * returns none. + */ +void mei_host_start_message(struct mei_device *dev) +{ + struct mei_msg_hdr *mei_hdr; + struct hbm_host_version_request *host_start_req; + + /* host start message */ + mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; + mei_hdr->host_addr = 0; + mei_hdr->me_addr = 0; + mei_hdr->length = sizeof(struct hbm_host_version_request); + mei_hdr->msg_complete = 1; + mei_hdr->reserved = 0; + + host_start_req = + (struct hbm_host_version_request *) &dev->wr_msg_buf[1]; + memset(host_start_req, 0, sizeof(struct hbm_host_version_request)); + host_start_req->hbm_cmd = HOST_START_REQ_CMD; + host_start_req->host_version.major_version = HBM_MAJOR_VERSION; + host_start_req->host_version.minor_version = HBM_MINOR_VERSION; + dev->recvd_msg = false; + if (mei_write_message(dev, mei_hdr, (unsigned char *)host_start_req, + mei_hdr->length)) { + dev_dbg(&dev->pdev->dev, "write send version message to FW fail.\n"); + dev->mei_state = MEI_RESETING; + mei_reset(dev, 1); + } + dev->init_clients_state = MEI_START_MESSAGE; + dev->init_clients_timer = INIT_CLIENTS_TIMEOUT; + return ; +} + +/** + * host_enum_clients_message - host sends enumeration client request message. + * + * @dev: the device structure + * + * returns none. + */ +void mei_host_enum_clients_message(struct mei_device *dev) +{ + struct mei_msg_hdr *mei_hdr; + struct hbm_host_enum_request *host_enum_req; + mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; + /* enumerate clients */ + mei_hdr->host_addr = 0; + mei_hdr->me_addr = 0; + mei_hdr->length = sizeof(struct hbm_host_enum_request); + mei_hdr->msg_complete = 1; + mei_hdr->reserved = 0; + + host_enum_req = (struct hbm_host_enum_request *) &dev->wr_msg_buf[1]; + memset(host_enum_req, 0, sizeof(struct hbm_host_enum_request)); + host_enum_req->hbm_cmd = HOST_ENUM_REQ_CMD; + if (mei_write_message(dev, mei_hdr, (unsigned char *)host_enum_req, + mei_hdr->length)) { + dev->mei_state = MEI_RESETING; + dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n"); + mei_reset(dev, 1); + } + dev->init_clients_state = MEI_ENUM_CLIENTS_MESSAGE; + dev->init_clients_timer = INIT_CLIENTS_TIMEOUT; + return; +} + + +/** + * allocate_me_clients_storage - allocates storage for me clients + * + * @dev: the device structure + * + * returns none. + */ +void mei_allocate_me_clients_storage(struct mei_device *dev) +{ + struct mei_me_client *clients; + int b; + + /* count how many ME clients we have */ + for_each_set_bit(b, dev->me_clients_map, MEI_CLIENTS_MAX) + dev->me_clients_num++; + + if (dev->me_clients_num <= 0) + return ; + + + if (dev->me_clients != NULL) { + kfree(dev->me_clients); + dev->me_clients = NULL; + } + dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%zd.\n", + dev->me_clients_num * sizeof(struct mei_me_client)); + /* allocate storage for ME clients representation */ + clients = kcalloc(dev->me_clients_num, + sizeof(struct mei_me_client), GFP_KERNEL); + if (!clients) { + dev_dbg(&dev->pdev->dev, "memory allocation for ME clients failed.\n"); + dev->mei_state = MEI_RESETING; + mei_reset(dev, 1); + return ; + } + dev->me_clients = clients; + return ; +} +/** + * host_client_properties - reads properties for client + * + * @dev: the device structure + * + * returns: + * < 0 - Error. + * = 0 - no more clients. + * = 1 - still have clients to send properties request. + */ +int mei_host_client_properties(struct mei_device *dev) +{ + struct mei_msg_hdr *mei_header; + struct hbm_props_request *host_cli_req; + int b; + u8 client_num = dev->me_client_presentation_num; + + b = dev->me_client_index; + b = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, b); + if (b < MEI_CLIENTS_MAX) { + dev->me_clients[client_num].client_id = b; + dev->me_clients[client_num].mei_flow_ctrl_creds = 0; + mei_header = (struct mei_msg_hdr *)&dev->wr_msg_buf[0]; + mei_header->host_addr = 0; + mei_header->me_addr = 0; + mei_header->length = sizeof(struct hbm_props_request); + mei_header->msg_complete = 1; + mei_header->reserved = 0; + + host_cli_req = (struct hbm_props_request *)&dev->wr_msg_buf[1]; + + memset(host_cli_req, 0, sizeof(struct hbm_props_request)); + + host_cli_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; + host_cli_req->address = b; + + if (mei_write_message(dev, mei_header, + (unsigned char *)host_cli_req, + mei_header->length)) { + dev->mei_state = MEI_RESETING; + dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n"); + mei_reset(dev, 1); + return -EIO; + } + + dev->init_clients_timer = INIT_CLIENTS_TIMEOUT; + dev->me_client_index = b; + return 1; + } + + return 0; +} + +/** + * mei_init_file_private - initializes private file structure. + * + * @priv: private file structure to be initialized + * @file: the file structure + */ +void mei_cl_init(struct mei_cl *priv, struct mei_device *dev) +{ + memset(priv, 0, sizeof(struct mei_cl)); + init_waitqueue_head(&priv->wait); + init_waitqueue_head(&priv->rx_wait); + init_waitqueue_head(&priv->tx_wait); + INIT_LIST_HEAD(&priv->link); + priv->reading_state = MEI_IDLE; + priv->writing_state = MEI_IDLE; + priv->dev = dev; +} + +int mei_find_me_client_index(const struct mei_device *dev, uuid_le cuuid) +{ + int i, res = -1; + + for (i = 0; i < dev->me_clients_num; ++i) + if (uuid_le_cmp(cuuid, + dev->me_clients[i].props.protocol_name) == 0) { + res = i; + break; + } + + return res; +} + + +/** + * mei_find_me_client_update_filext - searches for ME client guid + * sets client_id in mei_file_private if found + * @dev: the device structure + * @priv: private file structure to set client_id in + * @cguid: searched guid of ME client + * @client_id: id of host client to be set in file private structure + * + * returns ME client index + */ +u8 mei_find_me_client_update_filext(struct mei_device *dev, struct mei_cl *priv, + const uuid_le *cguid, u8 client_id) +{ + int i; + + if (!dev || !priv || !cguid) + return 0; + + /* check for valid client id */ + i = mei_find_me_client_index(dev, *cguid); + if (i >= 0) { + priv->me_client_id = dev->me_clients[i].client_id; + priv->state = MEI_FILE_CONNECTING; + priv->host_client_id = client_id; + + list_add_tail(&priv->link, &dev->file_list); + return (u8)i; + } + + return 0; +} + +/** + * host_init_iamthif - mei initialization iamthif client. + * + * @dev: the device structure + * + */ +void mei_host_init_iamthif(struct mei_device *dev) +{ + u8 i; + unsigned char *msg_buf; + + mei_cl_init(&dev->iamthif_cl, dev); + dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; + + /* find ME amthi client */ + i = mei_find_me_client_update_filext(dev, &dev->iamthif_cl, + &mei_amthi_guid, MEI_IAMTHIF_HOST_CLIENT_ID); + if (dev->iamthif_cl.state != MEI_FILE_CONNECTING) { + dev_dbg(&dev->pdev->dev, "failed to find iamthif client.\n"); + return; + } + + /* Assign iamthif_mtu to the value received from ME */ + + dev->iamthif_mtu = dev->me_clients[i].props.max_msg_length; + dev_dbg(&dev->pdev->dev, "IAMTHIF_MTU = %d\n", + dev->me_clients[i].props.max_msg_length); + + kfree(dev->iamthif_msg_buf); + dev->iamthif_msg_buf = NULL; + + /* allocate storage for ME message buffer */ + msg_buf = kcalloc(dev->iamthif_mtu, + sizeof(unsigned char), GFP_KERNEL); + if (!msg_buf) { + dev_dbg(&dev->pdev->dev, "memory allocation for ME message buffer failed.\n"); + return; + } + + dev->iamthif_msg_buf = msg_buf; + + if (mei_connect(dev, &dev->iamthif_cl)) { + dev_dbg(&dev->pdev->dev, "Failed to connect to AMTHI client\n"); + dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; + dev->iamthif_cl.host_client_id = 0; + } else { + dev->iamthif_cl.timer_count = CONNECT_TIMEOUT; + } +} + +/** + * mei_alloc_file_private - allocates a private file structure and sets it up. + * @file: the file structure + * + * returns The allocated file or NULL on failure + */ +struct mei_cl *mei_cl_allocate(struct mei_device *dev) +{ + struct mei_cl *cl; + + cl = kmalloc(sizeof(struct mei_cl), GFP_KERNEL); + if (!cl) + return NULL; + + mei_cl_init(cl, dev); + + return cl; +} + + + +/** + * mei_disconnect_host_client - sends disconnect message to fw from host client. + * + * @dev: the device structure + * @cl: private data of the file object + * + * Locking: called under "dev->device_lock" lock + * + * returns 0 on success, <0 on failure. + */ +int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl) +{ + int rets, err; + long timeout = 15; /* 15 seconds */ + struct mei_cl_cb *cb; + + if (!dev || !cl) + return -ENODEV; + + if (cl->state != MEI_FILE_DISCONNECTING) + return 0; + + cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); + if (!cb) + return -ENOMEM; + + INIT_LIST_HEAD(&cb->cb_list); + cb->file_private = cl; + cb->major_file_operations = MEI_CLOSE; + if (dev->mei_host_buffer_is_empty) { + dev->mei_host_buffer_is_empty = false; + if (mei_disconnect(dev, cl)) { + rets = -ENODEV; + dev_dbg(&dev->pdev->dev, "failed to call mei_disconnect.\n"); + goto free; + } + mdelay(10); /* Wait for hardware disconnection ready */ + list_add_tail(&cb->cb_list, &dev->ctrl_rd_list.mei_cb.cb_list); + } else { + dev_dbg(&dev->pdev->dev, "add disconnect cb to control write list\n"); + list_add_tail(&cb->cb_list, + &dev->ctrl_wr_list.mei_cb.cb_list); + } + mutex_unlock(&dev->device_lock); + + err = wait_event_timeout(dev->wait_recvd_msg, + (MEI_FILE_DISCONNECTED == cl->state), + timeout * HZ); + + mutex_lock(&dev->device_lock); + if (MEI_FILE_DISCONNECTED == cl->state) { + rets = 0; + dev_dbg(&dev->pdev->dev, "successfully disconnected from FW client.\n"); + } else { + rets = -ENODEV; + if (MEI_FILE_DISCONNECTED != cl->state) + dev_dbg(&dev->pdev->dev, "wrong status client disconnect.\n"); + + if (err) + dev_dbg(&dev->pdev->dev, + "wait failed disconnect err=%08x\n", + err); + + dev_dbg(&dev->pdev->dev, "failed to disconnect from FW client.\n"); + } + + mei_io_list_flush(&dev->ctrl_rd_list, cl); + mei_io_list_flush(&dev->ctrl_wr_list, cl); +free: + mei_free_cb_private(cb); + return rets; +} + +/** + * mei_remove_client_from_file_list - + * removes file private data from device file list + * + * @dev: the device structure + * @host_client_id: host client id to be removed + */ +void mei_remove_client_from_file_list(struct mei_device *dev, + u8 host_client_id) +{ + struct mei_cl *cl_pos = NULL; + struct mei_cl *cl_next = NULL; + list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { + if (host_client_id == cl_pos->host_client_id) { + dev_dbg(&dev->pdev->dev, "remove host client = %d, ME client = %d\n", + cl_pos->host_client_id, + cl_pos->me_client_id); + list_del_init(&cl_pos->link); + break; + } + } +} diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c new file mode 100644 index 0000000..9a2cfaf --- /dev/null +++ b/drivers/misc/mei/interface.c @@ -0,0 +1,428 @@ +/* + * + * Intel Management Engine Interface (Intel MEI) Linux driver + * Copyright (c) 2003-2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include "mei_dev.h" +#include "mei.h" +#include "interface.h" + + + +/** + * mei_set_csr_register - writes H_CSR register to the mei device, + * and ignores the H_IS bit for it is write-one-to-zero. + * + * @dev: the device structure + */ +void mei_hcsr_set(struct mei_device *dev) +{ + if ((dev->host_hw_state & H_IS) == H_IS) + dev->host_hw_state &= ~H_IS; + mei_reg_write(dev, H_CSR, dev->host_hw_state); + dev->host_hw_state = mei_hcsr_read(dev); +} + +/** + * mei_csr_enable_interrupts - enables mei device interrupts + * + * @dev: the device structure + */ +void mei_enable_interrupts(struct mei_device *dev) +{ + dev->host_hw_state |= H_IE; + mei_hcsr_set(dev); +} + +/** + * mei_csr_disable_interrupts - disables mei device interrupts + * + * @dev: the device structure + */ +void mei_disable_interrupts(struct mei_device *dev) +{ + dev->host_hw_state &= ~H_IE; + mei_hcsr_set(dev); +} + +/** + * _host_get_filled_slots - gets number of device filled buffer slots + * + * @device: the device structure + * + * returns number of filled slots + */ +static unsigned char _host_get_filled_slots(const struct mei_device *dev) +{ + char read_ptr, write_ptr; + + read_ptr = (char) ((dev->host_hw_state & H_CBRP) >> 8); + write_ptr = (char) ((dev->host_hw_state & H_CBWP) >> 16); + + return (unsigned char) (write_ptr - read_ptr); +} + +/** + * mei_host_buffer_is_empty - checks if host buffer is empty. + * + * @dev: the device structure + * + * returns 1 if empty, 0 - otherwise. + */ +int mei_host_buffer_is_empty(struct mei_device *dev) +{ + unsigned char filled_slots; + + dev->host_hw_state = mei_hcsr_read(dev); + filled_slots = _host_get_filled_slots(dev); + + if (filled_slots == 0) + return 1; + + return 0; +} + +/** + * mei_count_empty_write_slots - counts write empty slots. + * + * @dev: the device structure + * + * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count + */ +int mei_count_empty_write_slots(struct mei_device *dev) +{ + unsigned char buffer_depth, filled_slots, empty_slots; + + dev->host_hw_state = mei_hcsr_read(dev); + buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24); + filled_slots = _host_get_filled_slots(dev); + empty_slots = buffer_depth - filled_slots; + + /* check for overflow */ + if (filled_slots > buffer_depth) + return -EOVERFLOW; + + return empty_slots; +} + +/** + * mei_write_message - writes a message to mei device. + * + * @dev: the device structure + * @header: header of message + * @write_buffer: message buffer will be written + * @write_length: message size will be written + * + * This function returns -EIO if write has failed + */ +int mei_write_message(struct mei_device *dev, + struct mei_msg_hdr *header, + unsigned char *write_buffer, + unsigned long write_length) +{ + u32 temp_msg = 0; + unsigned long bytes_written = 0; + unsigned char buffer_depth, filled_slots, empty_slots; + unsigned long dw_to_write; + + dev->host_hw_state = mei_hcsr_read(dev); + + dev_dbg(&dev->pdev->dev, + "host_hw_state = 0x%08x.\n", + dev->host_hw_state); + + dev_dbg(&dev->pdev->dev, + "mei_write_message header=%08x.\n", + *((u32 *) header)); + + buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24); + filled_slots = _host_get_filled_slots(dev); + empty_slots = buffer_depth - filled_slots; + dev_dbg(&dev->pdev->dev, + "filled = %hu, empty = %hu.\n", + filled_slots, empty_slots); + + dw_to_write = ((write_length + 3) / 4); + + if (dw_to_write > empty_slots) + return -EIO; + + mei_reg_write(dev, H_CB_WW, *((u32 *) header)); + + while (write_length >= 4) { + mei_reg_write(dev, H_CB_WW, + *(u32 *) (write_buffer + bytes_written)); + bytes_written += 4; + write_length -= 4; + } + + if (write_length > 0) { + memcpy(&temp_msg, &write_buffer[bytes_written], write_length); + mei_reg_write(dev, H_CB_WW, temp_msg); + } + + dev->host_hw_state |= H_IG; + mei_hcsr_set(dev); + dev->me_hw_state = mei_mecsr_read(dev); + if ((dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA) + return -EIO; + + return 0; +} + +/** + * mei_count_full_read_slots - counts read full slots. + * + * @dev: the device structure + * + * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise filled slots count + */ +int mei_count_full_read_slots(struct mei_device *dev) +{ + char read_ptr, write_ptr; + unsigned char buffer_depth, filled_slots; + + dev->me_hw_state = mei_mecsr_read(dev); + buffer_depth = (unsigned char)((dev->me_hw_state & ME_CBD_HRA) >> 24); + read_ptr = (char) ((dev->me_hw_state & ME_CBRP_HRA) >> 8); + write_ptr = (char) ((dev->me_hw_state & ME_CBWP_HRA) >> 16); + filled_slots = (unsigned char) (write_ptr - read_ptr); + + /* check for overflow */ + if (filled_slots > buffer_depth) + return -EOVERFLOW; + + dev_dbg(&dev->pdev->dev, "filled_slots =%08x\n", filled_slots); + return (int)filled_slots; +} + +/** + * mei_read_slots - reads a message from mei device. + * + * @dev: the device structure + * @buffer: message buffer will be written + * @buffer_length: message size will be read + */ +void mei_read_slots(struct mei_device *dev, unsigned char *buffer, + unsigned long buffer_length) +{ + u32 *reg_buf = (u32 *)buffer; + + for (; buffer_length >= sizeof(u32); buffer_length -= sizeof(u32)) + *reg_buf++ = mei_mecbrw_read(dev); + + if (buffer_length > 0) { + u32 reg = mei_mecbrw_read(dev); + memcpy(reg_buf, ®, buffer_length); + } + + dev->host_hw_state |= H_IG; + mei_hcsr_set(dev); +} + +/** + * mei_flow_ctrl_creds - checks flow_control credentials. + * + * @dev: the device structure + * @cl: private data of the file object + * + * returns 1 if mei_flow_ctrl_creds >0, 0 - otherwise. + * -ENOENT if mei_cl is not present + * -EINVAL if single_recv_buf == 0 + */ +int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl) +{ + int i; + + if (!dev->me_clients_num) + return 0; + + if (cl->mei_flow_ctrl_creds > 0) + return 1; + + for (i = 0; i < dev->me_clients_num; i++) { + struct mei_me_client *me_cl = &dev->me_clients[i]; + if (me_cl->client_id == cl->me_client_id) { + if (me_cl->mei_flow_ctrl_creds) { + if (WARN_ON(me_cl->props.single_recv_buf == 0)) + return -EINVAL; + return 1; + } else { + return 0; + } + } + } + return -ENOENT; +} + +/** + * mei_flow_ctrl_reduce - reduces flow_control. + * + * @dev: the device structure + * @cl: private data of the file object + * @returns + * 0 on success + * -ENOENT when me client is not found + * -EINVAL when ctrl credits are <= 0 + */ +int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl) +{ + int i; + + if (!dev->me_clients_num) + return -ENOENT; + + for (i = 0; i < dev->me_clients_num; i++) { + struct mei_me_client *me_cl = &dev->me_clients[i]; + if (me_cl->client_id == cl->me_client_id) { + if (me_cl->props.single_recv_buf != 0) { + if (WARN_ON(me_cl->mei_flow_ctrl_creds <= 0)) + return -EINVAL; + dev->me_clients[i].mei_flow_ctrl_creds--; + } else { + if (WARN_ON(cl->mei_flow_ctrl_creds <= 0)) + return -EINVAL; + cl->mei_flow_ctrl_creds--; + } + return 0; + } + } + return -ENOENT; +} + +/** + * mei_send_flow_control - sends flow control to fw. + * + * @dev: the device structure + * @cl: private data of the file object + * + * This function returns -EIO on write failure + */ +int mei_send_flow_control(struct mei_device *dev, struct mei_cl *cl) +{ + struct mei_msg_hdr *mei_hdr; + struct hbm_flow_control *mei_flow_control; + + mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; + mei_hdr->host_addr = 0; + mei_hdr->me_addr = 0; + mei_hdr->length = sizeof(struct hbm_flow_control); + mei_hdr->msg_complete = 1; + mei_hdr->reserved = 0; + + mei_flow_control = (struct hbm_flow_control *) &dev->wr_msg_buf[1]; + memset(mei_flow_control, 0, sizeof(*mei_flow_control)); + mei_flow_control->host_addr = cl->host_client_id; + mei_flow_control->me_addr = cl->me_client_id; + mei_flow_control->hbm_cmd = MEI_FLOW_CONTROL_CMD; + memset(mei_flow_control->reserved, 0, + sizeof(mei_flow_control->reserved)); + dev_dbg(&dev->pdev->dev, "sending flow control host client = %d, ME client = %d\n", + cl->host_client_id, cl->me_client_id); + + return mei_write_message(dev, mei_hdr, + (unsigned char *) mei_flow_control, + sizeof(struct hbm_flow_control)); +} + +/** + * mei_other_client_is_connecting - checks if other + * client with the same client id is connected. + * + * @dev: the device structure + * @cl: private data of the file object + * + * returns 1 if other client is connected, 0 - otherwise. + */ +int mei_other_client_is_connecting(struct mei_device *dev, + struct mei_cl *cl) +{ + struct mei_cl *cl_pos = NULL; + struct mei_cl *cl_next = NULL; + + list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { + if ((cl_pos->state == MEI_FILE_CONNECTING) && + (cl_pos != cl) && + cl->me_client_id == cl_pos->me_client_id) + return 1; + + } + return 0; +} + +/** + * mei_disconnect - sends disconnect message to fw. + * + * @dev: the device structure + * @cl: private data of the file object + * + * This function returns -EIO on write failure + */ +int mei_disconnect(struct mei_device *dev, struct mei_cl *cl) +{ + struct mei_msg_hdr *mei_hdr; + struct hbm_client_disconnect_request *mei_cli_disconnect; + + mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; + mei_hdr->host_addr = 0; + mei_hdr->me_addr = 0; + mei_hdr->length = sizeof(struct hbm_client_disconnect_request); + mei_hdr->msg_complete = 1; + mei_hdr->reserved = 0; + + mei_cli_disconnect = + (struct hbm_client_disconnect_request *) &dev->wr_msg_buf[1]; + memset(mei_cli_disconnect, 0, sizeof(*mei_cli_disconnect)); + mei_cli_disconnect->host_addr = cl->host_client_id; + mei_cli_disconnect->me_addr = cl->me_client_id; + mei_cli_disconnect->hbm_cmd = CLIENT_DISCONNECT_REQ_CMD; + mei_cli_disconnect->reserved[0] = 0; + + return mei_write_message(dev, mei_hdr, + (unsigned char *) mei_cli_disconnect, + sizeof(struct hbm_client_disconnect_request)); +} + +/** + * mei_connect - sends connect message to fw. + * + * @dev: the device structure + * @cl: private data of the file object + * + * This function returns -EIO on write failure + */ +int mei_connect(struct mei_device *dev, struct mei_cl *cl) +{ + struct mei_msg_hdr *mei_hdr; + struct hbm_client_connect_request *mei_cli_connect; + + mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; + mei_hdr->host_addr = 0; + mei_hdr->me_addr = 0; + mei_hdr->length = sizeof(struct hbm_client_connect_request); + mei_hdr->msg_complete = 1; + mei_hdr->reserved = 0; + + mei_cli_connect = + (struct hbm_client_connect_request *) &dev->wr_msg_buf[1]; + mei_cli_connect->host_addr = cl->host_client_id; + mei_cli_connect->me_addr = cl->me_client_id; + mei_cli_connect->hbm_cmd = CLIENT_CONNECT_REQ_CMD; + mei_cli_connect->reserved = 0; + + return mei_write_message(dev, mei_hdr, + (unsigned char *) mei_cli_connect, + sizeof(struct hbm_client_connect_request)); +} diff --git a/drivers/misc/mei/interface.h b/drivers/misc/mei/interface.h new file mode 100644 index 0000000..0d00435 --- /dev/null +++ b/drivers/misc/mei/interface.h @@ -0,0 +1,75 @@ +/* + * + * Intel Management Engine Interface (Intel MEI) Linux driver + * Copyright (c) 2003-2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + + + +#ifndef _MEI_INTERFACE_H_ +#define _MEI_INTERFACE_H_ + +#include "mei.h" +#include "mei_dev.h" + + +#define AMT_WD_DEFAULT_TIMEOUT 120 /* seconds */ +#define AMT_WD_MIN_TIMEOUT 120 /* seconds */ +#define AMT_WD_MAX_TIMEOUT 65535 /* seconds */ + +#define MEI_WATCHDOG_DATA_SIZE 16 +#define MEI_START_WD_DATA_SIZE 20 +#define MEI_WD_PARAMS_SIZE 4 + + +void mei_read_slots(struct mei_device *dev, + unsigned char *buffer, + unsigned long buffer_length); + +int mei_write_message(struct mei_device *dev, + struct mei_msg_hdr *header, + unsigned char *write_buffer, + unsigned long write_length); + +int mei_host_buffer_is_empty(struct mei_device *dev); + +int mei_count_full_read_slots(struct mei_device *dev); + +int mei_count_empty_write_slots(struct mei_device *dev); + +int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl); + +int mei_wd_send(struct mei_device *dev); +int mei_wd_stop(struct mei_device *dev, bool preserve); +int mei_wd_host_init(struct mei_device *dev); +/* + * mei_watchdog_register - Registering watchdog interface + * once we got connection to the WD Client + * @dev - mei device + */ +void mei_watchdog_register(struct mei_device *dev); +/* + * mei_watchdog_unregister - Unregistering watchdog interface + * @dev - mei device + */ +void mei_watchdog_unregister(struct mei_device *dev); + +int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl); + +int mei_send_flow_control(struct mei_device *dev, struct mei_cl *cl); + +int mei_disconnect(struct mei_device *dev, struct mei_cl *cl); +int mei_other_client_is_connecting(struct mei_device *dev, struct mei_cl *cl); +int mei_connect(struct mei_device *dev, struct mei_cl *cl); + +#endif /* _MEI_INTERFACE_H_ */ diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c new file mode 100644 index 0000000..2007d24 --- /dev/null +++ b/drivers/misc/mei/interrupt.c @@ -0,0 +1,1590 @@ +/* + * + * Intel Management Engine Interface (Intel MEI) Linux driver + * Copyright (c) 2003-2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + + +#include +#include +#include +#include +#include + +#include "mei_dev.h" +#include "mei.h" +#include "hw.h" +#include "interface.h" + + +/** + * mei_interrupt_quick_handler - The ISR of the MEI device + * + * @irq: The irq number + * @dev_id: pointer to the device structure + * + * returns irqreturn_t + */ +irqreturn_t mei_interrupt_quick_handler(int irq, void *dev_id) +{ + struct mei_device *dev = (struct mei_device *) dev_id; + u32 csr_reg = mei_hcsr_read(dev); + + if ((csr_reg & H_IS) != H_IS) + return IRQ_NONE; + + /* clear H_IS bit in H_CSR */ + mei_reg_write(dev, H_CSR, csr_reg); + + return IRQ_WAKE_THREAD; +} + +/** + * _mei_cmpl - processes completed operation. + * + * @cl: private data of the file object. + * @cb_pos: callback block. + */ +static void _mei_cmpl(struct mei_cl *cl, struct mei_cl_cb *cb_pos) +{ + if (cb_pos->major_file_operations == MEI_WRITE) { + mei_free_cb_private(cb_pos); + cb_pos = NULL; + cl->writing_state = MEI_WRITE_COMPLETE; + if (waitqueue_active(&cl->tx_wait)) + wake_up_interruptible(&cl->tx_wait); + + } else if (cb_pos->major_file_operations == MEI_READ && + MEI_READING == cl->reading_state) { + cl->reading_state = MEI_READ_COMPLETE; + if (waitqueue_active(&cl->rx_wait)) + wake_up_interruptible(&cl->rx_wait); + + } +} + +/** + * _mei_cmpl_iamthif - processes completed iamthif operation. + * + * @dev: the device structure. + * @cb_pos: callback block. + */ +static void _mei_cmpl_iamthif(struct mei_device *dev, struct mei_cl_cb *cb_pos) +{ + if (dev->iamthif_canceled != 1) { + dev->iamthif_state = MEI_IAMTHIF_READ_COMPLETE; + dev->iamthif_stall_timer = 0; + memcpy(cb_pos->response_buffer.data, + dev->iamthif_msg_buf, + dev->iamthif_msg_buf_index); + list_add_tail(&cb_pos->cb_list, + &dev->amthi_read_complete_list.mei_cb.cb_list); + dev_dbg(&dev->pdev->dev, "amthi read completed.\n"); + dev->iamthif_timer = jiffies; + dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n", + dev->iamthif_timer); + } else { + mei_run_next_iamthif_cmd(dev); + } + + dev_dbg(&dev->pdev->dev, "completing amthi call back.\n"); + wake_up_interruptible(&dev->iamthif_cl.wait); +} + + +/** + * mei_irq_thread_read_amthi_message - bottom half read routine after ISR to + * handle the read amthi message data processing. + * + * @complete_list: An instance of our list structure + * @dev: the device structure + * @mei_hdr: header of amthi message + * + * returns 0 on success, <0 on failure. + */ +static int mei_irq_thread_read_amthi_message(struct mei_io_list *complete_list, + struct mei_device *dev, + struct mei_msg_hdr *mei_hdr) +{ + struct mei_cl *cl; + struct mei_cl_cb *cb; + unsigned char *buffer; + + BUG_ON(mei_hdr->me_addr != dev->iamthif_cl.me_client_id); + BUG_ON(dev->iamthif_state != MEI_IAMTHIF_READING); + + buffer = dev->iamthif_msg_buf + dev->iamthif_msg_buf_index; + BUG_ON(dev->iamthif_mtu < dev->iamthif_msg_buf_index + mei_hdr->length); + + mei_read_slots(dev, buffer, mei_hdr->length); + + dev->iamthif_msg_buf_index += mei_hdr->length; + + if (!mei_hdr->msg_complete) + return 0; + + dev_dbg(&dev->pdev->dev, + "amthi_message_buffer_index =%d\n", + mei_hdr->length); + + dev_dbg(&dev->pdev->dev, "completed amthi read.\n "); + if (!dev->iamthif_current_cb) + return -ENODEV; + + cb = dev->iamthif_current_cb; + dev->iamthif_current_cb = NULL; + + cl = (struct mei_cl *)cb->file_private; + if (!cl) + return -ENODEV; + + dev->iamthif_stall_timer = 0; + cb->information = dev->iamthif_msg_buf_index; + cb->read_time = jiffies; + if (dev->iamthif_ioctl && cl == &dev->iamthif_cl) { + /* found the iamthif cb */ + dev_dbg(&dev->pdev->dev, "complete the amthi read cb.\n "); + dev_dbg(&dev->pdev->dev, "add the amthi read cb to complete.\n "); + list_add_tail(&cb->cb_list, + &complete_list->mei_cb.cb_list); + } + return 0; +} + +/** + * _mei_irq_thread_state_ok - checks if mei header matches file private data + * + * @cl: private data of the file object + * @mei_hdr: header of mei client message + * + * returns !=0 if matches, 0 if no match. + */ +static int _mei_irq_thread_state_ok(struct mei_cl *cl, + struct mei_msg_hdr *mei_hdr) +{ + return (cl->host_client_id == mei_hdr->host_addr && + cl->me_client_id == mei_hdr->me_addr && + cl->state == MEI_FILE_CONNECTED && + MEI_READ_COMPLETE != cl->reading_state); +} + +/** + * mei_irq_thread_read_client_message - bottom half read routine after ISR to + * handle the read mei client message data processing. + * + * @complete_list: An instance of our list structure + * @dev: the device structure + * @mei_hdr: header of mei client message + * + * returns 0 on success, <0 on failure. + */ +static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list, + struct mei_device *dev, + struct mei_msg_hdr *mei_hdr) +{ + struct mei_cl *cl; + struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; + unsigned char *buffer = NULL; + + dev_dbg(&dev->pdev->dev, "start client msg\n"); + if (list_empty(&dev->read_list.mei_cb.cb_list)) + goto quit; + + list_for_each_entry_safe(cb_pos, cb_next, + &dev->read_list.mei_cb.cb_list, cb_list) { + cl = (struct mei_cl *)cb_pos->file_private; + if (cl && _mei_irq_thread_state_ok(cl, mei_hdr)) { + cl->reading_state = MEI_READING; + buffer = cb_pos->response_buffer.data + cb_pos->information; + + if (cb_pos->response_buffer.size < + mei_hdr->length + cb_pos->information) { + dev_dbg(&dev->pdev->dev, "message overflow.\n"); + list_del(&cb_pos->cb_list); + return -ENOMEM; + } + if (buffer) + mei_read_slots(dev, buffer, mei_hdr->length); + + cb_pos->information += mei_hdr->length; + if (mei_hdr->msg_complete) { + cl->status = 0; + list_del(&cb_pos->cb_list); + dev_dbg(&dev->pdev->dev, + "completed read host client = %d," + "ME client = %d, " + "data length = %lu\n", + cl->host_client_id, + cl->me_client_id, + cb_pos->information); + + *(cb_pos->response_buffer.data + + cb_pos->information) = '\0'; + dev_dbg(&dev->pdev->dev, "cb_pos->res_buffer - %s\n", + cb_pos->response_buffer.data); + list_add_tail(&cb_pos->cb_list, + &complete_list->mei_cb.cb_list); + } + + break; + } + + } + +quit: + dev_dbg(&dev->pdev->dev, "message read\n"); + if (!buffer) { + mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length); + dev_dbg(&dev->pdev->dev, "discarding message, header =%08x.\n", + *(u32 *) dev->rd_msg_buf); + } + + return 0; +} + +/** + * _mei_irq_thread_iamthif_read - prepares to read iamthif data. + * + * @dev: the device structure. + * @slots: free slots. + * + * returns 0, OK; otherwise, error. + */ +static int _mei_irq_thread_iamthif_read(struct mei_device *dev, s32 *slots) +{ + + if (((*slots) * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + + sizeof(struct hbm_flow_control))) { + return -EMSGSIZE; + } + *slots -= (sizeof(struct mei_msg_hdr) + + sizeof(struct hbm_flow_control) + 3) / 4; + if (mei_send_flow_control(dev, &dev->iamthif_cl)) { + dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n"); + return -EIO; + } + + dev_dbg(&dev->pdev->dev, "iamthif flow control success\n"); + dev->iamthif_state = MEI_IAMTHIF_READING; + dev->iamthif_flow_control_pending = false; + dev->iamthif_msg_buf_index = 0; + dev->iamthif_msg_buf_size = 0; + dev->iamthif_stall_timer = IAMTHIF_STALL_TIMER; + dev->mei_host_buffer_is_empty = mei_host_buffer_is_empty(dev); + return 0; +} + +/** + * _mei_irq_thread_close - processes close related operation. + * + * @dev: the device structure. + * @slots: free slots. + * @cb_pos: callback block. + * @cl: private data of the file object. + * @cmpl_list: complete list. + * + * returns 0, OK; otherwise, error. + */ +static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots, + struct mei_cl_cb *cb_pos, + struct mei_cl *cl, + struct mei_io_list *cmpl_list) +{ + if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + + sizeof(struct hbm_client_disconnect_request))) { + *slots -= (sizeof(struct mei_msg_hdr) + + sizeof(struct hbm_client_disconnect_request) + 3) / 4; + + if (mei_disconnect(dev, cl)) { + cl->status = 0; + cb_pos->information = 0; + list_move_tail(&cb_pos->cb_list, + &cmpl_list->mei_cb.cb_list); + return -EMSGSIZE; + } else { + cl->state = MEI_FILE_DISCONNECTING; + cl->status = 0; + cb_pos->information = 0; + list_move_tail(&cb_pos->cb_list, + &dev->ctrl_rd_list.mei_cb.cb_list); + cl->timer_count = MEI_CONNECT_TIMEOUT; + } + } else { + /* return the cancel routine */ + return -EBADMSG; + } + + return 0; +} + +/** + * is_treat_specially_client - checks if the message belongs + * to the file private data. + * + * @cl: private data of the file object + * @rs: connect response bus message + * + */ +static bool is_treat_specially_client(struct mei_cl *cl, + struct hbm_client_connect_response *rs) +{ + + if (cl->host_client_id == rs->host_addr && + cl->me_client_id == rs->me_addr) { + if (!rs->status) { + cl->state = MEI_FILE_CONNECTED; + cl->status = 0; + + } else { + cl->state = MEI_FILE_DISCONNECTED; + cl->status = -ENODEV; + } + cl->timer_count = 0; + + return true; + } + return false; +} + +/** + * mei_client_connect_response - connects to response irq routine + * + * @dev: the device structure + * @rs: connect response bus message + */ +static void mei_client_connect_response(struct mei_device *dev, + struct hbm_client_connect_response *rs) +{ + + struct mei_cl *cl; + struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; + + dev_dbg(&dev->pdev->dev, + "connect_response:\n" + "ME Client = %d\n" + "Host Client = %d\n" + "Status = %d\n", + rs->me_addr, + rs->host_addr, + rs->status); + + /* if WD or iamthif client treat specially */ + + if (is_treat_specially_client(&(dev->wd_cl), rs)) { + dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n"); + mei_watchdog_register(dev); + + /* next step in the state maching */ + mei_host_init_iamthif(dev); + return; + } + + if (is_treat_specially_client(&(dev->iamthif_cl), rs)) { + dev->iamthif_state = MEI_IAMTHIF_IDLE; + return; + } + list_for_each_entry_safe(cb_pos, cb_next, + &dev->ctrl_rd_list.mei_cb.cb_list, cb_list) { + + cl = (struct mei_cl *)cb_pos->file_private; + if (!cl) { + list_del(&cb_pos->cb_list); + return; + } + if (MEI_IOCTL == cb_pos->major_file_operations) { + if (is_treat_specially_client(cl, rs)) { + list_del(&cb_pos->cb_list); + cl->status = 0; + cl->timer_count = 0; + break; + } + } + } +} + +/** + * mei_client_disconnect_response - disconnects from response irq routine + * + * @dev: the device structure + * @rs: disconnect response bus message + */ +static void mei_client_disconnect_response(struct mei_device *dev, + struct hbm_client_connect_response *rs) +{ + struct mei_cl *cl; + struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; + + dev_dbg(&dev->pdev->dev, + "disconnect_response:\n" + "ME Client = %d\n" + "Host Client = %d\n" + "Status = %d\n", + rs->me_addr, + rs->host_addr, + rs->status); + + list_for_each_entry_safe(cb_pos, cb_next, + &dev->ctrl_rd_list.mei_cb.cb_list, cb_list) { + cl = (struct mei_cl *)cb_pos->file_private; + + if (!cl) { + list_del(&cb_pos->cb_list); + return; + } + + dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in ctrl_rd_list.\n"); + if (cl->host_client_id == rs->host_addr && + cl->me_client_id == rs->me_addr) { + + list_del(&cb_pos->cb_list); + if (!rs->status) + cl->state = MEI_FILE_DISCONNECTED; + + cl->status = 0; + cl->timer_count = 0; + break; + } + } +} + +/** + * same_flow_addr - tells if they have the same address. + * + * @file: private data of the file object. + * @flow: flow control. + * + * returns !=0, same; 0,not. + */ +static int same_flow_addr(struct mei_cl *cl, struct hbm_flow_control *flow) +{ + return (cl->host_client_id == flow->host_addr && + cl->me_client_id == flow->me_addr); +} + +/** + * add_single_flow_creds - adds single buffer credentials. + * + * @file: private data ot the file object. + * @flow: flow control. + */ +static void add_single_flow_creds(struct mei_device *dev, + struct hbm_flow_control *flow) +{ + struct mei_me_client *client; + int i; + + for (i = 0; i < dev->me_clients_num; i++) { + client = &dev->me_clients[i]; + if (client && flow->me_addr == client->client_id) { + if (client->props.single_recv_buf) { + client->mei_flow_ctrl_creds++; + dev_dbg(&dev->pdev->dev, "recv flow ctrl msg ME %d (single).\n", + flow->me_addr); + dev_dbg(&dev->pdev->dev, "flow control credentials =%d.\n", + client->mei_flow_ctrl_creds); + } else { + BUG(); /* error in flow control */ + } + } + } +} + +/** + * mei_client_flow_control_response - flow control response irq routine + * + * @dev: the device structure + * @flow_control: flow control response bus message + */ +static void mei_client_flow_control_response(struct mei_device *dev, + struct hbm_flow_control *flow_control) +{ + struct mei_cl *cl_pos = NULL; + struct mei_cl *cl_next = NULL; + + if (!flow_control->host_addr) { + /* single receive buffer */ + add_single_flow_creds(dev, flow_control); + } else { + /* normal connection */ + list_for_each_entry_safe(cl_pos, cl_next, + &dev->file_list, link) { + dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in file_list\n"); + + dev_dbg(&dev->pdev->dev, "cl of host client %d ME client %d.\n", + cl_pos->host_client_id, + cl_pos->me_client_id); + dev_dbg(&dev->pdev->dev, "flow ctrl msg for host %d ME %d.\n", + flow_control->host_addr, + flow_control->me_addr); + if (same_flow_addr(cl_pos, flow_control)) { + dev_dbg(&dev->pdev->dev, "recv ctrl msg for host %d ME %d.\n", + flow_control->host_addr, + flow_control->me_addr); + cl_pos->mei_flow_ctrl_creds++; + dev_dbg(&dev->pdev->dev, "flow control credentials = %d.\n", + cl_pos->mei_flow_ctrl_creds); + break; + } + } + } +} + +/** + * same_disconn_addr - tells if they have the same address + * + * @file: private data of the file object. + * @disconn: disconnection request. + * + * returns !=0, same; 0,not. + */ +static int same_disconn_addr(struct mei_cl *cl, + struct hbm_client_disconnect_request *disconn) +{ + return (cl->host_client_id == disconn->host_addr && + cl->me_client_id == disconn->me_addr); +} + +/** + * mei_client_disconnect_request - disconnects from request irq routine + * + * @dev: the device structure. + * @disconnect_req: disconnect request bus message. + */ +static void mei_client_disconnect_request(struct mei_device *dev, + struct hbm_client_disconnect_request *disconnect_req) +{ + struct mei_msg_hdr *mei_hdr; + struct hbm_client_connect_response *disconnect_res; + struct mei_cl *cl_pos = NULL; + struct mei_cl *cl_next = NULL; + + list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { + if (same_disconn_addr(cl_pos, disconnect_req)) { + dev_dbg(&dev->pdev->dev, "disconnect request host client %d ME client %d.\n", + disconnect_req->host_addr, + disconnect_req->me_addr); + cl_pos->state = MEI_FILE_DISCONNECTED; + cl_pos->timer_count = 0; + if (cl_pos == &dev->wd_cl) { + dev->wd_due_counter = 0; + dev->wd_pending = false; + } else if (cl_pos == &dev->iamthif_cl) + dev->iamthif_timer = 0; + + /* prepare disconnect response */ + mei_hdr = + (struct mei_msg_hdr *) &dev->ext_msg_buf[0]; + mei_hdr->host_addr = 0; + mei_hdr->me_addr = 0; + mei_hdr->length = + sizeof(struct hbm_client_connect_response); + mei_hdr->msg_complete = 1; + mei_hdr->reserved = 0; + + disconnect_res = + (struct hbm_client_connect_response *) + &dev->ext_msg_buf[1]; + disconnect_res->host_addr = cl_pos->host_client_id; + disconnect_res->me_addr = cl_pos->me_client_id; + disconnect_res->hbm_cmd = CLIENT_DISCONNECT_RES_CMD; + disconnect_res->status = 0; + dev->extra_write_index = 2; + break; + } + } +} + + +/** + * mei_irq_thread_read_bus_message - bottom half read routine after ISR to + * handle the read bus message cmd processing. + * + * @dev: the device structure + * @mei_hdr: header of bus message + */ +static void mei_irq_thread_read_bus_message(struct mei_device *dev, + struct mei_msg_hdr *mei_hdr) +{ + struct mei_bus_message *mei_msg; + struct hbm_host_version_response *version_res; + struct hbm_client_connect_response *connect_res; + struct hbm_client_connect_response *disconnect_res; + struct hbm_flow_control *flow_control; + struct hbm_props_response *props_res; + struct hbm_host_enum_response *enum_res; + struct hbm_client_disconnect_request *disconnect_req; + struct hbm_host_stop_request *host_stop_req; + int res; + + + /* read the message to our buffer */ + BUG_ON(mei_hdr->length >= sizeof(dev->rd_msg_buf)); + mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length); + mei_msg = (struct mei_bus_message *)dev->rd_msg_buf; + + switch (mei_msg->hbm_cmd) { + case HOST_START_RES_CMD: + version_res = (struct hbm_host_version_response *) mei_msg; + if (version_res->host_version_supported) { + dev->version.major_version = HBM_MAJOR_VERSION; + dev->version.minor_version = HBM_MINOR_VERSION; + if (dev->mei_state == MEI_INIT_CLIENTS && + dev->init_clients_state == MEI_START_MESSAGE) { + dev->init_clients_timer = 0; + mei_host_enum_clients_message(dev); + } else { + dev->recvd_msg = false; + dev_dbg(&dev->pdev->dev, "IMEI reset due to received host start response bus message.\n"); + mei_reset(dev, 1); + return; + } + } else { + dev->version = version_res->me_max_version; + /* send stop message */ + mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0]; + mei_hdr->host_addr = 0; + mei_hdr->me_addr = 0; + mei_hdr->length = sizeof(struct hbm_host_stop_request); + mei_hdr->msg_complete = 1; + mei_hdr->reserved = 0; + + host_stop_req = (struct hbm_host_stop_request *) + &dev->wr_msg_buf[1]; + + memset(host_stop_req, + 0, + sizeof(struct hbm_host_stop_request)); + host_stop_req->hbm_cmd = HOST_STOP_REQ_CMD; + host_stop_req->reason = DRIVER_STOP_REQUEST; + mei_write_message(dev, mei_hdr, + (unsigned char *) (host_stop_req), + mei_hdr->length); + dev_dbg(&dev->pdev->dev, "version mismatch.\n"); + return; + } + + dev->recvd_msg = true; + dev_dbg(&dev->pdev->dev, "host start response message received.\n"); + break; + + case CLIENT_CONNECT_RES_CMD: + connect_res = + (struct hbm_client_connect_response *) mei_msg; + mei_client_connect_response(dev, connect_res); + dev_dbg(&dev->pdev->dev, "client connect response message received.\n"); + wake_up(&dev->wait_recvd_msg); + break; + + case CLIENT_DISCONNECT_RES_CMD: + disconnect_res = + (struct hbm_client_connect_response *) mei_msg; + mei_client_disconnect_response(dev, disconnect_res); + dev_dbg(&dev->pdev->dev, "client disconnect response message received.\n"); + wake_up(&dev->wait_recvd_msg); + break; + + case MEI_FLOW_CONTROL_CMD: + flow_control = (struct hbm_flow_control *) mei_msg; + mei_client_flow_control_response(dev, flow_control); + dev_dbg(&dev->pdev->dev, "client flow control response message received.\n"); + break; + + case HOST_CLIENT_PROPERTIES_RES_CMD: + props_res = (struct hbm_props_response *)mei_msg; + if (props_res->status || !dev->me_clients) { + dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n"); + mei_reset(dev, 1); + return; + } + if (dev->me_clients[dev->me_client_presentation_num] + .client_id == props_res->address) { + + dev->me_clients[dev->me_client_presentation_num].props + = props_res->client_properties; + + if (dev->mei_state == MEI_INIT_CLIENTS && + dev->init_clients_state == + MEI_CLIENT_PROPERTIES_MESSAGE) { + dev->me_client_index++; + dev->me_client_presentation_num++; + + /** Send Client Properties request **/ + res = mei_host_client_properties(dev); + if (res < 0) { + dev_dbg(&dev->pdev->dev, "mei_host_client_properties() failed"); + return; + } else if (!res) { + /* + * No more clients to send to. + * Clear Map for indicating now ME clients + * with associated host client + */ + bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX); + dev->open_handle_count = 0; + + /* + * Reserving the first three client IDs + * Client Id 0 - Reserved for MEI Bus Message communications + * Client Id 1 - Reserved for Watchdog + * Client ID 2 - Reserved for AMTHI + */ + bitmap_set(dev->host_clients_map, 0, 3); + dev->mei_state = MEI_ENABLED; + + /* if wd initialization fails, initialization the AMTHI client, + * otherwise the AMTHI client will be initialized after the WD client connect response + * will be received + */ + if (mei_wd_host_init(dev)) + mei_host_init_iamthif(dev); + } + + } else { + dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message"); + mei_reset(dev, 1); + return; + } + } else { + dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message for wrong client ID\n"); + mei_reset(dev, 1); + return; + } + break; + + case HOST_ENUM_RES_CMD: + enum_res = (struct hbm_host_enum_response *) mei_msg; + memcpy(dev->me_clients_map, enum_res->valid_addresses, 32); + if (dev->mei_state == MEI_INIT_CLIENTS && + dev->init_clients_state == MEI_ENUM_CLIENTS_MESSAGE) { + dev->init_clients_timer = 0; + dev->me_client_presentation_num = 0; + dev->me_client_index = 0; + mei_allocate_me_clients_storage(dev); + dev->init_clients_state = + MEI_CLIENT_PROPERTIES_MESSAGE; + mei_host_client_properties(dev); + } else { + dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n"); + mei_reset(dev, 1); + return; + } + break; + + case HOST_STOP_RES_CMD: + dev->mei_state = MEI_DISABLED; + dev_dbg(&dev->pdev->dev, "resetting because of FW stop response.\n"); + mei_reset(dev, 1); + break; + + case CLIENT_DISCONNECT_REQ_CMD: + /* search for client */ + disconnect_req = + (struct hbm_client_disconnect_request *) mei_msg; + mei_client_disconnect_request(dev, disconnect_req); + break; + + case ME_STOP_REQ_CMD: + /* prepare stop request */ + mei_hdr = (struct mei_msg_hdr *) &dev->ext_msg_buf[0]; + mei_hdr->host_addr = 0; + mei_hdr->me_addr = 0; + mei_hdr->length = sizeof(struct hbm_host_stop_request); + mei_hdr->msg_complete = 1; + mei_hdr->reserved = 0; + host_stop_req = + (struct hbm_host_stop_request *) &dev->ext_msg_buf[1]; + memset(host_stop_req, 0, sizeof(struct hbm_host_stop_request)); + host_stop_req->hbm_cmd = HOST_STOP_REQ_CMD; + host_stop_req->reason = DRIVER_STOP_REQUEST; + host_stop_req->reserved[0] = 0; + host_stop_req->reserved[1] = 0; + dev->extra_write_index = 2; + break; + + default: + BUG(); + break; + + } +} + + +/** + * _mei_hb_read - processes read related operation. + * + * @dev: the device structure. + * @slots: free slots. + * @cb_pos: callback block. + * @cl: private data of the file object. + * @cmpl_list: complete list. + * + * returns 0, OK; otherwise, error. + */ +static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots, + struct mei_cl_cb *cb_pos, + struct mei_cl *cl, + struct mei_io_list *cmpl_list) +{ + if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + + sizeof(struct hbm_flow_control))) { + /* return the cancel routine */ + list_del(&cb_pos->cb_list); + return -EBADMSG; + } + + *slots -= (sizeof(struct mei_msg_hdr) + + sizeof(struct hbm_flow_control) + 3) / 4; + if (mei_send_flow_control(dev, cl)) { + cl->status = -ENODEV; + cb_pos->information = 0; + list_move_tail(&cb_pos->cb_list, &cmpl_list->mei_cb.cb_list); + return -ENODEV; + } + list_move_tail(&cb_pos->cb_list, &dev->read_list.mei_cb.cb_list); + + return 0; +} + + +/** + * _mei_irq_thread_ioctl - processes ioctl related operation. + * + * @dev: the device structure. + * @slots: free slots. + * @cb_pos: callback block. + * @cl: private data of the file object. + * @cmpl_list: complete list. + * + * returns 0, OK; otherwise, error. + */ +static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots, + struct mei_cl_cb *cb_pos, + struct mei_cl *cl, + struct mei_io_list *cmpl_list) +{ + if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + + sizeof(struct hbm_client_connect_request))) { + cl->state = MEI_FILE_CONNECTING; + *slots -= (sizeof(struct mei_msg_hdr) + + sizeof(struct hbm_client_connect_request) + 3) / 4; + if (mei_connect(dev, cl)) { + cl->status = -ENODEV; + cb_pos->information = 0; + list_del(&cb_pos->cb_list); + return -ENODEV; + } else { + list_move_tail(&cb_pos->cb_list, + &dev->ctrl_rd_list.mei_cb.cb_list); + cl->timer_count = MEI_CONNECT_TIMEOUT; + } + } else { + /* return the cancel routine */ + list_del(&cb_pos->cb_list); + return -EBADMSG; + } + + return 0; +} + +/** + * _mei_irq_thread_cmpl - processes completed and no-iamthif operation. + * + * @dev: the device structure. + * @slots: free slots. + * @cb_pos: callback block. + * @cl: private data of the file object. + * @cmpl_list: complete list. + * + * returns 0, OK; otherwise, error. + */ +static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots, + struct mei_cl_cb *cb_pos, + struct mei_cl *cl, + struct mei_io_list *cmpl_list) +{ + struct mei_msg_hdr *mei_hdr; + + if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + + (cb_pos->request_buffer.size - + cb_pos->information))) { + mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; + mei_hdr->host_addr = cl->host_client_id; + mei_hdr->me_addr = cl->me_client_id; + mei_hdr->length = cb_pos->request_buffer.size - + cb_pos->information; + mei_hdr->msg_complete = 1; + mei_hdr->reserved = 0; + dev_dbg(&dev->pdev->dev, "cb_pos->request_buffer.size =%d" + "mei_hdr->msg_complete = %d\n", + cb_pos->request_buffer.size, + mei_hdr->msg_complete); + dev_dbg(&dev->pdev->dev, "cb_pos->information =%lu\n", + cb_pos->information); + dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", + mei_hdr->length); + *slots -= (sizeof(struct mei_msg_hdr) + + mei_hdr->length + 3) / 4; + if (mei_write_message(dev, mei_hdr, + (unsigned char *) + (cb_pos->request_buffer.data + + cb_pos->information), + mei_hdr->length)) { + cl->status = -ENODEV; + list_move_tail(&cb_pos->cb_list, + &cmpl_list->mei_cb.cb_list); + return -ENODEV; + } else { + if (mei_flow_ctrl_reduce(dev, cl)) + return -ENODEV; + cl->status = 0; + cb_pos->information += mei_hdr->length; + list_move_tail(&cb_pos->cb_list, + &dev->write_waiting_list.mei_cb.cb_list); + } + } else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) { + /* buffer is still empty */ + mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; + mei_hdr->host_addr = cl->host_client_id; + mei_hdr->me_addr = cl->me_client_id; + mei_hdr->length = + (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr); + mei_hdr->msg_complete = 0; + mei_hdr->reserved = 0; + + (*slots) -= (sizeof(struct mei_msg_hdr) + + mei_hdr->length + 3) / 4; + if (mei_write_message(dev, mei_hdr, + (unsigned char *) + (cb_pos->request_buffer.data + + cb_pos->information), + mei_hdr->length)) { + cl->status = -ENODEV; + list_move_tail(&cb_pos->cb_list, + &cmpl_list->mei_cb.cb_list); + return -ENODEV; + } else { + cb_pos->information += mei_hdr->length; + dev_dbg(&dev->pdev->dev, + "cb_pos->request_buffer.size =%d" + " mei_hdr->msg_complete = %d\n", + cb_pos->request_buffer.size, + mei_hdr->msg_complete); + dev_dbg(&dev->pdev->dev, "cb_pos->information =%lu\n", + cb_pos->information); + dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", + mei_hdr->length); + } + return -EMSGSIZE; + } else { + return -EBADMSG; + } + + return 0; +} + +/** + * _mei_irq_thread_cmpl_iamthif - processes completed iamthif operation. + * + * @dev: the device structure. + * @slots: free slots. + * @cb_pos: callback block. + * @cl: private data of the file object. + * @cmpl_list: complete list. + * + * returns 0, OK; otherwise, error. + */ +static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots, + struct mei_cl_cb *cb_pos, + struct mei_cl *cl, + struct mei_io_list *cmpl_list) +{ + struct mei_msg_hdr *mei_hdr; + + if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + + dev->iamthif_msg_buf_size - + dev->iamthif_msg_buf_index)) { + mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; + mei_hdr->host_addr = cl->host_client_id; + mei_hdr->me_addr = cl->me_client_id; + mei_hdr->length = dev->iamthif_msg_buf_size - + dev->iamthif_msg_buf_index; + mei_hdr->msg_complete = 1; + mei_hdr->reserved = 0; + + *slots -= (sizeof(struct mei_msg_hdr) + + mei_hdr->length + 3) / 4; + + if (mei_write_message(dev, mei_hdr, + (dev->iamthif_msg_buf + + dev->iamthif_msg_buf_index), + mei_hdr->length)) { + dev->iamthif_state = MEI_IAMTHIF_IDLE; + cl->status = -ENODEV; + list_del(&cb_pos->cb_list); + return -ENODEV; + } else { + if (mei_flow_ctrl_reduce(dev, cl)) + return -ENODEV; + dev->iamthif_msg_buf_index += mei_hdr->length; + cb_pos->information = dev->iamthif_msg_buf_index; + cl->status = 0; + dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; + dev->iamthif_flow_control_pending = true; + /* save iamthif cb sent to amthi client */ + dev->iamthif_current_cb = cb_pos; + list_move_tail(&cb_pos->cb_list, + &dev->write_waiting_list.mei_cb.cb_list); + + } + } else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) { + /* buffer is still empty */ + mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; + mei_hdr->host_addr = cl->host_client_id; + mei_hdr->me_addr = cl->me_client_id; + mei_hdr->length = + (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr); + mei_hdr->msg_complete = 0; + mei_hdr->reserved = 0; + + *slots -= (sizeof(struct mei_msg_hdr) + + mei_hdr->length + 3) / 4; + + if (mei_write_message(dev, mei_hdr, + (dev->iamthif_msg_buf + + dev->iamthif_msg_buf_index), + mei_hdr->length)) { + cl->status = -ENODEV; + list_del(&cb_pos->cb_list); + } else { + dev->iamthif_msg_buf_index += mei_hdr->length; + } + return -EMSGSIZE; + } else { + return -EBADMSG; + } + + return 0; +} + +/** + * mei_irq_thread_read_handler - bottom half read routine after ISR to + * handle the read processing. + * + * @cmpl_list: An instance of our list structure + * @dev: the device structure + * @slots: slots to read. + * + * returns 0 on success, <0 on failure. + */ +static int mei_irq_thread_read_handler(struct mei_io_list *cmpl_list, + struct mei_device *dev, + s32 *slots) +{ + struct mei_msg_hdr *mei_hdr; + struct mei_cl *cl_pos = NULL; + struct mei_cl *cl_next = NULL; + int ret = 0; + + if (!dev->rd_msg_hdr) { + dev->rd_msg_hdr = mei_mecbrw_read(dev); + dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots); + (*slots)--; + dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots); + } + mei_hdr = (struct mei_msg_hdr *) &dev->rd_msg_hdr; + dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", mei_hdr->length); + + if (mei_hdr->reserved || !dev->rd_msg_hdr) { + dev_dbg(&dev->pdev->dev, "corrupted message header.\n"); + ret = -EBADMSG; + goto end; + } + + if (mei_hdr->host_addr || mei_hdr->me_addr) { + list_for_each_entry_safe(cl_pos, cl_next, + &dev->file_list, link) { + dev_dbg(&dev->pdev->dev, + "list_for_each_entry_safe read host" + " client = %d, ME client = %d\n", + cl_pos->host_client_id, + cl_pos->me_client_id); + if (cl_pos->host_client_id == mei_hdr->host_addr && + cl_pos->me_client_id == mei_hdr->me_addr) + break; + } + + if (&cl_pos->link == &dev->file_list) { + dev_dbg(&dev->pdev->dev, "corrupted message header\n"); + ret = -EBADMSG; + goto end; + } + } + if (((*slots) * sizeof(u32)) < mei_hdr->length) { + dev_dbg(&dev->pdev->dev, + "we can't read the message slots =%08x.\n", + *slots); + /* we can't read the message */ + ret = -ERANGE; + goto end; + } + + /* decide where to read the message too */ + if (!mei_hdr->host_addr) { + dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_bus_message.\n"); + mei_irq_thread_read_bus_message(dev, mei_hdr); + dev_dbg(&dev->pdev->dev, "end mei_irq_thread_read_bus_message.\n"); + } else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id && + (MEI_FILE_CONNECTED == dev->iamthif_cl.state) && + (dev->iamthif_state == MEI_IAMTHIF_READING)) { + dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n"); + dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", + mei_hdr->length); + ret = mei_irq_thread_read_amthi_message(cmpl_list, + dev, mei_hdr); + if (ret) + goto end; + + } else { + dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_client_message.\n"); + ret = mei_irq_thread_read_client_message(cmpl_list, + dev, mei_hdr); + if (ret) + goto end; + + } + + /* reset the number of slots and header */ + *slots = mei_count_full_read_slots(dev); + dev->rd_msg_hdr = 0; + + if (*slots == -EOVERFLOW) { + /* overflow - reset */ + dev_dbg(&dev->pdev->dev, "resetting due to slots overflow.\n"); + /* set the event since message has been read */ + ret = -ERANGE; + goto end; + } +end: + return ret; +} + + +/** + * mei_irq_thread_write_handler - bottom half write routine after + * ISR to handle the write processing. + * + * @cmpl_list: An instance of our list structure + * @dev: the device structure + * @slots: slots to write. + * + * returns 0 on success, <0 on failure. + */ +static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, + struct mei_device *dev, + s32 *slots) +{ + + struct mei_cl *cl; + struct mei_cl_cb *pos = NULL, *next = NULL; + struct mei_io_list *list; + int ret; + + if (!mei_host_buffer_is_empty(dev)) { + dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n"); + return 0; + } + *slots = mei_count_empty_write_slots(dev); + /* complete all waiting for write CB */ + dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n"); + + list = &dev->write_waiting_list; + list_for_each_entry_safe(pos, next, + &list->mei_cb.cb_list, cb_list) { + cl = (struct mei_cl *)pos->file_private; + if (cl == NULL) + continue; + + cl->status = 0; + list_del(&pos->cb_list); + if (MEI_WRITING == cl->writing_state && + (pos->major_file_operations == MEI_WRITE) && + (cl != &dev->iamthif_cl)) { + dev_dbg(&dev->pdev->dev, + "MEI WRITE COMPLETE\n"); + cl->writing_state = MEI_WRITE_COMPLETE; + list_add_tail(&pos->cb_list, + &cmpl_list->mei_cb.cb_list); + } + if (cl == &dev->iamthif_cl) { + dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n"); + if (dev->iamthif_flow_control_pending) { + ret = _mei_irq_thread_iamthif_read( + dev, slots); + if (ret) + return ret; + } + } + } + + if (dev->stop && !dev->wd_pending) { + dev->wd_stopped = true; + wake_up_interruptible(&dev->wait_stop_wd); + return 0; + } + + if (dev->extra_write_index) { + dev_dbg(&dev->pdev->dev, "extra_write_index =%d.\n", + dev->extra_write_index); + mei_write_message(dev, + (struct mei_msg_hdr *) &dev->ext_msg_buf[0], + (unsigned char *) &dev->ext_msg_buf[1], + (dev->extra_write_index - 1) * sizeof(u32)); + *slots -= dev->extra_write_index; + dev->extra_write_index = 0; + } + if (dev->mei_state == MEI_ENABLED) { + if (dev->wd_pending && + mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) { + if (mei_wd_send(dev)) + dev_dbg(&dev->pdev->dev, "wd send failed.\n"); + else + if (mei_flow_ctrl_reduce(dev, &dev->wd_cl)) + return -ENODEV; + + dev->wd_pending = false; + + if (dev->wd_timeout) { + *slots -= (sizeof(struct mei_msg_hdr) + + MEI_START_WD_DATA_SIZE + 3) / 4; + dev->wd_due_counter = 2; + } else { + *slots -= (sizeof(struct mei_msg_hdr) + + MEI_WD_PARAMS_SIZE + 3) / 4; + dev->wd_due_counter = 0; + } + + } + } + if (dev->stop) + return -ENODEV; + + /* complete control write list CB */ + dev_dbg(&dev->pdev->dev, "complete control write list cb.\n"); + list_for_each_entry_safe(pos, next, + &dev->ctrl_wr_list.mei_cb.cb_list, cb_list) { + cl = (struct mei_cl *) pos->file_private; + if (!cl) { + list_del(&pos->cb_list); + return -ENODEV; + } + switch (pos->major_file_operations) { + case MEI_CLOSE: + /* send disconnect message */ + ret = _mei_irq_thread_close(dev, slots, pos, cl, cmpl_list); + if (ret) + return ret; + + break; + case MEI_READ: + /* send flow control message */ + ret = _mei_irq_thread_read(dev, slots, pos, cl, cmpl_list); + if (ret) + return ret; + + break; + case MEI_IOCTL: + /* connect message */ + if (mei_other_client_is_connecting(dev, cl)) + continue; + ret = _mei_irq_thread_ioctl(dev, slots, pos, cl, cmpl_list); + if (ret) + return ret; + + break; + + default: + BUG(); + } + + } + /* complete write list CB */ + dev_dbg(&dev->pdev->dev, "complete write list cb.\n"); + list_for_each_entry_safe(pos, next, + &dev->write_list.mei_cb.cb_list, cb_list) { + cl = (struct mei_cl *)pos->file_private; + if (cl == NULL) + continue; + + if (cl != &dev->iamthif_cl) { + if (!mei_flow_ctrl_creds(dev, cl)) { + dev_dbg(&dev->pdev->dev, + "No flow control" + " credentials for client" + " %d, not sending.\n", + cl->host_client_id); + continue; + } + ret = _mei_irq_thread_cmpl(dev, slots, + pos, + cl, cmpl_list); + if (ret) + return ret; + + } else if (cl == &dev->iamthif_cl) { + /* IAMTHIF IOCTL */ + dev_dbg(&dev->pdev->dev, "complete amthi write cb.\n"); + if (!mei_flow_ctrl_creds(dev, cl)) { + dev_dbg(&dev->pdev->dev, + "No flow control" + " credentials for amthi" + " client %d.\n", + cl->host_client_id); + continue; + } + ret = _mei_irq_thread_cmpl_iamthif(dev, + slots, + pos, + cl, + cmpl_list); + if (ret) + return ret; + + } + + } + return 0; +} + + + +/** + * mei_timer - timer function. + * + * @work: pointer to the work_struct structure + * + * NOTE: This function is called by timer interrupt work + */ +void mei_timer(struct work_struct *work) +{ + unsigned long timeout; + struct mei_cl *cl_pos = NULL; + struct mei_cl *cl_next = NULL; + struct list_head *amthi_complete_list = NULL; + struct mei_cl_cb *cb_pos = NULL; + struct mei_cl_cb *cb_next = NULL; + + struct mei_device *dev = container_of(work, + struct mei_device, timer_work.work); + + + mutex_lock(&dev->device_lock); + if (dev->mei_state != MEI_ENABLED) { + if (dev->mei_state == MEI_INIT_CLIENTS) { + if (dev->init_clients_timer) { + if (--dev->init_clients_timer == 0) { + dev_dbg(&dev->pdev->dev, "IMEI reset due to init clients timeout ,init clients state = %d.\n", + dev->init_clients_state); + mei_reset(dev, 1); + } + } + } + goto out; + } + /*** connect/disconnect timeouts ***/ + list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { + if (cl_pos->timer_count) { + if (--cl_pos->timer_count == 0) { + dev_dbg(&dev->pdev->dev, "HECI reset due to connect/disconnect timeout.\n"); + mei_reset(dev, 1); + goto out; + } + } + } + + if (dev->iamthif_stall_timer) { + if (--dev->iamthif_stall_timer == 0) { + dev_dbg(&dev->pdev->dev, "resetting because of hang to amthi.\n"); + mei_reset(dev, 1); + dev->iamthif_msg_buf_size = 0; + dev->iamthif_msg_buf_index = 0; + dev->iamthif_canceled = false; + dev->iamthif_ioctl = true; + dev->iamthif_state = MEI_IAMTHIF_IDLE; + dev->iamthif_timer = 0; + + if (dev->iamthif_current_cb) + mei_free_cb_private(dev->iamthif_current_cb); + + dev->iamthif_file_object = NULL; + dev->iamthif_current_cb = NULL; + mei_run_next_iamthif_cmd(dev); + } + } + + if (dev->iamthif_timer) { + + timeout = dev->iamthif_timer + + msecs_to_jiffies(IAMTHIF_READ_TIMER); + + dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n", + dev->iamthif_timer); + dev_dbg(&dev->pdev->dev, "timeout = %ld\n", timeout); + dev_dbg(&dev->pdev->dev, "jiffies = %ld\n", jiffies); + if (time_after(jiffies, timeout)) { + /* + * User didn't read the AMTHI data on time (15sec) + * freeing AMTHI for other requests + */ + + dev_dbg(&dev->pdev->dev, "freeing AMTHI for other requests\n"); + + amthi_complete_list = &dev->amthi_read_complete_list. + mei_cb.cb_list; + + list_for_each_entry_safe(cb_pos, cb_next, amthi_complete_list, cb_list) { + + cl_pos = cb_pos->file_object->private_data; + + /* Finding the AMTHI entry. */ + if (cl_pos == &dev->iamthif_cl) + list_del(&cb_pos->cb_list); + } + if (dev->iamthif_current_cb) + mei_free_cb_private(dev->iamthif_current_cb); + + dev->iamthif_file_object->private_data = NULL; + dev->iamthif_file_object = NULL; + dev->iamthif_current_cb = NULL; + dev->iamthif_timer = 0; + mei_run_next_iamthif_cmd(dev); + + } + } +out: + schedule_delayed_work(&dev->timer_work, 2 * HZ); + mutex_unlock(&dev->device_lock); +} + +/** + * mei_interrupt_thread_handler - function called after ISR to handle the interrupt + * processing. + * + * @irq: The irq number + * @dev_id: pointer to the device structure + * + * returns irqreturn_t + * + */ +irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id) +{ + struct mei_device *dev = (struct mei_device *) dev_id; + struct mei_io_list complete_list; + struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; + struct mei_cl *cl; + s32 slots; + int rets; + bool bus_message_received; + + + dev_dbg(&dev->pdev->dev, "function called after ISR to handle the interrupt processing.\n"); + /* initialize our complete list */ + mutex_lock(&dev->device_lock); + mei_io_list_init(&complete_list); + dev->host_hw_state = mei_hcsr_read(dev); + + /* Ack the interrupt here + * In case of MSI we don't go through the quick handler */ + if (pci_dev_msi_enabled(dev->pdev)) + mei_reg_write(dev, H_CSR, dev->host_hw_state); + + dev->me_hw_state = mei_mecsr_read(dev); + + /* check if ME wants a reset */ + if ((dev->me_hw_state & ME_RDY_HRA) == 0 && + dev->mei_state != MEI_RESETING && + dev->mei_state != MEI_INITIALIZING) { + dev_dbg(&dev->pdev->dev, "FW not ready.\n"); + mei_reset(dev, 1); + mutex_unlock(&dev->device_lock); + return IRQ_HANDLED; + } + + /* check if we need to start the dev */ + if ((dev->host_hw_state & H_RDY) == 0) { + if ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA) { + dev_dbg(&dev->pdev->dev, "we need to start the dev.\n"); + dev->host_hw_state |= (H_IE | H_IG | H_RDY); + mei_hcsr_set(dev); + dev->mei_state = MEI_INIT_CLIENTS; + dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n"); + /* link is established + * start sending messages. + */ + mei_host_start_message(dev); + mutex_unlock(&dev->device_lock); + return IRQ_HANDLED; + } else { + dev_dbg(&dev->pdev->dev, "FW not ready.\n"); + mutex_unlock(&dev->device_lock); + return IRQ_HANDLED; + } + } + /* check slots available for reading */ + slots = mei_count_full_read_slots(dev); + dev_dbg(&dev->pdev->dev, "slots =%08x extra_write_index =%08x.\n", + slots, dev->extra_write_index); + while (slots > 0 && !dev->extra_write_index) { + dev_dbg(&dev->pdev->dev, "slots =%08x extra_write_index =%08x.\n", + slots, dev->extra_write_index); + dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_handler.\n"); + rets = mei_irq_thread_read_handler(&complete_list, dev, &slots); + if (rets) + goto end; + } + rets = mei_irq_thread_write_handler(&complete_list, dev, &slots); +end: + dev_dbg(&dev->pdev->dev, "end of bottom half function.\n"); + dev->host_hw_state = mei_hcsr_read(dev); + dev->mei_host_buffer_is_empty = mei_host_buffer_is_empty(dev); + + bus_message_received = false; + if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) { + dev_dbg(&dev->pdev->dev, "received waiting bus message\n"); + bus_message_received = true; + } + mutex_unlock(&dev->device_lock); + if (bus_message_received) { + dev_dbg(&dev->pdev->dev, "wake up dev->wait_recvd_msg\n"); + wake_up_interruptible(&dev->wait_recvd_msg); + bus_message_received = false; + } + if (list_empty(&complete_list.mei_cb.cb_list)) + return IRQ_HANDLED; + + + list_for_each_entry_safe(cb_pos, cb_next, + &complete_list.mei_cb.cb_list, cb_list) { + cl = (struct mei_cl *)cb_pos->file_private; + list_del(&cb_pos->cb_list); + if (cl) { + if (cl != &dev->iamthif_cl) { + dev_dbg(&dev->pdev->dev, "completing call back.\n"); + _mei_cmpl(cl, cb_pos); + cb_pos = NULL; + } else if (cl == &dev->iamthif_cl) { + _mei_cmpl_iamthif(dev, cb_pos); + } + } + } + return IRQ_HANDLED; +} diff --git a/drivers/misc/mei/iorw.c b/drivers/misc/mei/iorw.c new file mode 100644 index 0000000..0a80dc4 --- /dev/null +++ b/drivers/misc/mei/iorw.c @@ -0,0 +1,590 @@ +/* + * + * Intel Management Engine Interface (Intel MEI) Linux driver + * Copyright (c) 2003-2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "mei_dev.h" +#include "hw.h" +#include "mei.h" +#include "interface.h" + + + +/** + * mei_ioctl_connect_client - the connect to fw client IOCTL function + * + * @dev: the device structure + * @data: IOCTL connect data, input and output parameters + * @file: private data of the file object + * + * Locking: called under "dev->device_lock" lock + * + * returns 0 on success, <0 on failure. + */ +int mei_ioctl_connect_client(struct file *file, + struct mei_connect_client_data *data) +{ + struct mei_device *dev; + struct mei_cl_cb *cb; + struct mei_client *client; + struct mei_cl *cl; + struct mei_cl *cl_pos = NULL; + struct mei_cl *cl_next = NULL; + long timeout = CONNECT_TIMEOUT; + int i; + int err; + int rets; + + cl = file->private_data; + if (WARN_ON(!cl || !cl->dev)) + return -ENODEV; + + dev = cl->dev; + + dev_dbg(&dev->pdev->dev, "mei_ioctl_connect_client() Entry\n"); + + + /* buffered ioctl cb */ + cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); + if (!cb) { + rets = -ENOMEM; + goto end; + } + INIT_LIST_HEAD(&cb->cb_list); + + cb->major_file_operations = MEI_IOCTL; + + if (dev->mei_state != MEI_ENABLED) { + rets = -ENODEV; + goto end; + } + if (cl->state != MEI_FILE_INITIALIZING && + cl->state != MEI_FILE_DISCONNECTED) { + rets = -EBUSY; + goto end; + } + + /* find ME client we're trying to connect to */ + i = mei_find_me_client_index(dev, data->in_client_uuid); + if (i >= 0 && !dev->me_clients[i].props.fixed_address) { + cl->me_client_id = dev->me_clients[i].client_id; + cl->state = MEI_FILE_CONNECTING; + } + + dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n", + cl->me_client_id); + dev_dbg(&dev->pdev->dev, "FW Client - Protocol Version = %d\n", + dev->me_clients[i].props.protocol_version); + dev_dbg(&dev->pdev->dev, "FW Client - Max Msg Len = %d\n", + dev->me_clients[i].props.max_msg_length); + + /* if we're connecting to amthi client then we will use the + * existing connection + */ + if (uuid_le_cmp(data->in_client_uuid, mei_amthi_guid) == 0) { + dev_dbg(&dev->pdev->dev, "FW Client is amthi\n"); + if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) { + rets = -ENODEV; + goto end; + } + clear_bit(cl->host_client_id, dev->host_clients_map); + list_for_each_entry_safe(cl_pos, cl_next, + &dev->file_list, link) { + if (mei_cl_cmp_id(cl, cl_pos)) { + dev_dbg(&dev->pdev->dev, + "remove file private data node host" + " client = %d, ME client = %d.\n", + cl_pos->host_client_id, + cl_pos->me_client_id); + list_del(&cl_pos->link); + } + + } + dev_dbg(&dev->pdev->dev, "free file private data memory.\n"); + kfree(cl); + + cl = NULL; + file->private_data = &dev->iamthif_cl; + + client = &data->out_client_properties; + client->max_msg_length = + dev->me_clients[i].props.max_msg_length; + client->protocol_version = + dev->me_clients[i].props.protocol_version; + rets = dev->iamthif_cl.status; + + goto end; + } + + if (cl->state != MEI_FILE_CONNECTING) { + rets = -ENODEV; + goto end; + } + + + /* prepare the output buffer */ + client = &data->out_client_properties; + client->max_msg_length = dev->me_clients[i].props.max_msg_length; + client->protocol_version = dev->me_clients[i].props.protocol_version; + dev_dbg(&dev->pdev->dev, "Can connect?\n"); + if (dev->mei_host_buffer_is_empty + && !mei_other_client_is_connecting(dev, cl)) { + dev_dbg(&dev->pdev->dev, "Sending Connect Message\n"); + dev->mei_host_buffer_is_empty = false; + if (mei_connect(dev, cl)) { + dev_dbg(&dev->pdev->dev, "Sending connect message - failed\n"); + rets = -ENODEV; + goto end; + } else { + dev_dbg(&dev->pdev->dev, "Sending connect message - succeeded\n"); + cl->timer_count = MEI_CONNECT_TIMEOUT; + cb->file_private = cl; + list_add_tail(&cb->cb_list, + &dev->ctrl_rd_list.mei_cb. + cb_list); + } + + + } else { + dev_dbg(&dev->pdev->dev, "Queuing the connect request due to device busy\n"); + cb->file_private = cl; + dev_dbg(&dev->pdev->dev, "add connect cb to control write list.\n"); + list_add_tail(&cb->cb_list, + &dev->ctrl_wr_list.mei_cb.cb_list); + } + mutex_unlock(&dev->device_lock); + err = wait_event_timeout(dev->wait_recvd_msg, + (MEI_FILE_CONNECTED == cl->state || + MEI_FILE_DISCONNECTED == cl->state), + timeout * HZ); + + mutex_lock(&dev->device_lock); + if (MEI_FILE_CONNECTED == cl->state) { + dev_dbg(&dev->pdev->dev, "successfully connected to FW client.\n"); + rets = cl->status; + goto end; + } else { + dev_dbg(&dev->pdev->dev, "failed to connect to FW client.cl->state = %d.\n", + cl->state); + if (!err) { + dev_dbg(&dev->pdev->dev, + "wait_event_interruptible_timeout failed on client" + " connect message fw response message.\n"); + } + rets = -EFAULT; + + mei_io_list_flush(&dev->ctrl_rd_list, cl); + mei_io_list_flush(&dev->ctrl_wr_list, cl); + goto end; + } + rets = 0; +end: + dev_dbg(&dev->pdev->dev, "free connect cb memory."); + kfree(cb); + return rets; +} + +/** + * find_amthi_read_list_entry - finds a amthilist entry for current file + * + * @dev: the device structure + * @file: pointer to file object + * + * returns returned a list entry on success, NULL on failure. + */ +struct mei_cl_cb *find_amthi_read_list_entry( + struct mei_device *dev, + struct file *file) +{ + struct mei_cl *cl_temp; + struct mei_cl_cb *pos = NULL; + struct mei_cl_cb *next = NULL; + + list_for_each_entry_safe(pos, next, + &dev->amthi_read_complete_list.mei_cb.cb_list, cb_list) { + cl_temp = (struct mei_cl *)pos->file_private; + if (cl_temp && cl_temp == &dev->iamthif_cl && + pos->file_object == file) + return pos; + } + return NULL; +} + +/** + * amthi_read - read data from AMTHI client + * + * @dev: the device structure + * @if_num: minor number + * @file: pointer to file object + * @*ubuf: pointer to user data in user space + * @length: data length to read + * @offset: data read offset + * + * Locking: called under "dev->device_lock" lock + * + * returns + * returned data length on success, + * zero if no data to read, + * negative on failure. + */ +int amthi_read(struct mei_device *dev, struct file *file, + char __user *ubuf, size_t length, loff_t *offset) +{ + int rets; + int wait_ret; + struct mei_cl_cb *cb = NULL; + struct mei_cl *cl = file->private_data; + unsigned long timeout; + int i; + + /* Only Posible if we are in timeout */ + if (!cl || cl != &dev->iamthif_cl) { + dev_dbg(&dev->pdev->dev, "bad file ext.\n"); + return -ETIMEDOUT; + } + + for (i = 0; i < dev->me_clients_num; i++) { + if (dev->me_clients[i].client_id == + dev->iamthif_cl.me_client_id) + break; + } + + if (i == dev->me_clients_num) { + dev_dbg(&dev->pdev->dev, "amthi client not found.\n"); + return -ENODEV; + } + if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id)) + return -ENODEV; + + dev_dbg(&dev->pdev->dev, "checking amthi data\n"); + cb = find_amthi_read_list_entry(dev, file); + + /* Check for if we can block or not*/ + if (cb == NULL && file->f_flags & O_NONBLOCK) + return -EAGAIN; + + + dev_dbg(&dev->pdev->dev, "waiting for amthi data\n"); + while (cb == NULL) { + /* unlock the Mutex */ + mutex_unlock(&dev->device_lock); + + wait_ret = wait_event_interruptible(dev->iamthif_cl.wait, + (cb = find_amthi_read_list_entry(dev, file))); + + if (wait_ret) + return -ERESTARTSYS; + + dev_dbg(&dev->pdev->dev, "woke up from sleep\n"); + + /* Locking again the Mutex */ + mutex_lock(&dev->device_lock); + } + + + dev_dbg(&dev->pdev->dev, "Got amthi data\n"); + dev->iamthif_timer = 0; + + if (cb) { + timeout = cb->read_time + + msecs_to_jiffies(IAMTHIF_READ_TIMER); + dev_dbg(&dev->pdev->dev, "amthi timeout = %lud\n", + timeout); + + if (time_after(jiffies, timeout)) { + dev_dbg(&dev->pdev->dev, "amthi Time out\n"); + /* 15 sec for the message has expired */ + list_del(&cb->cb_list); + rets = -ETIMEDOUT; + goto free; + } + } + /* if the whole message will fit remove it from the list */ + if (cb->information >= *offset && length >= (cb->information - *offset)) + list_del(&cb->cb_list); + else if (cb->information > 0 && cb->information <= *offset) { + /* end of the message has been reached */ + list_del(&cb->cb_list); + rets = 0; + goto free; + } + /* else means that not full buffer will be read and do not + * remove message from deletion list + */ + + dev_dbg(&dev->pdev->dev, "amthi cb->response_buffer size - %d\n", + cb->response_buffer.size); + dev_dbg(&dev->pdev->dev, "amthi cb->information - %lu\n", + cb->information); + + /* length is being turncated to PAGE_SIZE, however, + * the information may be longer */ + length = min_t(size_t, length, (cb->information - *offset)); + + if (copy_to_user(ubuf, cb->response_buffer.data + *offset, length)) + rets = -EFAULT; + else { + rets = length; + if ((*offset + length) < cb->information) { + *offset += length; + goto out; + } + } +free: + dev_dbg(&dev->pdev->dev, "free amthi cb memory.\n"); + *offset = 0; + mei_free_cb_private(cb); +out: + return rets; +} + +/** + * mei_start_read - the start read client message function. + * + * @dev: the device structure + * @if_num: minor number + * @cl: private data of the file object + * + * returns 0 on success, <0 on failure. + */ +int mei_start_read(struct mei_device *dev, struct mei_cl *cl) +{ + struct mei_cl_cb *cb; + int rets = 0; + int i; + + if (cl->state != MEI_FILE_CONNECTED) + return -ENODEV; + + if (dev->mei_state != MEI_ENABLED) + return -ENODEV; + + dev_dbg(&dev->pdev->dev, "check if read is pending.\n"); + if (cl->read_pending || cl->read_cb) { + dev_dbg(&dev->pdev->dev, "read is pending.\n"); + return -EBUSY; + } + + cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); + if (!cb) + return -ENOMEM; + + dev_dbg(&dev->pdev->dev, "allocation call back successful. host client = %d, ME client = %d\n", + cl->host_client_id, cl->me_client_id); + + for (i = 0; i < dev->me_clients_num; i++) { + if (dev->me_clients[i].client_id == cl->me_client_id) + break; + + } + + if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id)) { + rets = -ENODEV; + goto unlock; + } + + if (i == dev->me_clients_num) { + rets = -ENODEV; + goto unlock; + } + + cb->response_buffer.size = dev->me_clients[i].props.max_msg_length; + cb->response_buffer.data = + kmalloc(cb->response_buffer.size, GFP_KERNEL); + if (!cb->response_buffer.data) { + rets = -ENOMEM; + goto unlock; + } + dev_dbg(&dev->pdev->dev, "allocation call back data success.\n"); + cb->major_file_operations = MEI_READ; + /* make sure information is zero before we start */ + cb->information = 0; + cb->file_private = (void *) cl; + cl->read_cb = cb; + if (dev->mei_host_buffer_is_empty) { + dev->mei_host_buffer_is_empty = false; + if (mei_send_flow_control(dev, cl)) { + rets = -ENODEV; + goto unlock; + } + list_add_tail(&cb->cb_list, &dev->read_list.mei_cb.cb_list); + } else { + list_add_tail(&cb->cb_list, &dev->ctrl_wr_list.mei_cb.cb_list); + } + return rets; +unlock: + mei_free_cb_private(cb); + return rets; +} + +/** + * amthi_write - write iamthif data to amthi client + * + * @dev: the device structure + * @cb: mei call back struct + * + * returns 0 on success, <0 on failure. + */ +int amthi_write(struct mei_device *dev, struct mei_cl_cb *cb) +{ + struct mei_msg_hdr mei_hdr; + int ret; + + if (!dev || !cb) + return -ENODEV; + + dev_dbg(&dev->pdev->dev, "write data to amthi client.\n"); + + dev->iamthif_state = MEI_IAMTHIF_WRITING; + dev->iamthif_current_cb = cb; + dev->iamthif_file_object = cb->file_object; + dev->iamthif_canceled = false; + dev->iamthif_ioctl = true; + dev->iamthif_msg_buf_size = cb->request_buffer.size; + memcpy(dev->iamthif_msg_buf, cb->request_buffer.data, + cb->request_buffer.size); + + ret = mei_flow_ctrl_creds(dev, &dev->iamthif_cl); + if (ret < 0) + return ret; + + if (ret && dev->mei_host_buffer_is_empty) { + ret = 0; + dev->mei_host_buffer_is_empty = false; + if (cb->request_buffer.size > + (((dev->host_hw_state & H_CBD) >> 24) * sizeof(u32)) + -sizeof(struct mei_msg_hdr)) { + mei_hdr.length = + (((dev->host_hw_state & H_CBD) >> 24) * + sizeof(u32)) - sizeof(struct mei_msg_hdr); + mei_hdr.msg_complete = 0; + } else { + mei_hdr.length = cb->request_buffer.size; + mei_hdr.msg_complete = 1; + } + + mei_hdr.host_addr = dev->iamthif_cl.host_client_id; + mei_hdr.me_addr = dev->iamthif_cl.me_client_id; + mei_hdr.reserved = 0; + dev->iamthif_msg_buf_index += mei_hdr.length; + if (mei_write_message(dev, &mei_hdr, + (unsigned char *)(dev->iamthif_msg_buf), + mei_hdr.length)) + return -ENODEV; + + if (mei_hdr.msg_complete) { + if (mei_flow_ctrl_reduce(dev, &dev->iamthif_cl)) + return -ENODEV; + dev->iamthif_flow_control_pending = true; + dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; + dev_dbg(&dev->pdev->dev, "add amthi cb to write waiting list\n"); + dev->iamthif_current_cb = cb; + dev->iamthif_file_object = cb->file_object; + list_add_tail(&cb->cb_list, + &dev->write_waiting_list.mei_cb.cb_list); + } else { + dev_dbg(&dev->pdev->dev, "message does not complete, " + "so add amthi cb to write list.\n"); + list_add_tail(&cb->cb_list, + &dev->write_list.mei_cb.cb_list); + } + } else { + if (!(dev->mei_host_buffer_is_empty)) + dev_dbg(&dev->pdev->dev, "host buffer is not empty"); + + dev_dbg(&dev->pdev->dev, "No flow control credentials, " + "so add iamthif cb to write list.\n"); + list_add_tail(&cb->cb_list, &dev->write_list.mei_cb.cb_list); + } + return 0; +} + +/** + * iamthif_ioctl_send_msg - send cmd data to amthi client + * + * @dev: the device structure + * + * returns 0 on success, <0 on failure. + */ +void mei_run_next_iamthif_cmd(struct mei_device *dev) +{ + struct mei_cl *cl_tmp; + struct mei_cl_cb *pos = NULL; + struct mei_cl_cb *next = NULL; + int status; + + if (!dev) + return; + + dev->iamthif_msg_buf_size = 0; + dev->iamthif_msg_buf_index = 0; + dev->iamthif_canceled = false; + dev->iamthif_ioctl = true; + dev->iamthif_state = MEI_IAMTHIF_IDLE; + dev->iamthif_timer = 0; + dev->iamthif_file_object = NULL; + + dev_dbg(&dev->pdev->dev, "complete amthi cmd_list cb.\n"); + + list_for_each_entry_safe(pos, next, + &dev->amthi_cmd_list.mei_cb.cb_list, cb_list) { + list_del(&pos->cb_list); + cl_tmp = (struct mei_cl *)pos->file_private; + + if (cl_tmp && cl_tmp == &dev->iamthif_cl) { + status = amthi_write(dev, pos); + if (status) { + dev_dbg(&dev->pdev->dev, + "amthi write failed status = %d\n", + status); + return; + } + break; + } + } +} + +/** + * mei_free_cb_private - free mei_cb_private related memory + * + * @cb: mei callback struct + */ +void mei_free_cb_private(struct mei_cl_cb *cb) +{ + if (cb == NULL) + return; + + kfree(cb->request_buffer.data); + kfree(cb->response_buffer.data); + kfree(cb); +} diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c new file mode 100644 index 0000000..20f80df --- /dev/null +++ b/drivers/misc/mei/main.c @@ -0,0 +1,1230 @@ +/* + * + * Intel Management Engine Interface (Intel MEI) Linux driver + * Copyright (c) 2003-2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mei_dev.h" +#include "mei.h" +#include "interface.h" + +static const char mei_driver_name[] = "mei"; + +/* The device pointer */ +/* Currently this driver works as long as there is only a single AMT device. */ +struct pci_dev *mei_device; + +/* mei_pci_tbl - PCI Device ID Table */ +static DEFINE_PCI_DEVICE_TABLE(mei_pci_tbl) = { + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82946GZ)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G35)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82Q965)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G965)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GM965)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GME965)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q35)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82G33)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q33)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82X38)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_3200)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_6)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_7)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_8)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_9)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_10)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_1)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_2)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_3)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_4)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_1)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_2)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_3)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_4)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_IBXPK_1)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_IBXPK_2)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_CPT_1)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PBG_1)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_1)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_2)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_3)}, + + /* required last entry */ + {0, } +}; + +MODULE_DEVICE_TABLE(pci, mei_pci_tbl); + +static DEFINE_MUTEX(mei_mutex); + + +/** + * mei_clear_list - removes all callbacks associated with file + * from mei_cb_list + * + * @dev: device structure. + * @file: file structure + * @mei_cb_list: callbacks list + * + * mei_clear_list is called to clear resources associated with file + * when application calls close function or Ctrl-C was pressed + * + * returns true if callback removed from the list, false otherwise + */ +static bool mei_clear_list(struct mei_device *dev, + struct file *file, struct list_head *mei_cb_list) +{ + struct mei_cl_cb *cb_pos = NULL; + struct mei_cl_cb *cb_next = NULL; + struct file *file_temp; + bool removed = false; + + /* list all list member */ + list_for_each_entry_safe(cb_pos, cb_next, mei_cb_list, cb_list) { + file_temp = (struct file *)cb_pos->file_object; + /* check if list member associated with a file */ + if (file_temp == file) { + /* remove member from the list */ + list_del(&cb_pos->cb_list); + /* check if cb equal to current iamthif cb */ + if (dev->iamthif_current_cb == cb_pos) { + dev->iamthif_current_cb = NULL; + /* send flow control to iamthif client */ + mei_send_flow_control(dev, &dev->iamthif_cl); + } + /* free all allocated buffers */ + mei_free_cb_private(cb_pos); + cb_pos = NULL; + removed = true; + } + } + return removed; +} + +/** + * mei_clear_lists - removes all callbacks associated with file + * + * @dev: device structure + * @file: file structure + * + * mei_clear_lists is called to clear resources associated with file + * when application calls close function or Ctrl-C was pressed + * + * returns true if callback removed from the list, false otherwise + */ +static bool mei_clear_lists(struct mei_device *dev, struct file *file) +{ + bool removed = false; + + /* remove callbacks associated with a file */ + mei_clear_list(dev, file, &dev->amthi_cmd_list.mei_cb.cb_list); + if (mei_clear_list(dev, file, + &dev->amthi_read_complete_list.mei_cb.cb_list)) + removed = true; + + mei_clear_list(dev, file, &dev->ctrl_rd_list.mei_cb.cb_list); + + if (mei_clear_list(dev, file, &dev->ctrl_wr_list.mei_cb.cb_list)) + removed = true; + + if (mei_clear_list(dev, file, &dev->write_waiting_list.mei_cb.cb_list)) + removed = true; + + if (mei_clear_list(dev, file, &dev->write_list.mei_cb.cb_list)) + removed = true; + + /* check if iamthif_current_cb not NULL */ + if (dev->iamthif_current_cb && !removed) { + /* check file and iamthif current cb association */ + if (dev->iamthif_current_cb->file_object == file) { + /* remove cb */ + mei_free_cb_private(dev->iamthif_current_cb); + dev->iamthif_current_cb = NULL; + removed = true; + } + } + return removed; +} +/** + * find_read_list_entry - find read list entry + * + * @dev: device structure + * @file: pointer to file structure + * + * returns cb on success, NULL on error + */ +static struct mei_cl_cb *find_read_list_entry( + struct mei_device *dev, + struct mei_cl *cl) +{ + struct mei_cl_cb *pos = NULL; + struct mei_cl_cb *next = NULL; + + dev_dbg(&dev->pdev->dev, "remove read_list CB\n"); + list_for_each_entry_safe(pos, next, + &dev->read_list.mei_cb.cb_list, cb_list) { + struct mei_cl *cl_temp; + cl_temp = (struct mei_cl *)pos->file_private; + + if (mei_cl_cmp_id(cl, cl_temp)) + return pos; + } + return NULL; +} + +/** + * mei_open - the open function + * + * @inode: pointer to inode structure + * @file: pointer to file structure + * + * returns 0 on success, <0 on error + */ +static int mei_open(struct inode *inode, struct file *file) +{ + struct mei_cl *cl; + struct mei_device *dev; + unsigned long cl_id; + int err; + + err = -ENODEV; + if (!mei_device) + goto out; + + dev = pci_get_drvdata(mei_device); + if (!dev) + goto out; + + mutex_lock(&dev->device_lock); + err = -ENOMEM; + cl = mei_cl_allocate(dev); + if (!cl) + goto out_unlock; + + err = -ENODEV; + if (dev->mei_state != MEI_ENABLED) { + dev_dbg(&dev->pdev->dev, "mei_state != MEI_ENABLED mei_state= %d\n", + dev->mei_state); + goto out_unlock; + } + err = -EMFILE; + if (dev->open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT) + goto out_unlock; + + cl_id = find_first_zero_bit(dev->host_clients_map, MEI_CLIENTS_MAX); + if (cl_id >= MEI_CLIENTS_MAX) + goto out_unlock; + + cl->host_client_id = cl_id; + + dev_dbg(&dev->pdev->dev, "client_id = %d\n", cl->host_client_id); + + dev->open_handle_count++; + + list_add_tail(&cl->link, &dev->file_list); + + set_bit(cl->host_client_id, dev->host_clients_map); + cl->state = MEI_FILE_INITIALIZING; + cl->sm_state = 0; + + file->private_data = cl; + mutex_unlock(&dev->device_lock); + + return nonseekable_open(inode, file); + +out_unlock: + mutex_unlock(&dev->device_lock); + kfree(cl); +out: + return err; +} + +/** + * mei_release - the release function + * + * @inode: pointer to inode structure + * @file: pointer to file structure + * + * returns 0 on success, <0 on error + */ +static int mei_release(struct inode *inode, struct file *file) +{ + struct mei_cl *cl = file->private_data; + struct mei_cl_cb *cb; + struct mei_device *dev; + int rets = 0; + + if (WARN_ON(!cl || !cl->dev)) + return -ENODEV; + + dev = cl->dev; + + mutex_lock(&dev->device_lock); + if (cl != &dev->iamthif_cl) { + if (cl->state == MEI_FILE_CONNECTED) { + cl->state = MEI_FILE_DISCONNECTING; + dev_dbg(&dev->pdev->dev, + "disconnecting client host client = %d, " + "ME client = %d\n", + cl->host_client_id, + cl->me_client_id); + rets = mei_disconnect_host_client(dev, cl); + } + mei_cl_flush_queues(cl); + dev_dbg(&dev->pdev->dev, "remove client host client = %d, ME client = %d\n", + cl->host_client_id, + cl->me_client_id); + + if (dev->open_handle_count > 0) { + clear_bit(cl->host_client_id, dev->host_clients_map); + dev->open_handle_count--; + } + mei_remove_client_from_file_list(dev, cl->host_client_id); + + /* free read cb */ + cb = NULL; + if (cl->read_cb) { + cb = find_read_list_entry(dev, cl); + /* Remove entry from read list */ + if (cb) + list_del(&cb->cb_list); + + cb = cl->read_cb; + cl->read_cb = NULL; + } + + file->private_data = NULL; + + if (cb) { + mei_free_cb_private(cb); + cb = NULL; + } + + kfree(cl); + } else { + if (dev->open_handle_count > 0) + dev->open_handle_count--; + + if (dev->iamthif_file_object == file && + dev->iamthif_state != MEI_IAMTHIF_IDLE) { + + dev_dbg(&dev->pdev->dev, "amthi canceled iamthif state %d\n", + dev->iamthif_state); + dev->iamthif_canceled = true; + if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE) { + dev_dbg(&dev->pdev->dev, "run next amthi iamthif cb\n"); + mei_run_next_iamthif_cmd(dev); + } + } + + if (mei_clear_lists(dev, file)) + dev->iamthif_state = MEI_IAMTHIF_IDLE; + + } + mutex_unlock(&dev->device_lock); + return rets; +} + + +/** + * mei_read - the read function. + * + * @file: pointer to file structure + * @ubuf: pointer to user buffer + * @length: buffer length + * @offset: data offset in buffer + * + * returns >=0 data length on success , <0 on error + */ +static ssize_t mei_read(struct file *file, char __user *ubuf, + size_t length, loff_t *offset) +{ + struct mei_cl *cl = file->private_data; + struct mei_cl_cb *cb_pos = NULL; + struct mei_cl_cb *cb = NULL; + struct mei_device *dev; + int i; + int rets; + int err; + + + if (WARN_ON(!cl || !cl->dev)) + return -ENODEV; + + dev = cl->dev; + + mutex_lock(&dev->device_lock); + if (dev->mei_state != MEI_ENABLED) { + rets = -ENODEV; + goto out; + } + + if ((cl->sm_state & MEI_WD_STATE_INDEPENDENCE_MSG_SENT) == 0) { + /* Do not allow to read watchdog client */ + i = mei_find_me_client_index(dev, mei_wd_guid); + if (i >= 0) { + struct mei_me_client *me_client = &dev->me_clients[i]; + + if (cl->me_client_id == me_client->client_id) { + rets = -EBADF; + goto out; + } + } + } else { + cl->sm_state &= ~MEI_WD_STATE_INDEPENDENCE_MSG_SENT; + } + + if (cl == &dev->iamthif_cl) { + rets = amthi_read(dev, file, ubuf, length, offset); + goto out; + } + + if (cl->read_cb && cl->read_cb->information > *offset) { + cb = cl->read_cb; + goto copy_buffer; + } else if (cl->read_cb && cl->read_cb->information > 0 && + cl->read_cb->information <= *offset) { + cb = cl->read_cb; + rets = 0; + goto free; + } else if ((!cl->read_cb || !cl->read_cb->information) && + *offset > 0) { + /*Offset needs to be cleaned for contiguous reads*/ + *offset = 0; + rets = 0; + goto out; + } + + err = mei_start_read(dev, cl); + if (err && err != -EBUSY) { + dev_dbg(&dev->pdev->dev, + "mei start read failure with status = %d\n", err); + rets = err; + goto out; + } + + if (MEI_READ_COMPLETE != cl->reading_state && + !waitqueue_active(&cl->rx_wait)) { + if (file->f_flags & O_NONBLOCK) { + rets = -EAGAIN; + goto out; + } + + mutex_unlock(&dev->device_lock); + + if (wait_event_interruptible(cl->rx_wait, + (MEI_READ_COMPLETE == cl->reading_state || + MEI_FILE_INITIALIZING == cl->state || + MEI_FILE_DISCONNECTED == cl->state || + MEI_FILE_DISCONNECTING == cl->state))) { + if (signal_pending(current)) + return -EINTR; + return -ERESTARTSYS; + } + + mutex_lock(&dev->device_lock); + if (MEI_FILE_INITIALIZING == cl->state || + MEI_FILE_DISCONNECTED == cl->state || + MEI_FILE_DISCONNECTING == cl->state) { + rets = -EBUSY; + goto out; + } + } + + cb = cl->read_cb; + + if (!cb) { + rets = -ENODEV; + goto out; + } + if (cl->reading_state != MEI_READ_COMPLETE) { + rets = 0; + goto out; + } + /* now copy the data to user space */ +copy_buffer: + dev_dbg(&dev->pdev->dev, "cb->response_buffer size - %d\n", + cb->response_buffer.size); + dev_dbg(&dev->pdev->dev, "cb->information - %lu\n", + cb->information); + if (length == 0 || ubuf == NULL || *offset > cb->information) { + rets = -EMSGSIZE; + goto free; + } + + /* length is being truncated to PAGE_SIZE, however, */ + /* information size may be longer */ + length = min_t(size_t, length, (cb->information - *offset)); + + if (copy_to_user(ubuf, cb->response_buffer.data + *offset, length)) { + rets = -EFAULT; + goto free; + } + + rets = length; + *offset += length; + if ((unsigned long)*offset < cb->information) + goto out; + +free: + cb_pos = find_read_list_entry(dev, cl); + /* Remove entry from read list */ + if (cb_pos) + list_del(&cb_pos->cb_list); + mei_free_cb_private(cb); + cl->reading_state = MEI_IDLE; + cl->read_cb = NULL; + cl->read_pending = 0; +out: + dev_dbg(&dev->pdev->dev, "end mei read rets= %d\n", rets); + mutex_unlock(&dev->device_lock); + return rets; +} + +/** + * mei_write - the write function. + * + * @file: pointer to file structure + * @ubuf: pointer to user buffer + * @length: buffer length + * @offset: data offset in buffer + * + * returns >=0 data length on success , <0 on error + */ +static ssize_t mei_write(struct file *file, const char __user *ubuf, + size_t length, loff_t *offset) +{ + struct mei_cl *cl = file->private_data; + struct mei_cl_cb *write_cb = NULL; + struct mei_msg_hdr mei_hdr; + struct mei_device *dev; + unsigned long timeout = 0; + int rets; + int i; + + if (WARN_ON(!cl || !cl->dev)) + return -ENODEV; + + dev = cl->dev; + + mutex_lock(&dev->device_lock); + + if (dev->mei_state != MEI_ENABLED) { + mutex_unlock(&dev->device_lock); + return -ENODEV; + } + + if (cl == &dev->iamthif_cl) { + write_cb = find_amthi_read_list_entry(dev, file); + + if (write_cb) { + timeout = write_cb->read_time + + msecs_to_jiffies(IAMTHIF_READ_TIMER); + + if (time_after(jiffies, timeout) || + cl->reading_state == MEI_READ_COMPLETE) { + *offset = 0; + list_del(&write_cb->cb_list); + mei_free_cb_private(write_cb); + write_cb = NULL; + } + } + } + + /* free entry used in read */ + if (cl->reading_state == MEI_READ_COMPLETE) { + *offset = 0; + write_cb = find_read_list_entry(dev, cl); + if (write_cb) { + list_del(&write_cb->cb_list); + mei_free_cb_private(write_cb); + write_cb = NULL; + cl->reading_state = MEI_IDLE; + cl->read_cb = NULL; + cl->read_pending = 0; + } + } else if (cl->reading_state == MEI_IDLE && !cl->read_pending) + *offset = 0; + + + write_cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); + if (!write_cb) { + mutex_unlock(&dev->device_lock); + return -ENOMEM; + } + + write_cb->file_object = file; + write_cb->file_private = cl; + write_cb->request_buffer.data = kmalloc(length, GFP_KERNEL); + rets = -ENOMEM; + if (!write_cb->request_buffer.data) + goto unlock_dev; + + dev_dbg(&dev->pdev->dev, "length =%d\n", (int) length); + + rets = -EFAULT; + if (copy_from_user(write_cb->request_buffer.data, ubuf, length)) + goto unlock_dev; + + cl->sm_state = 0; + if (length == 4 && + ((memcmp(mei_wd_state_independence_msg[0], + write_cb->request_buffer.data, 4) == 0) || + (memcmp(mei_wd_state_independence_msg[1], + write_cb->request_buffer.data, 4) == 0) || + (memcmp(mei_wd_state_independence_msg[2], + write_cb->request_buffer.data, 4) == 0))) + cl->sm_state |= MEI_WD_STATE_INDEPENDENCE_MSG_SENT; + + INIT_LIST_HEAD(&write_cb->cb_list); + if (cl == &dev->iamthif_cl) { + write_cb->response_buffer.data = + kmalloc(dev->iamthif_mtu, GFP_KERNEL); + if (!write_cb->response_buffer.data) { + rets = -ENOMEM; + goto unlock_dev; + } + if (dev->mei_state != MEI_ENABLED) { + rets = -ENODEV; + goto unlock_dev; + } + for (i = 0; i < dev->me_clients_num; i++) { + if (dev->me_clients[i].client_id == + dev->iamthif_cl.me_client_id) + break; + } + + if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id)) { + rets = -ENODEV; + goto unlock_dev; + } + if (i == dev->me_clients_num || + (dev->me_clients[i].client_id != + dev->iamthif_cl.me_client_id)) { + rets = -ENODEV; + goto unlock_dev; + } else if (length > dev->me_clients[i].props.max_msg_length || + length <= 0) { + rets = -EMSGSIZE; + goto unlock_dev; + } + + write_cb->response_buffer.size = dev->iamthif_mtu; + write_cb->major_file_operations = MEI_IOCTL; + write_cb->information = 0; + write_cb->request_buffer.size = length; + if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) { + rets = -ENODEV; + goto unlock_dev; + } + + if (!list_empty(&dev->amthi_cmd_list.mei_cb.cb_list) || + dev->iamthif_state != MEI_IAMTHIF_IDLE) { + dev_dbg(&dev->pdev->dev, "amthi_state = %d\n", + (int) dev->iamthif_state); + dev_dbg(&dev->pdev->dev, "add amthi cb to amthi cmd waiting list\n"); + list_add_tail(&write_cb->cb_list, + &dev->amthi_cmd_list.mei_cb.cb_list); + rets = length; + } else { + dev_dbg(&dev->pdev->dev, "call amthi write\n"); + rets = amthi_write(dev, write_cb); + + if (rets) { + dev_dbg(&dev->pdev->dev, "amthi write failed with status = %d\n", + rets); + goto unlock_dev; + } + rets = length; + } + mutex_unlock(&dev->device_lock); + return rets; + } + + write_cb->major_file_operations = MEI_WRITE; + /* make sure information is zero before we start */ + + write_cb->information = 0; + write_cb->request_buffer.size = length; + + dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n", + cl->host_client_id, cl->me_client_id); + if (cl->state != MEI_FILE_CONNECTED) { + rets = -ENODEV; + dev_dbg(&dev->pdev->dev, "host client = %d, is not connected to ME client = %d", + cl->host_client_id, + cl->me_client_id); + goto unlock_dev; + } + for (i = 0; i < dev->me_clients_num; i++) { + if (dev->me_clients[i].client_id == + cl->me_client_id) + break; + } + if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id)) { + rets = -ENODEV; + goto unlock_dev; + } + if (i == dev->me_clients_num) { + rets = -ENODEV; + goto unlock_dev; + } + if (length > dev->me_clients[i].props.max_msg_length || length <= 0) { + rets = -EINVAL; + goto unlock_dev; + } + write_cb->file_private = cl; + + rets = mei_flow_ctrl_creds(dev, cl); + if (rets < 0) + goto unlock_dev; + + if (rets && dev->mei_host_buffer_is_empty) { + rets = 0; + dev->mei_host_buffer_is_empty = false; + if (length > ((((dev->host_hw_state & H_CBD) >> 24) * + sizeof(u32)) - sizeof(struct mei_msg_hdr))) { + + mei_hdr.length = + (((dev->host_hw_state & H_CBD) >> 24) * + sizeof(u32)) - + sizeof(struct mei_msg_hdr); + mei_hdr.msg_complete = 0; + } else { + mei_hdr.length = length; + mei_hdr.msg_complete = 1; + } + mei_hdr.host_addr = cl->host_client_id; + mei_hdr.me_addr = cl->me_client_id; + mei_hdr.reserved = 0; + dev_dbg(&dev->pdev->dev, "call mei_write_message header=%08x.\n", + *((u32 *) &mei_hdr)); + if (mei_write_message(dev, &mei_hdr, + (unsigned char *) (write_cb->request_buffer.data), + mei_hdr.length)) { + rets = -ENODEV; + goto unlock_dev; + } + cl->writing_state = MEI_WRITING; + write_cb->information = mei_hdr.length; + if (mei_hdr.msg_complete) { + if (mei_flow_ctrl_reduce(dev, cl)) { + rets = -ENODEV; + goto unlock_dev; + } + list_add_tail(&write_cb->cb_list, + &dev->write_waiting_list.mei_cb.cb_list); + } else { + list_add_tail(&write_cb->cb_list, + &dev->write_list.mei_cb.cb_list); + } + + } else { + + write_cb->information = 0; + cl->writing_state = MEI_WRITING; + list_add_tail(&write_cb->cb_list, + &dev->write_list.mei_cb.cb_list); + } + mutex_unlock(&dev->device_lock); + return length; + +unlock_dev: + mutex_unlock(&dev->device_lock); + mei_free_cb_private(write_cb); + return rets; +} + + +/** + * mei_ioctl - the IOCTL function + * + * @file: pointer to file structure + * @cmd: ioctl command + * @data: pointer to mei message structure + * + * returns 0 on success , <0 on error + */ +static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data) +{ + struct mei_device *dev; + struct mei_cl *cl = file->private_data; + struct mei_connect_client_data *connect_data = NULL; + int rets; + + if (cmd != IOCTL_MEI_CONNECT_CLIENT) + return -EINVAL; + + if (WARN_ON(!cl || !cl->dev)) + return -ENODEV; + + dev = cl->dev; + + dev_dbg(&dev->pdev->dev, "IOCTL cmd = 0x%x", cmd); + + mutex_lock(&dev->device_lock); + if (dev->mei_state != MEI_ENABLED) { + rets = -ENODEV; + goto out; + } + + dev_dbg(&dev->pdev->dev, ": IOCTL_MEI_CONNECT_CLIENT.\n"); + + connect_data = kzalloc(sizeof(struct mei_connect_client_data), + GFP_KERNEL); + if (!connect_data) { + rets = -ENOMEM; + goto out; + } + dev_dbg(&dev->pdev->dev, "copy connect data from user\n"); + if (copy_from_user(connect_data, (char __user *)data, + sizeof(struct mei_connect_client_data))) { + dev_dbg(&dev->pdev->dev, "failed to copy data from userland\n"); + rets = -EFAULT; + goto out; + } + rets = mei_ioctl_connect_client(file, connect_data); + + /* if all is ok, copying the data back to user. */ + if (rets) + goto out; + + dev_dbg(&dev->pdev->dev, "copy connect data to user\n"); + if (copy_to_user((char __user *)data, connect_data, + sizeof(struct mei_connect_client_data))) { + dev_dbg(&dev->pdev->dev, "failed to copy data to userland\n"); + rets = -EFAULT; + goto out; + } + +out: + kfree(connect_data); + mutex_unlock(&dev->device_lock); + return rets; +} + +/** + * mei_compat_ioctl - the compat IOCTL function + * + * @file: pointer to file structure + * @cmd: ioctl command + * @data: pointer to mei message structure + * + * returns 0 on success , <0 on error + */ +#ifdef CONFIG_COMPAT +static long mei_compat_ioctl(struct file *file, + unsigned int cmd, unsigned long data) +{ + return mei_ioctl(file, cmd, (unsigned long)compat_ptr(data)); +} +#endif + + +/** + * mei_poll - the poll function + * + * @file: pointer to file structure + * @wait: pointer to poll_table structure + * + * returns poll mask + */ +static unsigned int mei_poll(struct file *file, poll_table *wait) +{ + struct mei_cl *cl = file->private_data; + struct mei_device *dev; + unsigned int mask = 0; + + if (WARN_ON(!cl || !cl->dev)) + return mask; + + dev = cl->dev; + + mutex_lock(&dev->device_lock); + + if (dev->mei_state != MEI_ENABLED) + goto out; + + + if (cl == &dev->iamthif_cl) { + mutex_unlock(&dev->device_lock); + poll_wait(file, &dev->iamthif_cl.wait, wait); + mutex_lock(&dev->device_lock); + if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE && + dev->iamthif_file_object == file) { + mask |= (POLLIN | POLLRDNORM); + dev_dbg(&dev->pdev->dev, "run next amthi cb\n"); + mei_run_next_iamthif_cmd(dev); + } + goto out; + } + + mutex_unlock(&dev->device_lock); + poll_wait(file, &cl->tx_wait, wait); + mutex_lock(&dev->device_lock); + if (MEI_WRITE_COMPLETE == cl->writing_state) + mask |= (POLLIN | POLLRDNORM); + +out: + mutex_unlock(&dev->device_lock); + return mask; +} + +/* + * file operations structure will be used for mei char device. + */ +static const struct file_operations mei_fops = { + .owner = THIS_MODULE, + .read = mei_read, + .unlocked_ioctl = mei_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = mei_compat_ioctl, +#endif + .open = mei_open, + .release = mei_release, + .write = mei_write, + .poll = mei_poll, + .llseek = no_llseek +}; + + +/* + * Misc Device Struct + */ +static struct miscdevice mei_misc_device = { + .name = "mei", + .fops = &mei_fops, + .minor = MISC_DYNAMIC_MINOR, +}; + +/** + * mei_probe - Device Initialization Routine + * + * @pdev: PCI device structure + * @ent: entry in kcs_pci_tbl + * + * returns 0 on success, <0 on failure. + */ +static int __devinit mei_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct mei_device *dev; + int err; + + mutex_lock(&mei_mutex); + if (mei_device) { + err = -EEXIST; + goto end; + } + /* enable pci dev */ + err = pci_enable_device(pdev); + if (err) { + printk(KERN_ERR "mei: Failed to enable pci device.\n"); + goto end; + } + /* set PCI host mastering */ + pci_set_master(pdev); + /* pci request regions for mei driver */ + err = pci_request_regions(pdev, mei_driver_name); + if (err) { + printk(KERN_ERR "mei: Failed to get pci regions.\n"); + goto disable_device; + } + /* allocates and initializes the mei dev structure */ + dev = mei_device_init(pdev); + if (!dev) { + err = -ENOMEM; + goto release_regions; + } + /* mapping IO device memory */ + dev->mem_addr = pci_iomap(pdev, 0, 0); + if (!dev->mem_addr) { + printk(KERN_ERR "mei: mapping I/O device memory failure.\n"); + err = -ENOMEM; + goto free_device; + } + pci_enable_msi(pdev); + + /* request and enable interrupt */ + if (pci_dev_msi_enabled(pdev)) + err = request_threaded_irq(pdev->irq, + NULL, + mei_interrupt_thread_handler, + 0, mei_driver_name, dev); + else + err = request_threaded_irq(pdev->irq, + mei_interrupt_quick_handler, + mei_interrupt_thread_handler, + IRQF_SHARED, mei_driver_name, dev); + + if (err) { + printk(KERN_ERR "mei: request_threaded_irq failure. irq = %d\n", + pdev->irq); + goto unmap_memory; + } + INIT_DELAYED_WORK(&dev->timer_work, mei_timer); + if (mei_hw_init(dev)) { + printk(KERN_ERR "mei: Init hw failure.\n"); + err = -ENODEV; + goto release_irq; + } + + err = misc_register(&mei_misc_device); + if (err) + goto release_irq; + + mei_device = pdev; + pci_set_drvdata(pdev, dev); + + + schedule_delayed_work(&dev->timer_work, HZ); + + mutex_unlock(&mei_mutex); + + pr_debug("initialization successful.\n"); + + return 0; + +release_irq: + /* disable interrupts */ + dev->host_hw_state = mei_hcsr_read(dev); + mei_disable_interrupts(dev); + flush_scheduled_work(); + free_irq(pdev->irq, dev); + pci_disable_msi(pdev); +unmap_memory: + pci_iounmap(pdev, dev->mem_addr); +free_device: + kfree(dev); +release_regions: + pci_release_regions(pdev); +disable_device: + pci_disable_device(pdev); +end: + mutex_unlock(&mei_mutex); + printk(KERN_ERR "mei: Driver initialization failed.\n"); + return err; +} + +/** + * mei_remove - Device Removal Routine + * + * @pdev: PCI device structure + * + * mei_remove is called by the PCI subsystem to alert the driver + * that it should release a PCI device. + */ +static void __devexit mei_remove(struct pci_dev *pdev) +{ + struct mei_device *dev; + + if (mei_device != pdev) + return; + + dev = pci_get_drvdata(pdev); + if (!dev) + return; + + mutex_lock(&dev->device_lock); + + mei_wd_stop(dev, false); + + mei_device = NULL; + + if (dev->iamthif_cl.state == MEI_FILE_CONNECTED) { + dev->iamthif_cl.state = MEI_FILE_DISCONNECTING; + mei_disconnect_host_client(dev, &dev->iamthif_cl); + } + if (dev->wd_cl.state == MEI_FILE_CONNECTED) { + dev->wd_cl.state = MEI_FILE_DISCONNECTING; + mei_disconnect_host_client(dev, &dev->wd_cl); + } + + /* Unregistering watchdog device */ + mei_watchdog_unregister(dev); + + /* remove entry if already in list */ + dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n"); + mei_remove_client_from_file_list(dev, dev->wd_cl.host_client_id); + mei_remove_client_from_file_list(dev, dev->iamthif_cl.host_client_id); + + dev->iamthif_current_cb = NULL; + dev->me_clients_num = 0; + + mutex_unlock(&dev->device_lock); + + flush_scheduled_work(); + + /* disable interrupts */ + mei_disable_interrupts(dev); + + free_irq(pdev->irq, dev); + pci_disable_msi(pdev); + pci_set_drvdata(pdev, NULL); + + if (dev->mem_addr) + pci_iounmap(pdev, dev->mem_addr); + + kfree(dev); + + pci_release_regions(pdev); + pci_disable_device(pdev); +} +#ifdef CONFIG_PM +static int mei_pci_suspend(struct device *device) +{ + struct pci_dev *pdev = to_pci_dev(device); + struct mei_device *dev = pci_get_drvdata(pdev); + int err; + + if (!dev) + return -ENODEV; + mutex_lock(&dev->device_lock); + /* Stop watchdog if exists */ + err = mei_wd_stop(dev, true); + /* Set new mei state */ + if (dev->mei_state == MEI_ENABLED || + dev->mei_state == MEI_RECOVERING_FROM_RESET) { + dev->mei_state = MEI_POWER_DOWN; + mei_reset(dev, 0); + } + mutex_unlock(&dev->device_lock); + + free_irq(pdev->irq, dev); + pci_disable_msi(pdev); + + return err; +} + +static int mei_pci_resume(struct device *device) +{ + struct pci_dev *pdev = to_pci_dev(device); + struct mei_device *dev; + int err; + + dev = pci_get_drvdata(pdev); + if (!dev) + return -ENODEV; + + pci_enable_msi(pdev); + + /* request and enable interrupt */ + if (pci_dev_msi_enabled(pdev)) + err = request_threaded_irq(pdev->irq, + NULL, + mei_interrupt_thread_handler, + 0, mei_driver_name, dev); + else + err = request_threaded_irq(pdev->irq, + mei_interrupt_quick_handler, + mei_interrupt_thread_handler, + IRQF_SHARED, mei_driver_name, dev); + + if (err) { + printk(KERN_ERR "mei: Request_irq failure. irq = %d\n", + pdev->irq); + return err; + } + + mutex_lock(&dev->device_lock); + dev->mei_state = MEI_POWER_UP; + mei_reset(dev, 1); + mutex_unlock(&dev->device_lock); + + /* Start timer if stopped in suspend */ + schedule_delayed_work(&dev->timer_work, HZ); + + return err; +} +static SIMPLE_DEV_PM_OPS(mei_pm_ops, mei_pci_suspend, mei_pci_resume); +#define MEI_PM_OPS (&mei_pm_ops) +#else +#define MEI_PM_OPS NULL +#endif /* CONFIG_PM */ +/* + * PCI driver structure + */ +static struct pci_driver mei_driver = { + .name = mei_driver_name, + .id_table = mei_pci_tbl, + .probe = mei_probe, + .remove = __devexit_p(mei_remove), + .shutdown = __devexit_p(mei_remove), + .driver.pm = MEI_PM_OPS, +}; + +/** + * mei_init_module - Driver Registration Routine + * + * mei_init_module is the first routine called when the driver is + * loaded. All it does is to register with the PCI subsystem. + * + * returns 0 on success, <0 on failure. + */ +static int __init mei_init_module(void) +{ + int ret; + + pr_debug("loading.\n"); + /* init pci module */ + ret = pci_register_driver(&mei_driver); + if (ret < 0) + printk(KERN_ERR "mei: Error registering driver.\n"); + + return ret; +} + +module_init(mei_init_module); + +/** + * mei_exit_module - Driver Exit Cleanup Routine + * + * mei_exit_module is called just before the driver is removed + * from memory. + */ +static void __exit mei_exit_module(void) +{ + misc_deregister(&mei_misc_device); + pci_unregister_driver(&mei_driver); + + pr_debug("unloaded successfully.\n"); +} + +module_exit(mei_exit_module); + + +MODULE_AUTHOR("Intel Corporation"); +MODULE_DESCRIPTION("Intel(R) Management Engine Interface"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/misc/mei/mei-amt-version.c b/drivers/misc/mei/mei-amt-version.c new file mode 100644 index 0000000..ac2a507 --- /dev/null +++ b/drivers/misc/mei/mei-amt-version.c @@ -0,0 +1,481 @@ +/****************************************************************************** + * Intel Management Engine Interface (Intel MEI) Linux driver + * Intel MEI Interface Header + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Corporation. + * linux-mei@linux.intel.com + * http://www.intel.com + * + * BSD LICENSE + * + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mei.h" + +/***************************************************************************** + * Intel Management Engine Interface + *****************************************************************************/ + +#define mei_msg(_me, fmt, ARGS...) do { \ + if (_me->verbose) \ + fprintf(stderr, fmt, ##ARGS); \ +} while (0) + +#define mei_err(_me, fmt, ARGS...) do { \ + fprintf(stderr, "Error: " fmt, ##ARGS); \ +} while (0) + +struct mei { + uuid_le guid; + bool initialized; + bool verbose; + unsigned int buf_size; + unsigned char prot_ver; + int fd; +}; + +static void mei_deinit(struct mei *cl) +{ + if (cl->fd != -1) + close(cl->fd); + cl->fd = -1; + cl->buf_size = 0; + cl->prot_ver = 0; + cl->initialized = false; +} + +static bool mei_init(struct mei *me, const uuid_le *guid, + unsigned char req_protocol_version, bool verbose) +{ + int result; + struct mei_client *cl; + struct mei_connect_client_data data; + + mei_deinit(me); + + me->verbose = verbose; + + me->fd = open("/dev/mei", O_RDWR); + if (me->fd == -1) { + mei_err(me, "Cannot establish a handle to the Intel MEI driver\n"); + goto err; + } + memcpy(&me->guid, guid, sizeof(*guid)); + memset(&data, 0, sizeof(data)); + me->initialized = true; + + memcpy(&data.in_client_uuid, &me->guid, sizeof(me->guid)); + result = ioctl(me->fd, IOCTL_MEI_CONNECT_CLIENT, &data); + if (result) { + mei_err(me, "IOCTL_MEI_CONNECT_CLIENT receive message. err=%d\n", result); + goto err; + } + cl = &data.out_client_properties; + mei_msg(me, "max_message_length %d\n", cl->max_msg_length); + mei_msg(me, "protocol_version %d\n", cl->protocol_version); + + if ((req_protocol_version > 0) && + (cl->protocol_version != req_protocol_version)) { + mei_err(me, "Intel MEI protocol version not supported\n"); + goto err; + } + + me->buf_size = cl->max_msg_length; + me->prot_ver = cl->protocol_version; + + return true; +err: + mei_deinit(me); + return false; +} + +static ssize_t mei_recv_msg(struct mei *me, unsigned char *buffer, + ssize_t len, unsigned long timeout) +{ + ssize_t rc; + + mei_msg(me, "call read length = %zd\n", len); + + rc = read(me->fd, buffer, len); + if (rc < 0) { + mei_err(me, "read failed with status %zd %s\n", + rc, strerror(errno)); + mei_deinit(me); + } else { + mei_msg(me, "read succeeded with result %zd\n", rc); + } + return rc; +} + +static ssize_t mei_send_msg(struct mei *me, const unsigned char *buffer, + ssize_t len, unsigned long timeout) +{ + struct timeval tv; + ssize_t written; + ssize_t rc; + fd_set set; + + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000000; + + mei_msg(me, "call write length = %zd\n", len); + + written = write(me->fd, buffer, len); + if (written < 0) { + rc = -errno; + mei_err(me, "write failed with status %zd %s\n", + written, strerror(errno)); + goto out; + } + + FD_ZERO(&set); + FD_SET(me->fd, &set); + rc = select(me->fd + 1 , &set, NULL, NULL, &tv); + if (rc > 0 && FD_ISSET(me->fd, &set)) { + mei_msg(me, "write success\n"); + } else if (rc == 0) { + mei_err(me, "write failed on timeout with status\n"); + goto out; + } else { /* rc < 0 */ + mei_err(me, "write failed on select with status %zd\n", rc); + goto out; + } + + rc = written; +out: + if (rc < 0) + mei_deinit(me); + + return rc; +} + +/*************************************************************************** + * Intel Advanced Management Technolgy ME Client + ***************************************************************************/ + +#define AMT_MAJOR_VERSION 1 +#define AMT_MINOR_VERSION 1 + +#define AMT_STATUS_SUCCESS 0x0 +#define AMT_STATUS_INTERNAL_ERROR 0x1 +#define AMT_STATUS_NOT_READY 0x2 +#define AMT_STATUS_INVALID_AMT_MODE 0x3 +#define AMT_STATUS_INVALID_MESSAGE_LENGTH 0x4 + +#define AMT_STATUS_HOST_IF_EMPTY_RESPONSE 0x4000 +#define AMT_STATUS_SDK_RESOURCES 0x1004 + + +#define AMT_BIOS_VERSION_LEN 65 +#define AMT_VERSIONS_NUMBER 50 +#define AMT_UNICODE_STRING_LEN 20 + +struct amt_unicode_string { + uint16_t length; + char string[AMT_UNICODE_STRING_LEN]; +} __attribute__((packed)); + +struct amt_version_type { + struct amt_unicode_string description; + struct amt_unicode_string version; +} __attribute__((packed)); + +struct amt_version { + uint8_t major; + uint8_t minor; +} __attribute__((packed)); + +struct amt_code_versions { + uint8_t bios[AMT_BIOS_VERSION_LEN]; + uint32_t count; + struct amt_version_type versions[AMT_VERSIONS_NUMBER]; +} __attribute__((packed)); + +/*************************************************************************** + * Intel Advanced Management Technolgy Host Interface + ***************************************************************************/ + +struct amt_host_if_msg_header { + struct amt_version version; + uint16_t _reserved; + uint32_t command; + uint32_t length; +} __attribute__((packed)); + +struct amt_host_if_resp_header { + struct amt_host_if_msg_header header; + uint32_t status; + unsigned char data[0]; +} __attribute__((packed)); + +const uuid_le MEI_IAMTHIF = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, \ + 0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, 0x81, 0x4c); + +#define AMT_HOST_IF_CODE_VERSIONS_REQUEST 0x0400001A +#define AMT_HOST_IF_CODE_VERSIONS_RESPONSE 0x0480001A + +const struct amt_host_if_msg_header CODE_VERSION_REQ = { + .version = {AMT_MAJOR_VERSION, AMT_MINOR_VERSION}, + ._reserved = 0, + .command = AMT_HOST_IF_CODE_VERSIONS_REQUEST, + .length = 0 +}; + + +struct amt_host_if { + struct mei mei_cl; + unsigned long send_timeout; + bool initialized; +}; + + +static bool amt_host_if_init(struct amt_host_if *acmd, + unsigned long send_timeout, bool verbose) +{ + acmd->send_timeout = (send_timeout) ? send_timeout : 20000; + acmd->initialized = mei_init(&acmd->mei_cl, &MEI_IAMTHIF, 0, verbose); + return acmd->initialized; +} + +static void amt_host_if_deinit(struct amt_host_if *acmd) +{ + mei_deinit(&acmd->mei_cl); + acmd->initialized = false; +} + +static uint32_t amt_verify_code_versions(const struct amt_host_if_resp_header *resp) +{ + uint32_t status = AMT_STATUS_SUCCESS; + struct amt_code_versions *code_ver; + size_t code_ver_len; + uint32_t ver_type_cnt; + uint32_t len; + uint32_t i; + + code_ver = (struct amt_code_versions *)resp->data; + /* length - sizeof(status) */ + code_ver_len = resp->header.length - sizeof(uint32_t); + ver_type_cnt = code_ver_len - + sizeof(code_ver->bios) - + sizeof(code_ver->count); + if (code_ver->count != ver_type_cnt / sizeof(struct amt_version_type)) { + status = AMT_STATUS_INTERNAL_ERROR; + goto out; + } + + for (i = 0; i < code_ver->count; i++) { + len = code_ver->versions[i].description.length; + + if (len > AMT_UNICODE_STRING_LEN) { + status = AMT_STATUS_INTERNAL_ERROR; + goto out; + } + + len = code_ver->versions[i].version.length; + if (code_ver->versions[i].version.string[len] != '\0' || + len != strlen(code_ver->versions[i].version.string)) { + status = AMT_STATUS_INTERNAL_ERROR; + goto out; + } + } +out: + return status; +} + +static uint32_t amt_verify_response_header(uint32_t command, + const struct amt_host_if_msg_header *resp_hdr, + uint32_t response_size) +{ + if (response_size < sizeof(struct amt_host_if_resp_header)) { + return AMT_STATUS_INTERNAL_ERROR; + } else if (response_size != (resp_hdr->length + + sizeof(struct amt_host_if_msg_header))) { + return AMT_STATUS_INTERNAL_ERROR; + } else if (resp_hdr->command != command) { + return AMT_STATUS_INTERNAL_ERROR; + } else if (resp_hdr->_reserved != 0) { + return AMT_STATUS_INTERNAL_ERROR; + } else if (resp_hdr->version.major != AMT_MAJOR_VERSION || + resp_hdr->version.minor < AMT_MINOR_VERSION) { + return AMT_STATUS_INTERNAL_ERROR; + } + return AMT_STATUS_SUCCESS; +} + +static uint32_t amt_host_if_call(struct amt_host_if *acmd, + const unsigned char *command, ssize_t command_sz, + uint8_t **read_buf, uint32_t rcmd, + unsigned int expected_sz) +{ + uint32_t in_buf_sz; + uint32_t out_buf_sz; + ssize_t written; + uint32_t status; + struct amt_host_if_resp_header *msg_hdr; + + in_buf_sz = acmd->mei_cl.buf_size; + *read_buf = (uint8_t *)malloc(sizeof(uint8_t) * in_buf_sz); + if (*read_buf == NULL) + return AMT_STATUS_SDK_RESOURCES; + memset(*read_buf, 0, in_buf_sz); + msg_hdr = (struct amt_host_if_resp_header *)*read_buf; + + written = mei_send_msg(&acmd->mei_cl, + command, command_sz, acmd->send_timeout); + if (written != command_sz) + return AMT_STATUS_INTERNAL_ERROR; + + out_buf_sz = mei_recv_msg(&acmd->mei_cl, *read_buf, in_buf_sz, 2000); + if (out_buf_sz <= 0) + return AMT_STATUS_HOST_IF_EMPTY_RESPONSE; + + status = msg_hdr->status; + if (status != AMT_STATUS_SUCCESS) + return status; + + status = amt_verify_response_header(rcmd, + &msg_hdr->header, out_buf_sz); + if (status != AMT_STATUS_SUCCESS) + return status; + + if (expected_sz && expected_sz != out_buf_sz) + return AMT_STATUS_INTERNAL_ERROR; + + return AMT_STATUS_SUCCESS; +} + + +static uint32_t amt_get_code_versions(struct amt_host_if *cmd, + struct amt_code_versions *versions) +{ + struct amt_host_if_resp_header *response = NULL; + uint32_t status; + + status = amt_host_if_call(cmd, + (const unsigned char *)&CODE_VERSION_REQ, + sizeof(CODE_VERSION_REQ), + (uint8_t **)&response, + AMT_HOST_IF_CODE_VERSIONS_RESPONSE, 0); + + if (status != AMT_STATUS_SUCCESS) + goto out; + + status = amt_verify_code_versions(response); + if (status != AMT_STATUS_SUCCESS) + goto out; + + memcpy(versions, response->data, sizeof(struct amt_code_versions)); +out: + if (response != NULL) + free(response); + + return status; +} + +/************************** end of amt_host_if_command ***********************/ +int main(int argc, char **argv) +{ + struct amt_code_versions ver; + struct amt_host_if acmd; + unsigned int i; + uint32_t status; + int ret; + bool verbose; + + verbose = (argc > 1 && strcmp(argv[1], "-v") == 0); + + if (!amt_host_if_init(&acmd, 5000, verbose)) { + ret = 1; + goto out; + } + + status = amt_get_code_versions(&acmd, &ver); + + amt_host_if_deinit(&acmd); + + switch (status) { + case AMT_STATUS_HOST_IF_EMPTY_RESPONSE: + printf("Intel AMT: DISABLED\n"); + ret = 0; + break; + case AMT_STATUS_SUCCESS: + printf("Intel AMT: ENABLED\n"); + for (i = 0; i < ver.count; i++) { + printf("%s:\t%s\n", ver.versions[i].description.string, + ver.versions[i].version.string); + } + ret = 0; + break; + default: + printf("An error has occurred\n"); + ret = 1; + break; + } + +out: + return ret; +} diff --git a/drivers/misc/mei/mei.h b/drivers/misc/mei/mei.h new file mode 100644 index 0000000..bc0d8b6 --- /dev/null +++ b/drivers/misc/mei/mei.h @@ -0,0 +1,110 @@ +/****************************************************************************** + * Intel Management Engine Interface (Intel MEI) Linux driver + * Intel MEI Interface Header + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Corporation. + * linux-mei@linux.intel.com + * http://www.intel.com + * + * BSD LICENSE + * + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +#ifndef _LINUX_MEI_H +#define _LINUX_MEI_H + +#include + +/* + * This IOCTL is used to associate the current file descriptor with a + * FW Client (given by UUID). This opens a communication channel + * between a host client and a FW client. From this point every read and write + * will communicate with the associated FW client. + * Only in close() (file_operation release()) the communication between + * the clients is disconnected + * + * The IOCTL argument is a struct with a union that contains + * the input parameter and the output parameter for this IOCTL. + * + * The input parameter is UUID of the FW Client. + * The output parameter is the properties of the FW client + * (FW protocol version and max message size). + * + */ +#define IOCTL_MEI_CONNECT_CLIENT \ + _IOWR('H' , 0x01, struct mei_connect_client_data) + +/* + * Intel MEI client information struct + */ +struct mei_client { + __u32 max_msg_length; + __u8 protocol_version; + __u8 reserved[3]; +}; + +/* + * IOCTL Connect Client Data structure + */ +struct mei_connect_client_data { + union { + uuid_le in_client_uuid; + struct mei_client out_client_properties; + }; +}; + +#endif /* _LINUX_MEI_H */ diff --git a/drivers/misc/mei/mei.txt b/drivers/misc/mei/mei.txt new file mode 100644 index 0000000..2785697 --- /dev/null +++ b/drivers/misc/mei/mei.txt @@ -0,0 +1,215 @@ +Intel(R) Management Engine Interface (Intel(R) MEI) +======================= + +Introduction +======================= + +The Intel Management Engine (Intel ME) is an isolated and protected computing +resource (Co-processor) residing inside certain Intel chipsets. The Intel ME +provides support for computer/IT management features. The feature set +depends on the Intel chipset SKU. + +The Intel Management Engine Interface (Intel MEI, previously known as HECI) +is the interface between the Host and Intel ME. This interface is exposed +to the host as a PCI device. The Intel MEI Driver is in charge of the +communication channel between a host application and the Intel ME feature. + +Each Intel ME feature (Intel ME Client) is addressed by a GUID/UUID and +each client has its own protocol. The protocol is message-based with a +header and payload up to 512 bytes. + +Prominent usage of the Intel ME Interface is to communicate with Intel(R) +Active Management Technology (Intel AMT)implemented in firmware running on +the Intel ME. + +Intel AMT provides the ability to manage a host remotely out-of-band (OOB) +even when the operating system running on the host processor has crashed or +is in a sleep state. + +Some examples of Intel AMT usage are: + - Monitoring hardware state and platform components + - Remote power off/on (useful for green computing or overnight IT + maintenance) + - OS updates + - Storage of useful platform information such as software assets + - Built-in hardware KVM + - Selective network isolation of Ethernet and IP protocol flows based + on policies set by a remote management console + - IDE device redirection from remote management console + +Intel AMT (OOB) communication is based on SOAP (deprecated +starting with Release 6.0) over HTTP/S or WS-Management protocol over +HTTP/S that are received from a remote management console application. + +For more information about Intel AMT: +http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide + +Intel MEI Driver +======================= + +The driver exposes a misc device called /dev/mei. + +An application maintains communication with an Intel ME feature while +/dev/mei is open. The binding to a specific features is performed by calling +MEI_CONNECT_CLIENT_IOCTL, which passes the desired UUID. +The number of instances of an Intel ME feature that can be opened +at the same time depends on the Intel ME feature, but most of the +features allow only a single instance. + +The Intel AMT Host Interface (Intel AMTHI) feature supports multiple +simultaneous user applications. Therefore, the Intel MEI driver handles +this internally by maintaining request queues for the applications. + +The driver is oblivious to data that is passed between firmware feature +and host application. + +Because some of the Intel ME features can change the system +configuration, the driver by default allows only a privileged +user to access it. + +A code snippet for an application communicating with +Intel AMTHI client: + struct mei_connect_client_data data; + fd = open(MEI_DEVICE); + + data.d.in_client_uuid = AMTHI_UUID; + + ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &data); + + printf("Ver=%d, MaxLen=%ld\n", + data.d.in_client_uuid.protocol_version, + data.d.in_client_uuid.max_msg_length); + + [...] + + write(fd, amthi_req_data, amthi_req_data_len); + + [...] + + read(fd, &amthi_res_data, amthi_res_data_len); + + [...] + close(fd); + +IOCTL: +====== +The Intel MEI Driver supports the following IOCTL command: + IOCTL_MEI_CONNECT_CLIENT Connect to firmware Feature (client). + + usage: + struct mei_connect_client_data clientData; + ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &clientData); + + inputs: + mei_connect_client_data struct contain the following + input field: + + in_client_uuid - UUID of the FW Feature that needs + to connect to. + outputs: + out_client_properties - Client Properties: MTU and Protocol Version. + + error returns: + EINVAL Wrong IOCTL Number + ENODEV Device or Connection is not initialized or ready. + (e.g. Wrong UUID) + ENOMEM Unable to allocate memory to client internal data. + EFAULT Fatal Error (e.g. Unable to access user input data) + EBUSY Connection Already Open + + Notes: + max_msg_length (MTU) in client properties describes the maximum + data that can be sent or received. (e.g. if MTU=2K, can send + requests up to bytes 2k and received responses upto 2k bytes). + +Intel ME Applications: +============== + +1) Intel Local Management Service (Intel LMS) + + Applications running locally on the platform communicate with Intel AMT Release + 2.0 and later releases in the same way that network applications do via SOAP + over HTTP (deprecated starting with Release 6.0) or with WS-Management over + SOAP over HTTP. This means that some Intel AMT features can be accessed from a + local application using the same network interface as a remote application + communicating with Intel AMT over the network. + + When a local application sends a message addressed to the local Intel AMT host + name, the Intel LMS, which listens for traffic directed to the host name, + intercepts the message and routes it to the Intel MEI. + For more information: + http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide + Under "About Intel AMT" => "Local Access" + + For downloading Intel LMS: + http://software.intel.com/en-us/articles/download-the-latest-intel-amt-open-source-drivers/ + + The Intel LMS opens a connection using the Intel MEI driver to the Intel LMS + firmware feature using a defined UUID and then communicates with the feature + using a protocol called Intel AMT Port Forwarding Protocol(Intel APF protocol). + The protocol is used to maintain multiple sessions with Intel AMT from a + single application. + + See the protocol specification in the Intel AMT Software Development Kit(SDK) + http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide + Under "SDK Resources" => "Intel(R) vPro(TM) Gateway(MPS)" + => "Information for Intel(R) vPro(TM) Gateway Developers" + => "Description of the Intel AMT Port Forwarding (APF)Protocol" + + 2) Intel AMT Remote configuration using a Local Agent + A Local Agent enables IT personnel to configure Intel AMT out-of-the-box + without requiring installing additional data to enable setup. The remote + configuration process may involve an ISV-developed remote configuration + agent that runs on the host. + For more information: + http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide + Under "Setup and Configuration of Intel AMT" => + "SDK Tools Supporting Setup and Configuration" => + "Using the Local Agent Sample" + + An open source Intel AMT configuration utility, implementing a local agent + that accesses the Intel MEI driver, can be found here: + http://software.intel.com/en-us/articles/download-the-latest-intel-amt-open-source-drivers/ + + +Intel AMT OS Health Watchdog: +============================= +The Intel AMT Watchdog is an OS Health (Hang/Crash) watchdog. +Whenever the OS hangs or crashes, Intel AMT will send an event +to any subscriber to this event. This mechanism means that +IT knows when a platform crashes even when there is a hard failure on the host. + +The Intel AMT Watchdog is composed of two parts: + 1) Firmware feature - receives the heartbeats + and sends an event when the heartbeats stop. + 2) Intel MEI driver - connects to the watchdog feature, configures the + watchdog and sends the heartbeats. + +The Intel MEI driver uses the kernel watchdog to configure the Intel AMT +Watchdog and to send heartbeats to it. The default timeout of the +watchdog is 120 seconds. + +If the Intel AMT Watchdog feature does not exist (i.e. the connection failed), +the Intel MEI driver will disable the sending of heartbeats. + +Supported Chipsets: +================== +7 Series Chipset Family +6 Series Chipset Family +5 Series Chipset Family +4 Series Chipset Family +Mobile 4 Series Chipset Family +ICH9 +82946GZ/GL +82G35 Express +82Q963/Q965 +82P965/G965 +Mobile PM965/GM965 +Mobile GME965/GLE960 +82Q35 Express +82G33/G31/P35/P31 Express +82Q33 Express +82X38/X48 Express + +--- +linux-mei@linux.intel.com diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h new file mode 100644 index 0000000..10b1b4e --- /dev/null +++ b/drivers/misc/mei/mei_dev.h @@ -0,0 +1,428 @@ +/* + * + * Intel Management Engine Interface (Intel MEI) Linux driver + * Copyright (c) 2003-2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef _MEI_DEV_H_ +#define _MEI_DEV_H_ + +#include +#include +#include "mei.h" +#include "hw.h" + +/* + * watch dog definition + */ +#define MEI_WATCHDOG_DATA_SIZE 16 +#define MEI_START_WD_DATA_SIZE 20 +#define MEI_WD_PARAMS_SIZE 4 +#define MEI_WD_STATE_INDEPENDENCE_MSG_SENT (1 << 0) + +#define MEI_RD_MSG_BUF_SIZE (128 * sizeof(u32)) + +/* + * MEI PCI Device object + */ +extern struct pci_dev *mei_device; + + +/* + * AMTHI Client UUID + */ +extern const uuid_le mei_amthi_guid; + +/* + * Watchdog Client UUID + */ +extern const uuid_le mei_wd_guid; + +/* + * Watchdog independence state message + */ +extern const u8 mei_wd_state_independence_msg[3][4]; + +/* + * Number of File descriptors/handles + * that can be opened to the driver. + * + * Limit to 253: 255 Total Clients + * minus internal client for AMTHI + * minus internal client for Watchdog + */ +#define MEI_MAX_OPEN_HANDLE_COUNT 253 + +/* + * Number of Maximum MEI Clients + */ +#define MEI_CLIENTS_MAX 255 + +/* File state */ +enum file_state { + MEI_FILE_INITIALIZING = 0, + MEI_FILE_CONNECTING, + MEI_FILE_CONNECTED, + MEI_FILE_DISCONNECTING, + MEI_FILE_DISCONNECTED +}; + +/* MEI device states */ +enum mei_states { + MEI_INITIALIZING = 0, + MEI_INIT_CLIENTS, + MEI_ENABLED, + MEI_RESETING, + MEI_DISABLED, + MEI_RECOVERING_FROM_RESET, + MEI_POWER_DOWN, + MEI_POWER_UP +}; + +/* init clients states*/ +enum mei_init_clients_states { + MEI_START_MESSAGE = 0, + MEI_ENUM_CLIENTS_MESSAGE, + MEI_CLIENT_PROPERTIES_MESSAGE +}; + +enum iamthif_states { + MEI_IAMTHIF_IDLE, + MEI_IAMTHIF_WRITING, + MEI_IAMTHIF_FLOW_CONTROL, + MEI_IAMTHIF_READING, + MEI_IAMTHIF_READ_COMPLETE +}; + +enum mei_file_transaction_states { + MEI_IDLE, + MEI_WRITING, + MEI_WRITE_COMPLETE, + MEI_FLOW_CONTROL, + MEI_READING, + MEI_READ_COMPLETE +}; + +/* MEI CB */ +enum mei_cb_major_types { + MEI_READ = 0, + MEI_WRITE, + MEI_IOCTL, + MEI_OPEN, + MEI_CLOSE +}; + +/* + * Intel MEI message data struct + */ +struct mei_message_data { + u32 size; + unsigned char *data; +} __packed; + + +struct mei_cl_cb { + struct list_head cb_list; + enum mei_cb_major_types major_file_operations; + void *file_private; + struct mei_message_data request_buffer; + struct mei_message_data response_buffer; + unsigned long information; + unsigned long read_time; + struct file *file_object; +}; + +/* MEI client instance carried as file->pirvate_data*/ +struct mei_cl { + struct list_head link; + struct mei_device *dev; + enum file_state state; + wait_queue_head_t tx_wait; + wait_queue_head_t rx_wait; + wait_queue_head_t wait; + int read_pending; + int status; + /* ID of client connected */ + u8 host_client_id; + u8 me_client_id; + u8 mei_flow_ctrl_creds; + u8 timer_count; + enum mei_file_transaction_states reading_state; + enum mei_file_transaction_states writing_state; + int sm_state; + struct mei_cl_cb *read_cb; +}; + +struct mei_io_list { + struct mei_cl_cb mei_cb; +}; + +/* MEI private device struct */ +struct mei_device { + struct pci_dev *pdev; /* pointer to pci device struct */ + /* + * lists of queues + */ + /* array of pointers to aio lists */ + struct mei_io_list read_list; /* driver read queue */ + struct mei_io_list write_list; /* driver write queue */ + struct mei_io_list write_waiting_list; /* write waiting queue */ + struct mei_io_list ctrl_wr_list; /* managed write IOCTL list */ + struct mei_io_list ctrl_rd_list; /* managed read IOCTL list */ + struct mei_io_list amthi_cmd_list; /* amthi list for cmd waiting */ + + /* driver managed amthi list for reading completed amthi cmd data */ + struct mei_io_list amthi_read_complete_list; + /* + * list of files + */ + struct list_head file_list; + long open_handle_count; + /* + * memory of device + */ + unsigned int mem_base; + unsigned int mem_length; + void __iomem *mem_addr; + /* + * lock for the device + */ + struct mutex device_lock; /* device lock */ + struct delayed_work timer_work; /* MEI timer delayed work (timeouts) */ + bool recvd_msg; + /* + * hw states of host and fw(ME) + */ + u32 host_hw_state; + u32 me_hw_state; + /* + * waiting queue for receive message from FW + */ + wait_queue_head_t wait_recvd_msg; + wait_queue_head_t wait_stop_wd; + + /* + * mei device states + */ + enum mei_states mei_state; + enum mei_init_clients_states init_clients_state; + u16 init_clients_timer; + bool stop; + bool need_reset; + + u32 extra_write_index; + unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE]; /* control messages */ + u32 wr_msg_buf[128]; /* used for control messages */ + u32 ext_msg_buf[8]; /* for control responses */ + u32 rd_msg_hdr; + + struct hbm_version version; + + struct mei_me_client *me_clients; /* Note: memory has to be allocated */ + DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX); + DECLARE_BITMAP(host_clients_map, MEI_CLIENTS_MAX); + u8 me_clients_num; + u8 me_client_presentation_num; + u8 me_client_index; + bool mei_host_buffer_is_empty; + + struct mei_cl wd_cl; + bool wd_pending; + bool wd_stopped; + bool wd_bypass; /* if false, don't refresh watchdog ME client */ + u16 wd_timeout; /* seconds ((wd_data[1] << 8) + wd_data[0]) */ + u16 wd_due_counter; + unsigned char wd_data[MEI_START_WD_DATA_SIZE]; + + + + struct file *iamthif_file_object; + struct mei_cl iamthif_cl; + struct mei_cl_cb *iamthif_current_cb; + int iamthif_mtu; + unsigned long iamthif_timer; + u32 iamthif_stall_timer; + unsigned char *iamthif_msg_buf; /* Note: memory has to be allocated */ + u32 iamthif_msg_buf_size; + u32 iamthif_msg_buf_index; + enum iamthif_states iamthif_state; + bool iamthif_flow_control_pending; + bool iamthif_ioctl; + bool iamthif_canceled; + + bool wd_interface_reg; +}; + + +/* + * mei init function prototypes + */ +struct mei_device *mei_device_init(struct pci_dev *pdev); +void mei_reset(struct mei_device *dev, int interrupts); +int mei_hw_init(struct mei_device *dev); +int mei_task_initialize_clients(void *data); +int mei_initialize_clients(struct mei_device *dev); +int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl); +void mei_remove_client_from_file_list(struct mei_device *dev, u8 host_client_id); +void mei_host_init_iamthif(struct mei_device *dev); +void mei_allocate_me_clients_storage(struct mei_device *dev); + + +u8 mei_find_me_client_update_filext(struct mei_device *dev, + struct mei_cl *priv, + const uuid_le *cguid, u8 client_id); + +/* + * MEI IO List Functions + */ +void mei_io_list_init(struct mei_io_list *list); +void mei_io_list_flush(struct mei_io_list *list, struct mei_cl *cl); + +/* + * MEI ME Client Functions + */ + +struct mei_cl *mei_cl_allocate(struct mei_device *dev); +void mei_cl_init(struct mei_cl *cl, struct mei_device *dev); +int mei_cl_flush_queues(struct mei_cl *cl); +/** + * mei_cl_cmp_id - tells if file private data have same id + * + * @fe1: private data of 1. file object + * @fe2: private data of 2. file object + * + * returns true - if ids are the same and not NULL + */ +static inline bool mei_cl_cmp_id(const struct mei_cl *cl1, + const struct mei_cl *cl2) +{ + return cl1 && cl2 && + (cl1->host_client_id == cl2->host_client_id) && + (cl1->me_client_id == cl2->me_client_id); +} + + + +/* + * MEI Host Client Functions + */ +void mei_host_start_message(struct mei_device *dev); +void mei_host_enum_clients_message(struct mei_device *dev); +int mei_host_client_properties(struct mei_device *dev); + +/* + * MEI interrupt functions prototype + */ +irqreturn_t mei_interrupt_quick_handler(int irq, void *dev_id); +irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id); +void mei_timer(struct work_struct *work); + +/* + * MEI input output function prototype + */ +int mei_ioctl_connect_client(struct file *file, + struct mei_connect_client_data *data); + +int mei_start_read(struct mei_device *dev, struct mei_cl *cl); + +int amthi_write(struct mei_device *dev, struct mei_cl_cb *priv_cb); + +int amthi_read(struct mei_device *dev, struct file *file, + char __user *ubuf, size_t length, loff_t *offset); + +struct mei_cl_cb *find_amthi_read_list_entry(struct mei_device *dev, + struct file *file); + +void mei_run_next_iamthif_cmd(struct mei_device *dev); + +void mei_free_cb_private(struct mei_cl_cb *priv_cb); + +int mei_find_me_client_index(const struct mei_device *dev, uuid_le cuuid); + +/* + * Register Access Function + */ + +/** + * mei_reg_read - Reads 32bit data from the mei device + * + * @dev: the device structure + * @offset: offset from which to read the data + * + * returns register value (u32) + */ +static inline u32 mei_reg_read(struct mei_device *dev, unsigned long offset) +{ + return ioread32(dev->mem_addr + offset); +} + +/** + * mei_reg_write - Writes 32bit data to the mei device + * + * @dev: the device structure + * @offset: offset from which to write the data + * @value: register value to write (u32) + */ +static inline void mei_reg_write(struct mei_device *dev, + unsigned long offset, u32 value) +{ + iowrite32(value, dev->mem_addr + offset); +} + +/** + * mei_hcsr_read - Reads 32bit data from the host CSR + * + * @dev: the device structure + * + * returns the byte read. + */ +static inline u32 mei_hcsr_read(struct mei_device *dev) +{ + return mei_reg_read(dev, H_CSR); +} + +/** + * mei_mecsr_read - Reads 32bit data from the ME CSR + * + * @dev: the device structure + * + * returns ME_CSR_HA register value (u32) + */ +static inline u32 mei_mecsr_read(struct mei_device *dev) +{ + return mei_reg_read(dev, ME_CSR_HA); +} + +/** + * get_me_cb_rw - Reads 32bit data from the mei ME_CB_RW register + * + * @dev: the device structure + * + * returns ME_CB_RW register value (u32) + */ +static inline u32 mei_mecbrw_read(struct mei_device *dev) +{ + return mei_reg_read(dev, ME_CB_RW); +} + + +/* + * mei interface function prototypes + */ +void mei_hcsr_set(struct mei_device *dev); +void mei_csr_clear_his(struct mei_device *dev); + +void mei_enable_interrupts(struct mei_device *dev); +void mei_disable_interrupts(struct mei_device *dev); + +#endif diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c new file mode 100644 index 0000000..1e62851 --- /dev/null +++ b/drivers/misc/mei/wd.c @@ -0,0 +1,379 @@ +/* + * + * Intel Management Engine Interface (Intel MEI) Linux driver + * Copyright (c) 2003-2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ +#include +#include +#include +#include +#include +#include +#include + +#include "mei_dev.h" +#include "hw.h" +#include "interface.h" +#include "mei.h" + +static const u8 mei_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 }; +static const u8 mei_stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 }; + +const u8 mei_wd_state_independence_msg[3][4] = { + {0x05, 0x02, 0x51, 0x10}, + {0x05, 0x02, 0x52, 0x10}, + {0x07, 0x02, 0x01, 0x10} +}; + +/* + * AMT Watchdog Device + */ +#define INTEL_AMT_WATCHDOG_ID "INTCAMT" + +/* UUIDs for AMT F/W clients */ +const uuid_le mei_wd_guid = UUID_LE(0x05B79A6F, 0x4628, 0x4D7F, 0x89, + 0x9D, 0xA9, 0x15, 0x14, 0xCB, + 0x32, 0xAB); + +static void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout) +{ + dev_dbg(&dev->pdev->dev, "wd: set timeout=%d.\n", timeout); + memcpy(dev->wd_data, mei_start_wd_params, MEI_WD_PARAMS_SIZE); + memcpy(dev->wd_data + MEI_WD_PARAMS_SIZE, &timeout, sizeof(u16)); +} + +/** + * host_init_wd - mei initialization wd. + * + * @dev: the device structure + * returns -ENENT if wd client cannot be found + * -EIO if write has failed + */ +int mei_wd_host_init(struct mei_device *dev) +{ + mei_cl_init(&dev->wd_cl, dev); + + /* look for WD client and connect to it */ + dev->wd_cl.state = MEI_FILE_DISCONNECTED; + dev->wd_timeout = AMT_WD_DEFAULT_TIMEOUT; + + /* find ME WD client */ + mei_find_me_client_update_filext(dev, &dev->wd_cl, + &mei_wd_guid, MEI_WD_HOST_CLIENT_ID); + + dev_dbg(&dev->pdev->dev, "wd: check client\n"); + if (MEI_FILE_CONNECTING != dev->wd_cl.state) { + dev_info(&dev->pdev->dev, "wd: failed to find the client\n"); + return -ENOENT; + } + + if (mei_connect(dev, &dev->wd_cl)) { + dev_err(&dev->pdev->dev, "wd: failed to connect to the client\n"); + dev->wd_cl.state = MEI_FILE_DISCONNECTED; + dev->wd_cl.host_client_id = 0; + return -EIO; + } + dev->wd_cl.timer_count = CONNECT_TIMEOUT; + + return 0; +} + +/** + * mei_wd_send - sends watch dog message to fw. + * + * @dev: the device structure + * + * returns 0 if success, + * -EIO when message send fails + * -EINVAL when invalid message is to be sent + */ +int mei_wd_send(struct mei_device *dev) +{ + struct mei_msg_hdr *mei_hdr; + + mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; + mei_hdr->host_addr = dev->wd_cl.host_client_id; + mei_hdr->me_addr = dev->wd_cl.me_client_id; + mei_hdr->msg_complete = 1; + mei_hdr->reserved = 0; + + if (!memcmp(dev->wd_data, mei_start_wd_params, MEI_WD_PARAMS_SIZE)) + mei_hdr->length = MEI_START_WD_DATA_SIZE; + else if (!memcmp(dev->wd_data, mei_stop_wd_params, MEI_WD_PARAMS_SIZE)) + mei_hdr->length = MEI_WD_PARAMS_SIZE; + else + return -EINVAL; + + return mei_write_message(dev, mei_hdr, dev->wd_data, mei_hdr->length); +} + +/** + * mei_wd_stop - sends watchdog stop message to fw. + * + * @dev: the device structure + * @preserve: indicate if to keep the timeout value + * + * returns 0 if success, + * -EIO when message send fails + * -EINVAL when invalid message is to be sent + */ +int mei_wd_stop(struct mei_device *dev, bool preserve) +{ + int ret; + u16 wd_timeout = dev->wd_timeout; + + cancel_delayed_work(&dev->timer_work); + if (dev->wd_cl.state != MEI_FILE_CONNECTED || !dev->wd_timeout) + return 0; + + dev->wd_timeout = 0; + dev->wd_due_counter = 0; + memcpy(dev->wd_data, mei_stop_wd_params, MEI_WD_PARAMS_SIZE); + dev->stop = true; + + ret = mei_flow_ctrl_creds(dev, &dev->wd_cl); + if (ret < 0) + goto out; + + if (ret && dev->mei_host_buffer_is_empty) { + ret = 0; + dev->mei_host_buffer_is_empty = false; + + if (!mei_wd_send(dev)) { + ret = mei_flow_ctrl_reduce(dev, &dev->wd_cl); + if (ret) + goto out; + } else { + dev_err(&dev->pdev->dev, "wd: send stop failed\n"); + } + + dev->wd_pending = false; + } else { + dev->wd_pending = true; + } + dev->wd_stopped = false; + mutex_unlock(&dev->device_lock); + + ret = wait_event_interruptible_timeout(dev->wait_stop_wd, + dev->wd_stopped, 10 * HZ); + mutex_lock(&dev->device_lock); + if (dev->wd_stopped) { + dev_dbg(&dev->pdev->dev, "wd: stop completed ret=%d.\n", ret); + ret = 0; + } else { + if (!ret) + ret = -ETIMEDOUT; + dev_warn(&dev->pdev->dev, + "wd: stop failed to complete ret=%d.\n", ret); + } + + if (preserve) + dev->wd_timeout = wd_timeout; + +out: + return ret; +} + +/* + * mei_wd_ops_start - wd start command from the watchdog core. + * + * @wd_dev - watchdog device struct + * + * returns 0 if success, negative errno code for failure + */ +static int mei_wd_ops_start(struct watchdog_device *wd_dev) +{ + int err = -ENODEV; + struct mei_device *dev; + + dev = pci_get_drvdata(mei_device); + if (!dev) + return -ENODEV; + + mutex_lock(&dev->device_lock); + + if (dev->mei_state != MEI_ENABLED) { + dev_dbg(&dev->pdev->dev, + "wd: mei_state != MEI_ENABLED mei_state = %d\n", + dev->mei_state); + goto end_unlock; + } + + if (dev->wd_cl.state != MEI_FILE_CONNECTED) { + dev_dbg(&dev->pdev->dev, + "MEI Driver is not connected to Watchdog Client\n"); + goto end_unlock; + } + + mei_wd_set_start_timeout(dev, dev->wd_timeout); + + err = 0; +end_unlock: + mutex_unlock(&dev->device_lock); + return err; +} + +/* + * mei_wd_ops_stop - wd stop command from the watchdog core. + * + * @wd_dev - watchdog device struct + * + * returns 0 if success, negative errno code for failure + */ +static int mei_wd_ops_stop(struct watchdog_device *wd_dev) +{ + struct mei_device *dev; + dev = pci_get_drvdata(mei_device); + + if (!dev) + return -ENODEV; + + mutex_lock(&dev->device_lock); + mei_wd_stop(dev, false); + mutex_unlock(&dev->device_lock); + + return 0; +} + +/* + * mei_wd_ops_ping - wd ping command from the watchdog core. + * + * @wd_dev - watchdog device struct + * + * returns 0 if success, negative errno code for failure + */ +static int mei_wd_ops_ping(struct watchdog_device *wd_dev) +{ + int ret = 0; + struct mei_device *dev; + dev = pci_get_drvdata(mei_device); + + if (!dev) + return -ENODEV; + + mutex_lock(&dev->device_lock); + + if (dev->wd_cl.state != MEI_FILE_CONNECTED) { + dev_err(&dev->pdev->dev, "wd: not connected.\n"); + ret = -ENODEV; + goto end; + } + + /* Check if we can send the ping to HW*/ + if (dev->mei_host_buffer_is_empty && + mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) { + + dev->mei_host_buffer_is_empty = false; + dev_dbg(&dev->pdev->dev, "wd: sending ping\n"); + + if (mei_wd_send(dev)) { + dev_err(&dev->pdev->dev, "wd: send failed.\n"); + ret = -EIO; + goto end; + } + + if (mei_flow_ctrl_reduce(dev, &dev->wd_cl)) { + dev_err(&dev->pdev->dev, + "wd: mei_flow_ctrl_reduce() failed.\n"); + ret = -EIO; + goto end; + } + + } else { + dev->wd_pending = true; + } + +end: + mutex_unlock(&dev->device_lock); + return ret; +} + +/* + * mei_wd_ops_set_timeout - wd set timeout command from the watchdog core. + * + * @wd_dev - watchdog device struct + * @timeout - timeout value to set + * + * returns 0 if success, negative errno code for failure + */ +static int mei_wd_ops_set_timeout(struct watchdog_device *wd_dev, unsigned int timeout) +{ + struct mei_device *dev; + dev = pci_get_drvdata(mei_device); + + if (!dev) + return -ENODEV; + + /* Check Timeout value */ + if (timeout < AMT_WD_MIN_TIMEOUT || timeout > AMT_WD_MAX_TIMEOUT) + return -EINVAL; + + mutex_lock(&dev->device_lock); + + dev->wd_timeout = timeout; + wd_dev->timeout = timeout; + mei_wd_set_start_timeout(dev, dev->wd_timeout); + + mutex_unlock(&dev->device_lock); + + return 0; +} + +/* + * Watchdog Device structs + */ +static const struct watchdog_ops wd_ops = { + .owner = THIS_MODULE, + .start = mei_wd_ops_start, + .stop = mei_wd_ops_stop, + .ping = mei_wd_ops_ping, + .set_timeout = mei_wd_ops_set_timeout, +}; +static const struct watchdog_info wd_info = { + .identity = INTEL_AMT_WATCHDOG_ID, + .options = WDIOF_KEEPALIVEPING, +}; + +static struct watchdog_device amt_wd_dev = { + .info = &wd_info, + .ops = &wd_ops, + .timeout = AMT_WD_DEFAULT_TIMEOUT, + .min_timeout = AMT_WD_MIN_TIMEOUT, + .max_timeout = AMT_WD_MAX_TIMEOUT, +}; + + +void mei_watchdog_register(struct mei_device *dev) +{ + dev_dbg(&dev->pdev->dev, "dev->wd_timeout =%d.\n", dev->wd_timeout); + + dev->wd_due_counter = !!dev->wd_timeout; + + if (watchdog_register_device(&amt_wd_dev)) { + dev_err(&dev->pdev->dev, + "wd: unable to register watchdog device.\n"); + dev->wd_interface_reg = false; + } else { + dev_dbg(&dev->pdev->dev, + "wd: successfully register watchdog interface.\n"); + dev->wd_interface_reg = true; + } +} + +void mei_watchdog_unregister(struct mei_device *dev) +{ + if (dev->wd_interface_reg) + watchdog_unregister_device(&amt_wd_dev); + dev->wd_interface_reg = false; +} + diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 60221ef..32b02e4 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -112,8 +112,6 @@ source "drivers/staging/cptm1217/Kconfig" source "drivers/staging/ste_rmi4/Kconfig" -source "drivers/staging/mei/Kconfig" - source "drivers/staging/nvec/Kconfig" source "drivers/staging/media/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 0381958..e603c07 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -50,7 +50,6 @@ obj-$(CONFIG_FT1000) += ft1000/ obj-$(CONFIG_SPEAKUP) += speakup/ obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/ obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/ -obj-$(CONFIG_INTEL_MEI) += mei/ obj-$(CONFIG_MFD_NVEC) += nvec/ obj-$(CONFIG_DRM_OMAP) += omapdrm/ obj-$(CONFIG_ANDROID) += android/ diff --git a/drivers/staging/mei/Kconfig b/drivers/staging/mei/Kconfig deleted file mode 100644 index 47d78a7..0000000 --- a/drivers/staging/mei/Kconfig +++ /dev/null @@ -1,28 +0,0 @@ -config INTEL_MEI - tristate "Intel Management Engine Interface (Intel MEI)" - depends on X86 && PCI && EXPERIMENTAL && WATCHDOG_CORE - help - The Intel Management Engine (Intel ME) provides Manageability, - Security and Media services for system containing Intel chipsets. - if selected /dev/mei misc device will be created. - - Supported Chipsets are: - 7 Series Chipset Family - 6 Series Chipset Family - 5 Series Chipset Family - 4 Series Chipset Family - Mobile 4 Series Chipset Family - ICH9 - 82946GZ/GL - 82G35 Express - 82Q963/Q965 - 82P965/G965 - Mobile PM965/GM965 - Mobile GME965/GLE960 - 82Q35 Express - 82G33/G31/P35/P31 Express - 82Q33 Express - 82X38/X48 Express - - For more information see - diff --git a/drivers/staging/mei/Makefile b/drivers/staging/mei/Makefile deleted file mode 100644 index 57168db..0000000 --- a/drivers/staging/mei/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile - Intel Management Engine Interface (Intel MEI) Linux driver -# Copyright (c) 2010-2011, Intel Corporation. -# -obj-$(CONFIG_INTEL_MEI) += mei.o -mei-objs := init.o -mei-objs += interrupt.o -mei-objs += interface.o -mei-objs += iorw.o -mei-objs += main.o -mei-objs += wd.o diff --git a/drivers/staging/mei/TODO b/drivers/staging/mei/TODO deleted file mode 100644 index fc26601..0000000 --- a/drivers/staging/mei/TODO +++ /dev/null @@ -1,10 +0,0 @@ -TODO: - - Cleanup and split the timer function -Upon Unstaging: - - move mei.h to include/linux/mei.h - - Documentation/ioctl/ioctl-number.txt - - move mei.txt under Documentation/mei/ - - move mei-amt-version.c under Documentation/mei - - add hostprogs-y for mei-amt-version.c - - drop mei_version.h - - Updated MAINTAINERS diff --git a/drivers/staging/mei/hw.h b/drivers/staging/mei/hw.h deleted file mode 100644 index 24c4c96..0000000 --- a/drivers/staging/mei/hw.h +++ /dev/null @@ -1,332 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2012, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - -#ifndef _MEI_HW_TYPES_H_ -#define _MEI_HW_TYPES_H_ - -#include - -/* - * Timeouts - */ -#define MEI_INTEROP_TIMEOUT (HZ * 7) -#define MEI_CONNECT_TIMEOUT 3 /* at least 2 seconds */ - -#define CONNECT_TIMEOUT 15 /* HPS definition */ -#define INIT_CLIENTS_TIMEOUT 15 /* HPS definition */ - -#define IAMTHIF_STALL_TIMER 12 /* seconds */ -#define IAMTHIF_READ_TIMER 10000 /* ms */ - -/* - * Internal Clients Number - */ -#define MEI_WD_HOST_CLIENT_ID 1 -#define MEI_IAMTHIF_HOST_CLIENT_ID 2 - -/* - * MEI device IDs - */ -#define MEI_DEV_ID_82946GZ 0x2974 /* 82946GZ/GL */ -#define MEI_DEV_ID_82G35 0x2984 /* 82G35 Express */ -#define MEI_DEV_ID_82Q965 0x2994 /* 82Q963/Q965 */ -#define MEI_DEV_ID_82G965 0x29A4 /* 82P965/G965 */ - -#define MEI_DEV_ID_82GM965 0x2A04 /* Mobile PM965/GM965 */ -#define MEI_DEV_ID_82GME965 0x2A14 /* Mobile GME965/GLE960 */ - -#define MEI_DEV_ID_ICH9_82Q35 0x29B4 /* 82Q35 Express */ -#define MEI_DEV_ID_ICH9_82G33 0x29C4 /* 82G33/G31/P35/P31 Express */ -#define MEI_DEV_ID_ICH9_82Q33 0x29D4 /* 82Q33 Express */ -#define MEI_DEV_ID_ICH9_82X38 0x29E4 /* 82X38/X48 Express */ -#define MEI_DEV_ID_ICH9_3200 0x29F4 /* 3200/3210 Server */ - -#define MEI_DEV_ID_ICH9_6 0x28B4 /* Bearlake */ -#define MEI_DEV_ID_ICH9_7 0x28C4 /* Bearlake */ -#define MEI_DEV_ID_ICH9_8 0x28D4 /* Bearlake */ -#define MEI_DEV_ID_ICH9_9 0x28E4 /* Bearlake */ -#define MEI_DEV_ID_ICH9_10 0x28F4 /* Bearlake */ - -#define MEI_DEV_ID_ICH9M_1 0x2A44 /* Cantiga */ -#define MEI_DEV_ID_ICH9M_2 0x2A54 /* Cantiga */ -#define MEI_DEV_ID_ICH9M_3 0x2A64 /* Cantiga */ -#define MEI_DEV_ID_ICH9M_4 0x2A74 /* Cantiga */ - -#define MEI_DEV_ID_ICH10_1 0x2E04 /* Eaglelake */ -#define MEI_DEV_ID_ICH10_2 0x2E14 /* Eaglelake */ -#define MEI_DEV_ID_ICH10_3 0x2E24 /* Eaglelake */ -#define MEI_DEV_ID_ICH10_4 0x2E34 /* Eaglelake */ - -#define MEI_DEV_ID_IBXPK_1 0x3B64 /* Calpella */ -#define MEI_DEV_ID_IBXPK_2 0x3B65 /* Calpella */ - -#define MEI_DEV_ID_CPT_1 0x1C3A /* Cougerpoint */ -#define MEI_DEV_ID_PBG_1 0x1D3A /* PBG */ - -#define MEI_DEV_ID_PPT_1 0x1E3A /* Pantherpoint PPT */ -#define MEI_DEV_ID_PPT_2 0x1CBA /* Pantherpoint PPT */ -#define MEI_DEV_ID_PPT_3 0x1DBA /* Pantherpoint PPT */ - - -/* - * MEI HW Section - */ - -/* MEI registers */ -/* H_CB_WW - Host Circular Buffer (CB) Write Window register */ -#define H_CB_WW 0 -/* H_CSR - Host Control Status register */ -#define H_CSR 4 -/* ME_CB_RW - ME Circular Buffer Read Window register (read only) */ -#define ME_CB_RW 8 -/* ME_CSR_HA - ME Control Status Host Access register (read only) */ -#define ME_CSR_HA 0xC - - -/* register bits of H_CSR (Host Control Status register) */ -/* Host Circular Buffer Depth - maximum number of 32-bit entries in CB */ -#define H_CBD 0xFF000000 -/* Host Circular Buffer Write Pointer */ -#define H_CBWP 0x00FF0000 -/* Host Circular Buffer Read Pointer */ -#define H_CBRP 0x0000FF00 -/* Host Reset */ -#define H_RST 0x00000010 -/* Host Ready */ -#define H_RDY 0x00000008 -/* Host Interrupt Generate */ -#define H_IG 0x00000004 -/* Host Interrupt Status */ -#define H_IS 0x00000002 -/* Host Interrupt Enable */ -#define H_IE 0x00000001 - - -/* register bits of ME_CSR_HA (ME Control Status Host Access register) */ -/* ME CB (Circular Buffer) Depth HRA (Host Read Access) - host read only -access to ME_CBD */ -#define ME_CBD_HRA 0xFF000000 -/* ME CB Write Pointer HRA - host read only access to ME_CBWP */ -#define ME_CBWP_HRA 0x00FF0000 -/* ME CB Read Pointer HRA - host read only access to ME_CBRP */ -#define ME_CBRP_HRA 0x0000FF00 -/* ME Reset HRA - host read only access to ME_RST */ -#define ME_RST_HRA 0x00000010 -/* ME Ready HRA - host read only access to ME_RDY */ -#define ME_RDY_HRA 0x00000008 -/* ME Interrupt Generate HRA - host read only access to ME_IG */ -#define ME_IG_HRA 0x00000004 -/* ME Interrupt Status HRA - host read only access to ME_IS */ -#define ME_IS_HRA 0x00000002 -/* ME Interrupt Enable HRA - host read only access to ME_IE */ -#define ME_IE_HRA 0x00000001 - -/* - * MEI Version - */ -#define HBM_MINOR_VERSION 0 -#define HBM_MAJOR_VERSION 1 -#define HBM_TIMEOUT 1 /* 1 second */ - -/* Host bus message command opcode */ -#define MEI_HBM_CMD_OP_MSK 0x7f -/* Host bus message command RESPONSE */ -#define MEI_HBM_CMD_RES_MSK 0x80 - -/* - * MEI Bus Message Command IDs - */ -#define HOST_START_REQ_CMD 0x01 -#define HOST_START_RES_CMD 0x81 - -#define HOST_STOP_REQ_CMD 0x02 -#define HOST_STOP_RES_CMD 0x82 - -#define ME_STOP_REQ_CMD 0x03 - -#define HOST_ENUM_REQ_CMD 0x04 -#define HOST_ENUM_RES_CMD 0x84 - -#define HOST_CLIENT_PROPERTIES_REQ_CMD 0x05 -#define HOST_CLIENT_PROPERTIES_RES_CMD 0x85 - -#define CLIENT_CONNECT_REQ_CMD 0x06 -#define CLIENT_CONNECT_RES_CMD 0x86 - -#define CLIENT_DISCONNECT_REQ_CMD 0x07 -#define CLIENT_DISCONNECT_RES_CMD 0x87 - -#define MEI_FLOW_CONTROL_CMD 0x08 - -/* - * MEI Stop Reason - * used by hbm_host_stop_request.reason - */ -enum mei_stop_reason_types { - DRIVER_STOP_REQUEST = 0x00, - DEVICE_D1_ENTRY = 0x01, - DEVICE_D2_ENTRY = 0x02, - DEVICE_D3_ENTRY = 0x03, - SYSTEM_S1_ENTRY = 0x04, - SYSTEM_S2_ENTRY = 0x05, - SYSTEM_S3_ENTRY = 0x06, - SYSTEM_S4_ENTRY = 0x07, - SYSTEM_S5_ENTRY = 0x08 -}; - -/* - * Client Connect Status - * used by hbm_client_connect_response.status - */ -enum client_connect_status_types { - CCS_SUCCESS = 0x00, - CCS_NOT_FOUND = 0x01, - CCS_ALREADY_STARTED = 0x02, - CCS_OUT_OF_RESOURCES = 0x03, - CCS_MESSAGE_SMALL = 0x04 -}; - -/* - * Client Disconnect Status - */ -enum client_disconnect_status_types { - CDS_SUCCESS = 0x00 -}; - -/* - * MEI BUS Interface Section - */ -struct mei_msg_hdr { - u32 me_addr:8; - u32 host_addr:8; - u32 length:9; - u32 reserved:6; - u32 msg_complete:1; -} __packed; - - -struct mei_bus_message { - u8 hbm_cmd; - u8 data[0]; -} __packed; - -struct hbm_version { - u8 minor_version; - u8 major_version; -} __packed; - -struct hbm_host_version_request { - u8 hbm_cmd; - u8 reserved; - struct hbm_version host_version; -} __packed; - -struct hbm_host_version_response { - u8 hbm_cmd; - u8 host_version_supported; - struct hbm_version me_max_version; -} __packed; - -struct hbm_host_stop_request { - u8 hbm_cmd; - u8 reason; - u8 reserved[2]; -} __packed; - -struct hbm_host_stop_response { - u8 hbm_cmd; - u8 reserved[3]; -} __packed; - -struct hbm_me_stop_request { - u8 hbm_cmd; - u8 reason; - u8 reserved[2]; -} __packed; - -struct hbm_host_enum_request { - u8 hbm_cmd; - u8 reserved[3]; -} __packed; - -struct hbm_host_enum_response { - u8 hbm_cmd; - u8 reserved[3]; - u8 valid_addresses[32]; -} __packed; - -struct mei_client_properties { - uuid_le protocol_name; - u8 protocol_version; - u8 max_number_of_connections; - u8 fixed_address; - u8 single_recv_buf; - u32 max_msg_length; -} __packed; - -struct hbm_props_request { - u8 hbm_cmd; - u8 address; - u8 reserved[2]; -} __packed; - - -struct hbm_props_response { - u8 hbm_cmd; - u8 address; - u8 status; - u8 reserved[1]; - struct mei_client_properties client_properties; -} __packed; - -struct hbm_client_connect_request { - u8 hbm_cmd; - u8 me_addr; - u8 host_addr; - u8 reserved; -} __packed; - -struct hbm_client_connect_response { - u8 hbm_cmd; - u8 me_addr; - u8 host_addr; - u8 status; -} __packed; - -struct hbm_client_disconnect_request { - u8 hbm_cmd; - u8 me_addr; - u8 host_addr; - u8 reserved[1]; -} __packed; - -#define MEI_FC_MESSAGE_RESERVED_LENGTH 5 - -struct hbm_flow_control { - u8 hbm_cmd; - u8 me_addr; - u8 host_addr; - u8 reserved[MEI_FC_MESSAGE_RESERVED_LENGTH]; -} __packed; - -struct mei_me_client { - struct mei_client_properties props; - u8 client_id; - u8 mei_flow_ctrl_creds; -} __packed; - - -#endif diff --git a/drivers/staging/mei/init.c b/drivers/staging/mei/init.c deleted file mode 100644 index afb0a58..0000000 --- a/drivers/staging/mei/init.c +++ /dev/null @@ -1,735 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2012, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - -#include -#include -#include -#include - -#include "mei_dev.h" -#include "hw.h" -#include "interface.h" -#include "mei.h" - -const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac, - 0xa8, 0x46, 0xe0, 0xff, 0x65, - 0x81, 0x4c); - -/** - * mei_io_list_init - Sets up a queue list. - * - * @list: An instance io list structure - * @dev: the device structure - */ -void mei_io_list_init(struct mei_io_list *list) -{ - /* initialize our queue list */ - INIT_LIST_HEAD(&list->mei_cb.cb_list); -} - -/** - * mei_io_list_flush - removes list entry belonging to cl. - * - * @list: An instance of our list structure - * @cl: private data of the file object - */ -void mei_io_list_flush(struct mei_io_list *list, struct mei_cl *cl) -{ - struct mei_cl_cb *pos; - struct mei_cl_cb *next; - - list_for_each_entry_safe(pos, next, &list->mei_cb.cb_list, cb_list) { - if (pos->file_private) { - struct mei_cl *cl_tmp; - cl_tmp = (struct mei_cl *)pos->file_private; - if (mei_cl_cmp_id(cl, cl_tmp)) - list_del(&pos->cb_list); - } - } -} -/** - * mei_cl_flush_queues - flushes queue lists belonging to cl. - * - * @dev: the device structure - * @cl: private data of the file object - */ -int mei_cl_flush_queues(struct mei_cl *cl) -{ - if (!cl || !cl->dev) - return -EINVAL; - - dev_dbg(&cl->dev->pdev->dev, "remove list entry belonging to cl\n"); - mei_io_list_flush(&cl->dev->read_list, cl); - mei_io_list_flush(&cl->dev->write_list, cl); - mei_io_list_flush(&cl->dev->write_waiting_list, cl); - mei_io_list_flush(&cl->dev->ctrl_wr_list, cl); - mei_io_list_flush(&cl->dev->ctrl_rd_list, cl); - mei_io_list_flush(&cl->dev->amthi_cmd_list, cl); - mei_io_list_flush(&cl->dev->amthi_read_complete_list, cl); - return 0; -} - - - -/** - * mei_reset_iamthif_params - initializes mei device iamthif - * - * @dev: the device structure - */ -static void mei_reset_iamthif_params(struct mei_device *dev) -{ - /* reset iamthif parameters. */ - dev->iamthif_current_cb = NULL; - dev->iamthif_msg_buf_size = 0; - dev->iamthif_msg_buf_index = 0; - dev->iamthif_canceled = false; - dev->iamthif_ioctl = false; - dev->iamthif_state = MEI_IAMTHIF_IDLE; - dev->iamthif_timer = 0; -} - -/** - * init_mei_device - allocates and initializes the mei device structure - * - * @pdev: The pci device structure - * - * returns The mei_device_device pointer on success, NULL on failure. - */ -struct mei_device *mei_device_init(struct pci_dev *pdev) -{ - struct mei_device *dev; - - dev = kzalloc(sizeof(struct mei_device), GFP_KERNEL); - if (!dev) - return NULL; - - /* setup our list array */ - INIT_LIST_HEAD(&dev->file_list); - INIT_LIST_HEAD(&dev->wd_cl.link); - INIT_LIST_HEAD(&dev->iamthif_cl.link); - mutex_init(&dev->device_lock); - init_waitqueue_head(&dev->wait_recvd_msg); - init_waitqueue_head(&dev->wait_stop_wd); - dev->mei_state = MEI_INITIALIZING; - dev->iamthif_state = MEI_IAMTHIF_IDLE; - dev->wd_interface_reg = false; - - - mei_io_list_init(&dev->read_list); - mei_io_list_init(&dev->write_list); - mei_io_list_init(&dev->write_waiting_list); - mei_io_list_init(&dev->ctrl_wr_list); - mei_io_list_init(&dev->ctrl_rd_list); - mei_io_list_init(&dev->amthi_cmd_list); - mei_io_list_init(&dev->amthi_read_complete_list); - dev->pdev = pdev; - return dev; -} - -/** - * mei_hw_init - initializes host and fw to start work. - * - * @dev: the device structure - * - * returns 0 on success, <0 on failure. - */ -int mei_hw_init(struct mei_device *dev) -{ - int err = 0; - int ret; - - mutex_lock(&dev->device_lock); - - dev->host_hw_state = mei_hcsr_read(dev); - dev->me_hw_state = mei_mecsr_read(dev); - dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, mestate = 0x%08x.\n", - dev->host_hw_state, dev->me_hw_state); - - /* acknowledge interrupt and stop interupts */ - if ((dev->host_hw_state & H_IS) == H_IS) - mei_reg_write(dev, H_CSR, dev->host_hw_state); - - dev->recvd_msg = false; - dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n"); - - mei_reset(dev, 1); - - dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", - dev->host_hw_state, dev->me_hw_state); - - /* wait for ME to turn on ME_RDY */ - if (!dev->recvd_msg) { - mutex_unlock(&dev->device_lock); - err = wait_event_interruptible_timeout(dev->wait_recvd_msg, - dev->recvd_msg, MEI_INTEROP_TIMEOUT); - mutex_lock(&dev->device_lock); - } - - if (err <= 0 && !dev->recvd_msg) { - dev->mei_state = MEI_DISABLED; - dev_dbg(&dev->pdev->dev, - "wait_event_interruptible_timeout failed" - "on wait for ME to turn on ME_RDY.\n"); - ret = -ENODEV; - goto out; - } - - if (!(((dev->host_hw_state & H_RDY) == H_RDY) && - ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA))) { - dev->mei_state = MEI_DISABLED; - dev_dbg(&dev->pdev->dev, - "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", - dev->host_hw_state, dev->me_hw_state); - - if (!(dev->host_hw_state & H_RDY)) - dev_dbg(&dev->pdev->dev, "host turn off H_RDY.\n"); - - if (!(dev->me_hw_state & ME_RDY_HRA)) - dev_dbg(&dev->pdev->dev, "ME turn off ME_RDY.\n"); - - dev_err(&dev->pdev->dev, "link layer initialization failed.\n"); - ret = -ENODEV; - goto out; - } - - if (dev->version.major_version != HBM_MAJOR_VERSION || - dev->version.minor_version != HBM_MINOR_VERSION) { - dev_dbg(&dev->pdev->dev, "MEI start failed.\n"); - ret = -ENODEV; - goto out; - } - - dev->recvd_msg = false; - dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", - dev->host_hw_state, dev->me_hw_state); - dev_dbg(&dev->pdev->dev, "ME turn on ME_RDY and host turn on H_RDY.\n"); - dev_dbg(&dev->pdev->dev, "link layer has been established.\n"); - dev_dbg(&dev->pdev->dev, "MEI start success.\n"); - ret = 0; - -out: - mutex_unlock(&dev->device_lock); - return ret; -} - -/** - * mei_hw_reset - resets fw via mei csr register. - * - * @dev: the device structure - * @interrupts_enabled: if interrupt should be enabled after reset. - */ -static void mei_hw_reset(struct mei_device *dev, int interrupts_enabled) -{ - dev->host_hw_state |= (H_RST | H_IG); - - if (interrupts_enabled) - mei_enable_interrupts(dev); - else - mei_disable_interrupts(dev); -} - -/** - * mei_reset - resets host and fw. - * - * @dev: the device structure - * @interrupts_enabled: if interrupt should be enabled after reset. - */ -void mei_reset(struct mei_device *dev, int interrupts_enabled) -{ - struct mei_cl *cl_pos = NULL; - struct mei_cl *cl_next = NULL; - struct mei_cl_cb *cb_pos = NULL; - struct mei_cl_cb *cb_next = NULL; - bool unexpected; - - if (dev->mei_state == MEI_RECOVERING_FROM_RESET) { - dev->need_reset = true; - return; - } - - unexpected = (dev->mei_state != MEI_INITIALIZING && - dev->mei_state != MEI_DISABLED && - dev->mei_state != MEI_POWER_DOWN && - dev->mei_state != MEI_POWER_UP); - - dev->host_hw_state = mei_hcsr_read(dev); - - dev_dbg(&dev->pdev->dev, "before reset host_hw_state = 0x%08x.\n", - dev->host_hw_state); - - mei_hw_reset(dev, interrupts_enabled); - - dev->host_hw_state &= ~H_RST; - dev->host_hw_state |= H_IG; - - mei_hcsr_set(dev); - - dev_dbg(&dev->pdev->dev, "currently saved host_hw_state = 0x%08x.\n", - dev->host_hw_state); - - dev->need_reset = false; - - if (dev->mei_state != MEI_INITIALIZING) { - if (dev->mei_state != MEI_DISABLED && - dev->mei_state != MEI_POWER_DOWN) - dev->mei_state = MEI_RESETING; - - list_for_each_entry_safe(cl_pos, - cl_next, &dev->file_list, link) { - cl_pos->state = MEI_FILE_DISCONNECTED; - cl_pos->mei_flow_ctrl_creds = 0; - cl_pos->read_cb = NULL; - cl_pos->timer_count = 0; - } - /* remove entry if already in list */ - dev_dbg(&dev->pdev->dev, "list del iamthif and wd file list.\n"); - mei_remove_client_from_file_list(dev, - dev->wd_cl.host_client_id); - - mei_remove_client_from_file_list(dev, - dev->iamthif_cl.host_client_id); - - mei_reset_iamthif_params(dev); - dev->wd_due_counter = 0; - dev->extra_write_index = 0; - } - - dev->me_clients_num = 0; - dev->rd_msg_hdr = 0; - dev->stop = false; - dev->wd_pending = false; - - /* update the state of the registers after reset */ - dev->host_hw_state = mei_hcsr_read(dev); - dev->me_hw_state = mei_mecsr_read(dev); - - dev_dbg(&dev->pdev->dev, "after reset host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", - dev->host_hw_state, dev->me_hw_state); - - if (unexpected) - dev_warn(&dev->pdev->dev, "unexpected reset.\n"); - - /* Wake up all readings so they can be interrupted */ - list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { - if (waitqueue_active(&cl_pos->rx_wait)) { - dev_dbg(&dev->pdev->dev, "Waking up client!\n"); - wake_up_interruptible(&cl_pos->rx_wait); - } - } - /* remove all waiting requests */ - list_for_each_entry_safe(cb_pos, cb_next, - &dev->write_list.mei_cb.cb_list, cb_list) { - list_del(&cb_pos->cb_list); - mei_free_cb_private(cb_pos); - } -} - - - -/** - * host_start_message - mei host sends start message. - * - * @dev: the device structure - * - * returns none. - */ -void mei_host_start_message(struct mei_device *dev) -{ - struct mei_msg_hdr *mei_hdr; - struct hbm_host_version_request *host_start_req; - - /* host start message */ - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_host_version_request); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - host_start_req = - (struct hbm_host_version_request *) &dev->wr_msg_buf[1]; - memset(host_start_req, 0, sizeof(struct hbm_host_version_request)); - host_start_req->hbm_cmd = HOST_START_REQ_CMD; - host_start_req->host_version.major_version = HBM_MAJOR_VERSION; - host_start_req->host_version.minor_version = HBM_MINOR_VERSION; - dev->recvd_msg = false; - if (mei_write_message(dev, mei_hdr, (unsigned char *)host_start_req, - mei_hdr->length)) { - dev_dbg(&dev->pdev->dev, "write send version message to FW fail.\n"); - dev->mei_state = MEI_RESETING; - mei_reset(dev, 1); - } - dev->init_clients_state = MEI_START_MESSAGE; - dev->init_clients_timer = INIT_CLIENTS_TIMEOUT; - return ; -} - -/** - * host_enum_clients_message - host sends enumeration client request message. - * - * @dev: the device structure - * - * returns none. - */ -void mei_host_enum_clients_message(struct mei_device *dev) -{ - struct mei_msg_hdr *mei_hdr; - struct hbm_host_enum_request *host_enum_req; - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - /* enumerate clients */ - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_host_enum_request); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - host_enum_req = (struct hbm_host_enum_request *) &dev->wr_msg_buf[1]; - memset(host_enum_req, 0, sizeof(struct hbm_host_enum_request)); - host_enum_req->hbm_cmd = HOST_ENUM_REQ_CMD; - if (mei_write_message(dev, mei_hdr, (unsigned char *)host_enum_req, - mei_hdr->length)) { - dev->mei_state = MEI_RESETING; - dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n"); - mei_reset(dev, 1); - } - dev->init_clients_state = MEI_ENUM_CLIENTS_MESSAGE; - dev->init_clients_timer = INIT_CLIENTS_TIMEOUT; - return; -} - - -/** - * allocate_me_clients_storage - allocates storage for me clients - * - * @dev: the device structure - * - * returns none. - */ -void mei_allocate_me_clients_storage(struct mei_device *dev) -{ - struct mei_me_client *clients; - int b; - - /* count how many ME clients we have */ - for_each_set_bit(b, dev->me_clients_map, MEI_CLIENTS_MAX) - dev->me_clients_num++; - - if (dev->me_clients_num <= 0) - return ; - - - if (dev->me_clients != NULL) { - kfree(dev->me_clients); - dev->me_clients = NULL; - } - dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%zd.\n", - dev->me_clients_num * sizeof(struct mei_me_client)); - /* allocate storage for ME clients representation */ - clients = kcalloc(dev->me_clients_num, - sizeof(struct mei_me_client), GFP_KERNEL); - if (!clients) { - dev_dbg(&dev->pdev->dev, "memory allocation for ME clients failed.\n"); - dev->mei_state = MEI_RESETING; - mei_reset(dev, 1); - return ; - } - dev->me_clients = clients; - return ; -} -/** - * host_client_properties - reads properties for client - * - * @dev: the device structure - * - * returns: - * < 0 - Error. - * = 0 - no more clients. - * = 1 - still have clients to send properties request. - */ -int mei_host_client_properties(struct mei_device *dev) -{ - struct mei_msg_hdr *mei_header; - struct hbm_props_request *host_cli_req; - int b; - u8 client_num = dev->me_client_presentation_num; - - b = dev->me_client_index; - b = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, b); - if (b < MEI_CLIENTS_MAX) { - dev->me_clients[client_num].client_id = b; - dev->me_clients[client_num].mei_flow_ctrl_creds = 0; - mei_header = (struct mei_msg_hdr *)&dev->wr_msg_buf[0]; - mei_header->host_addr = 0; - mei_header->me_addr = 0; - mei_header->length = sizeof(struct hbm_props_request); - mei_header->msg_complete = 1; - mei_header->reserved = 0; - - host_cli_req = (struct hbm_props_request *)&dev->wr_msg_buf[1]; - - memset(host_cli_req, 0, sizeof(struct hbm_props_request)); - - host_cli_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; - host_cli_req->address = b; - - if (mei_write_message(dev, mei_header, - (unsigned char *)host_cli_req, - mei_header->length)) { - dev->mei_state = MEI_RESETING; - dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n"); - mei_reset(dev, 1); - return -EIO; - } - - dev->init_clients_timer = INIT_CLIENTS_TIMEOUT; - dev->me_client_index = b; - return 1; - } - - return 0; -} - -/** - * mei_init_file_private - initializes private file structure. - * - * @priv: private file structure to be initialized - * @file: the file structure - */ -void mei_cl_init(struct mei_cl *priv, struct mei_device *dev) -{ - memset(priv, 0, sizeof(struct mei_cl)); - init_waitqueue_head(&priv->wait); - init_waitqueue_head(&priv->rx_wait); - init_waitqueue_head(&priv->tx_wait); - INIT_LIST_HEAD(&priv->link); - priv->reading_state = MEI_IDLE; - priv->writing_state = MEI_IDLE; - priv->dev = dev; -} - -int mei_find_me_client_index(const struct mei_device *dev, uuid_le cuuid) -{ - int i, res = -1; - - for (i = 0; i < dev->me_clients_num; ++i) - if (uuid_le_cmp(cuuid, - dev->me_clients[i].props.protocol_name) == 0) { - res = i; - break; - } - - return res; -} - - -/** - * mei_find_me_client_update_filext - searches for ME client guid - * sets client_id in mei_file_private if found - * @dev: the device structure - * @priv: private file structure to set client_id in - * @cguid: searched guid of ME client - * @client_id: id of host client to be set in file private structure - * - * returns ME client index - */ -u8 mei_find_me_client_update_filext(struct mei_device *dev, struct mei_cl *priv, - const uuid_le *cguid, u8 client_id) -{ - int i; - - if (!dev || !priv || !cguid) - return 0; - - /* check for valid client id */ - i = mei_find_me_client_index(dev, *cguid); - if (i >= 0) { - priv->me_client_id = dev->me_clients[i].client_id; - priv->state = MEI_FILE_CONNECTING; - priv->host_client_id = client_id; - - list_add_tail(&priv->link, &dev->file_list); - return (u8)i; - } - - return 0; -} - -/** - * host_init_iamthif - mei initialization iamthif client. - * - * @dev: the device structure - * - */ -void mei_host_init_iamthif(struct mei_device *dev) -{ - u8 i; - unsigned char *msg_buf; - - mei_cl_init(&dev->iamthif_cl, dev); - dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; - - /* find ME amthi client */ - i = mei_find_me_client_update_filext(dev, &dev->iamthif_cl, - &mei_amthi_guid, MEI_IAMTHIF_HOST_CLIENT_ID); - if (dev->iamthif_cl.state != MEI_FILE_CONNECTING) { - dev_dbg(&dev->pdev->dev, "failed to find iamthif client.\n"); - return; - } - - /* Assign iamthif_mtu to the value received from ME */ - - dev->iamthif_mtu = dev->me_clients[i].props.max_msg_length; - dev_dbg(&dev->pdev->dev, "IAMTHIF_MTU = %d\n", - dev->me_clients[i].props.max_msg_length); - - kfree(dev->iamthif_msg_buf); - dev->iamthif_msg_buf = NULL; - - /* allocate storage for ME message buffer */ - msg_buf = kcalloc(dev->iamthif_mtu, - sizeof(unsigned char), GFP_KERNEL); - if (!msg_buf) { - dev_dbg(&dev->pdev->dev, "memory allocation for ME message buffer failed.\n"); - return; - } - - dev->iamthif_msg_buf = msg_buf; - - if (mei_connect(dev, &dev->iamthif_cl)) { - dev_dbg(&dev->pdev->dev, "Failed to connect to AMTHI client\n"); - dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; - dev->iamthif_cl.host_client_id = 0; - } else { - dev->iamthif_cl.timer_count = CONNECT_TIMEOUT; - } -} - -/** - * mei_alloc_file_private - allocates a private file structure and sets it up. - * @file: the file structure - * - * returns The allocated file or NULL on failure - */ -struct mei_cl *mei_cl_allocate(struct mei_device *dev) -{ - struct mei_cl *cl; - - cl = kmalloc(sizeof(struct mei_cl), GFP_KERNEL); - if (!cl) - return NULL; - - mei_cl_init(cl, dev); - - return cl; -} - - - -/** - * mei_disconnect_host_client - sends disconnect message to fw from host client. - * - * @dev: the device structure - * @cl: private data of the file object - * - * Locking: called under "dev->device_lock" lock - * - * returns 0 on success, <0 on failure. - */ -int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl) -{ - int rets, err; - long timeout = 15; /* 15 seconds */ - struct mei_cl_cb *cb; - - if (!dev || !cl) - return -ENODEV; - - if (cl->state != MEI_FILE_DISCONNECTING) - return 0; - - cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); - if (!cb) - return -ENOMEM; - - INIT_LIST_HEAD(&cb->cb_list); - cb->file_private = cl; - cb->major_file_operations = MEI_CLOSE; - if (dev->mei_host_buffer_is_empty) { - dev->mei_host_buffer_is_empty = false; - if (mei_disconnect(dev, cl)) { - rets = -ENODEV; - dev_dbg(&dev->pdev->dev, "failed to call mei_disconnect.\n"); - goto free; - } - mdelay(10); /* Wait for hardware disconnection ready */ - list_add_tail(&cb->cb_list, &dev->ctrl_rd_list.mei_cb.cb_list); - } else { - dev_dbg(&dev->pdev->dev, "add disconnect cb to control write list\n"); - list_add_tail(&cb->cb_list, - &dev->ctrl_wr_list.mei_cb.cb_list); - } - mutex_unlock(&dev->device_lock); - - err = wait_event_timeout(dev->wait_recvd_msg, - (MEI_FILE_DISCONNECTED == cl->state), - timeout * HZ); - - mutex_lock(&dev->device_lock); - if (MEI_FILE_DISCONNECTED == cl->state) { - rets = 0; - dev_dbg(&dev->pdev->dev, "successfully disconnected from FW client.\n"); - } else { - rets = -ENODEV; - if (MEI_FILE_DISCONNECTED != cl->state) - dev_dbg(&dev->pdev->dev, "wrong status client disconnect.\n"); - - if (err) - dev_dbg(&dev->pdev->dev, - "wait failed disconnect err=%08x\n", - err); - - dev_dbg(&dev->pdev->dev, "failed to disconnect from FW client.\n"); - } - - mei_io_list_flush(&dev->ctrl_rd_list, cl); - mei_io_list_flush(&dev->ctrl_wr_list, cl); -free: - mei_free_cb_private(cb); - return rets; -} - -/** - * mei_remove_client_from_file_list - - * removes file private data from device file list - * - * @dev: the device structure - * @host_client_id: host client id to be removed - */ -void mei_remove_client_from_file_list(struct mei_device *dev, - u8 host_client_id) -{ - struct mei_cl *cl_pos = NULL; - struct mei_cl *cl_next = NULL; - list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { - if (host_client_id == cl_pos->host_client_id) { - dev_dbg(&dev->pdev->dev, "remove host client = %d, ME client = %d\n", - cl_pos->host_client_id, - cl_pos->me_client_id); - list_del_init(&cl_pos->link); - break; - } - } -} diff --git a/drivers/staging/mei/interface.c b/drivers/staging/mei/interface.c deleted file mode 100644 index 9a2cfaf..0000000 --- a/drivers/staging/mei/interface.c +++ /dev/null @@ -1,428 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2012, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - -#include -#include "mei_dev.h" -#include "mei.h" -#include "interface.h" - - - -/** - * mei_set_csr_register - writes H_CSR register to the mei device, - * and ignores the H_IS bit for it is write-one-to-zero. - * - * @dev: the device structure - */ -void mei_hcsr_set(struct mei_device *dev) -{ - if ((dev->host_hw_state & H_IS) == H_IS) - dev->host_hw_state &= ~H_IS; - mei_reg_write(dev, H_CSR, dev->host_hw_state); - dev->host_hw_state = mei_hcsr_read(dev); -} - -/** - * mei_csr_enable_interrupts - enables mei device interrupts - * - * @dev: the device structure - */ -void mei_enable_interrupts(struct mei_device *dev) -{ - dev->host_hw_state |= H_IE; - mei_hcsr_set(dev); -} - -/** - * mei_csr_disable_interrupts - disables mei device interrupts - * - * @dev: the device structure - */ -void mei_disable_interrupts(struct mei_device *dev) -{ - dev->host_hw_state &= ~H_IE; - mei_hcsr_set(dev); -} - -/** - * _host_get_filled_slots - gets number of device filled buffer slots - * - * @device: the device structure - * - * returns number of filled slots - */ -static unsigned char _host_get_filled_slots(const struct mei_device *dev) -{ - char read_ptr, write_ptr; - - read_ptr = (char) ((dev->host_hw_state & H_CBRP) >> 8); - write_ptr = (char) ((dev->host_hw_state & H_CBWP) >> 16); - - return (unsigned char) (write_ptr - read_ptr); -} - -/** - * mei_host_buffer_is_empty - checks if host buffer is empty. - * - * @dev: the device structure - * - * returns 1 if empty, 0 - otherwise. - */ -int mei_host_buffer_is_empty(struct mei_device *dev) -{ - unsigned char filled_slots; - - dev->host_hw_state = mei_hcsr_read(dev); - filled_slots = _host_get_filled_slots(dev); - - if (filled_slots == 0) - return 1; - - return 0; -} - -/** - * mei_count_empty_write_slots - counts write empty slots. - * - * @dev: the device structure - * - * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count - */ -int mei_count_empty_write_slots(struct mei_device *dev) -{ - unsigned char buffer_depth, filled_slots, empty_slots; - - dev->host_hw_state = mei_hcsr_read(dev); - buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24); - filled_slots = _host_get_filled_slots(dev); - empty_slots = buffer_depth - filled_slots; - - /* check for overflow */ - if (filled_slots > buffer_depth) - return -EOVERFLOW; - - return empty_slots; -} - -/** - * mei_write_message - writes a message to mei device. - * - * @dev: the device structure - * @header: header of message - * @write_buffer: message buffer will be written - * @write_length: message size will be written - * - * This function returns -EIO if write has failed - */ -int mei_write_message(struct mei_device *dev, - struct mei_msg_hdr *header, - unsigned char *write_buffer, - unsigned long write_length) -{ - u32 temp_msg = 0; - unsigned long bytes_written = 0; - unsigned char buffer_depth, filled_slots, empty_slots; - unsigned long dw_to_write; - - dev->host_hw_state = mei_hcsr_read(dev); - - dev_dbg(&dev->pdev->dev, - "host_hw_state = 0x%08x.\n", - dev->host_hw_state); - - dev_dbg(&dev->pdev->dev, - "mei_write_message header=%08x.\n", - *((u32 *) header)); - - buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24); - filled_slots = _host_get_filled_slots(dev); - empty_slots = buffer_depth - filled_slots; - dev_dbg(&dev->pdev->dev, - "filled = %hu, empty = %hu.\n", - filled_slots, empty_slots); - - dw_to_write = ((write_length + 3) / 4); - - if (dw_to_write > empty_slots) - return -EIO; - - mei_reg_write(dev, H_CB_WW, *((u32 *) header)); - - while (write_length >= 4) { - mei_reg_write(dev, H_CB_WW, - *(u32 *) (write_buffer + bytes_written)); - bytes_written += 4; - write_length -= 4; - } - - if (write_length > 0) { - memcpy(&temp_msg, &write_buffer[bytes_written], write_length); - mei_reg_write(dev, H_CB_WW, temp_msg); - } - - dev->host_hw_state |= H_IG; - mei_hcsr_set(dev); - dev->me_hw_state = mei_mecsr_read(dev); - if ((dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA) - return -EIO; - - return 0; -} - -/** - * mei_count_full_read_slots - counts read full slots. - * - * @dev: the device structure - * - * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise filled slots count - */ -int mei_count_full_read_slots(struct mei_device *dev) -{ - char read_ptr, write_ptr; - unsigned char buffer_depth, filled_slots; - - dev->me_hw_state = mei_mecsr_read(dev); - buffer_depth = (unsigned char)((dev->me_hw_state & ME_CBD_HRA) >> 24); - read_ptr = (char) ((dev->me_hw_state & ME_CBRP_HRA) >> 8); - write_ptr = (char) ((dev->me_hw_state & ME_CBWP_HRA) >> 16); - filled_slots = (unsigned char) (write_ptr - read_ptr); - - /* check for overflow */ - if (filled_slots > buffer_depth) - return -EOVERFLOW; - - dev_dbg(&dev->pdev->dev, "filled_slots =%08x\n", filled_slots); - return (int)filled_slots; -} - -/** - * mei_read_slots - reads a message from mei device. - * - * @dev: the device structure - * @buffer: message buffer will be written - * @buffer_length: message size will be read - */ -void mei_read_slots(struct mei_device *dev, unsigned char *buffer, - unsigned long buffer_length) -{ - u32 *reg_buf = (u32 *)buffer; - - for (; buffer_length >= sizeof(u32); buffer_length -= sizeof(u32)) - *reg_buf++ = mei_mecbrw_read(dev); - - if (buffer_length > 0) { - u32 reg = mei_mecbrw_read(dev); - memcpy(reg_buf, ®, buffer_length); - } - - dev->host_hw_state |= H_IG; - mei_hcsr_set(dev); -} - -/** - * mei_flow_ctrl_creds - checks flow_control credentials. - * - * @dev: the device structure - * @cl: private data of the file object - * - * returns 1 if mei_flow_ctrl_creds >0, 0 - otherwise. - * -ENOENT if mei_cl is not present - * -EINVAL if single_recv_buf == 0 - */ -int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl) -{ - int i; - - if (!dev->me_clients_num) - return 0; - - if (cl->mei_flow_ctrl_creds > 0) - return 1; - - for (i = 0; i < dev->me_clients_num; i++) { - struct mei_me_client *me_cl = &dev->me_clients[i]; - if (me_cl->client_id == cl->me_client_id) { - if (me_cl->mei_flow_ctrl_creds) { - if (WARN_ON(me_cl->props.single_recv_buf == 0)) - return -EINVAL; - return 1; - } else { - return 0; - } - } - } - return -ENOENT; -} - -/** - * mei_flow_ctrl_reduce - reduces flow_control. - * - * @dev: the device structure - * @cl: private data of the file object - * @returns - * 0 on success - * -ENOENT when me client is not found - * -EINVAL when ctrl credits are <= 0 - */ -int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl) -{ - int i; - - if (!dev->me_clients_num) - return -ENOENT; - - for (i = 0; i < dev->me_clients_num; i++) { - struct mei_me_client *me_cl = &dev->me_clients[i]; - if (me_cl->client_id == cl->me_client_id) { - if (me_cl->props.single_recv_buf != 0) { - if (WARN_ON(me_cl->mei_flow_ctrl_creds <= 0)) - return -EINVAL; - dev->me_clients[i].mei_flow_ctrl_creds--; - } else { - if (WARN_ON(cl->mei_flow_ctrl_creds <= 0)) - return -EINVAL; - cl->mei_flow_ctrl_creds--; - } - return 0; - } - } - return -ENOENT; -} - -/** - * mei_send_flow_control - sends flow control to fw. - * - * @dev: the device structure - * @cl: private data of the file object - * - * This function returns -EIO on write failure - */ -int mei_send_flow_control(struct mei_device *dev, struct mei_cl *cl) -{ - struct mei_msg_hdr *mei_hdr; - struct hbm_flow_control *mei_flow_control; - - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_flow_control); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - mei_flow_control = (struct hbm_flow_control *) &dev->wr_msg_buf[1]; - memset(mei_flow_control, 0, sizeof(*mei_flow_control)); - mei_flow_control->host_addr = cl->host_client_id; - mei_flow_control->me_addr = cl->me_client_id; - mei_flow_control->hbm_cmd = MEI_FLOW_CONTROL_CMD; - memset(mei_flow_control->reserved, 0, - sizeof(mei_flow_control->reserved)); - dev_dbg(&dev->pdev->dev, "sending flow control host client = %d, ME client = %d\n", - cl->host_client_id, cl->me_client_id); - - return mei_write_message(dev, mei_hdr, - (unsigned char *) mei_flow_control, - sizeof(struct hbm_flow_control)); -} - -/** - * mei_other_client_is_connecting - checks if other - * client with the same client id is connected. - * - * @dev: the device structure - * @cl: private data of the file object - * - * returns 1 if other client is connected, 0 - otherwise. - */ -int mei_other_client_is_connecting(struct mei_device *dev, - struct mei_cl *cl) -{ - struct mei_cl *cl_pos = NULL; - struct mei_cl *cl_next = NULL; - - list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { - if ((cl_pos->state == MEI_FILE_CONNECTING) && - (cl_pos != cl) && - cl->me_client_id == cl_pos->me_client_id) - return 1; - - } - return 0; -} - -/** - * mei_disconnect - sends disconnect message to fw. - * - * @dev: the device structure - * @cl: private data of the file object - * - * This function returns -EIO on write failure - */ -int mei_disconnect(struct mei_device *dev, struct mei_cl *cl) -{ - struct mei_msg_hdr *mei_hdr; - struct hbm_client_disconnect_request *mei_cli_disconnect; - - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_client_disconnect_request); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - mei_cli_disconnect = - (struct hbm_client_disconnect_request *) &dev->wr_msg_buf[1]; - memset(mei_cli_disconnect, 0, sizeof(*mei_cli_disconnect)); - mei_cli_disconnect->host_addr = cl->host_client_id; - mei_cli_disconnect->me_addr = cl->me_client_id; - mei_cli_disconnect->hbm_cmd = CLIENT_DISCONNECT_REQ_CMD; - mei_cli_disconnect->reserved[0] = 0; - - return mei_write_message(dev, mei_hdr, - (unsigned char *) mei_cli_disconnect, - sizeof(struct hbm_client_disconnect_request)); -} - -/** - * mei_connect - sends connect message to fw. - * - * @dev: the device structure - * @cl: private data of the file object - * - * This function returns -EIO on write failure - */ -int mei_connect(struct mei_device *dev, struct mei_cl *cl) -{ - struct mei_msg_hdr *mei_hdr; - struct hbm_client_connect_request *mei_cli_connect; - - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_client_connect_request); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - mei_cli_connect = - (struct hbm_client_connect_request *) &dev->wr_msg_buf[1]; - mei_cli_connect->host_addr = cl->host_client_id; - mei_cli_connect->me_addr = cl->me_client_id; - mei_cli_connect->hbm_cmd = CLIENT_CONNECT_REQ_CMD; - mei_cli_connect->reserved = 0; - - return mei_write_message(dev, mei_hdr, - (unsigned char *) mei_cli_connect, - sizeof(struct hbm_client_connect_request)); -} diff --git a/drivers/staging/mei/interface.h b/drivers/staging/mei/interface.h deleted file mode 100644 index 0d00435..0000000 --- a/drivers/staging/mei/interface.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2012, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - - - -#ifndef _MEI_INTERFACE_H_ -#define _MEI_INTERFACE_H_ - -#include "mei.h" -#include "mei_dev.h" - - -#define AMT_WD_DEFAULT_TIMEOUT 120 /* seconds */ -#define AMT_WD_MIN_TIMEOUT 120 /* seconds */ -#define AMT_WD_MAX_TIMEOUT 65535 /* seconds */ - -#define MEI_WATCHDOG_DATA_SIZE 16 -#define MEI_START_WD_DATA_SIZE 20 -#define MEI_WD_PARAMS_SIZE 4 - - -void mei_read_slots(struct mei_device *dev, - unsigned char *buffer, - unsigned long buffer_length); - -int mei_write_message(struct mei_device *dev, - struct mei_msg_hdr *header, - unsigned char *write_buffer, - unsigned long write_length); - -int mei_host_buffer_is_empty(struct mei_device *dev); - -int mei_count_full_read_slots(struct mei_device *dev); - -int mei_count_empty_write_slots(struct mei_device *dev); - -int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl); - -int mei_wd_send(struct mei_device *dev); -int mei_wd_stop(struct mei_device *dev, bool preserve); -int mei_wd_host_init(struct mei_device *dev); -/* - * mei_watchdog_register - Registering watchdog interface - * once we got connection to the WD Client - * @dev - mei device - */ -void mei_watchdog_register(struct mei_device *dev); -/* - * mei_watchdog_unregister - Unregistering watchdog interface - * @dev - mei device - */ -void mei_watchdog_unregister(struct mei_device *dev); - -int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl); - -int mei_send_flow_control(struct mei_device *dev, struct mei_cl *cl); - -int mei_disconnect(struct mei_device *dev, struct mei_cl *cl); -int mei_other_client_is_connecting(struct mei_device *dev, struct mei_cl *cl); -int mei_connect(struct mei_device *dev, struct mei_cl *cl); - -#endif /* _MEI_INTERFACE_H_ */ diff --git a/drivers/staging/mei/interrupt.c b/drivers/staging/mei/interrupt.c deleted file mode 100644 index 2007d24..0000000 --- a/drivers/staging/mei/interrupt.c +++ /dev/null @@ -1,1590 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2012, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - - -#include -#include -#include -#include -#include - -#include "mei_dev.h" -#include "mei.h" -#include "hw.h" -#include "interface.h" - - -/** - * mei_interrupt_quick_handler - The ISR of the MEI device - * - * @irq: The irq number - * @dev_id: pointer to the device structure - * - * returns irqreturn_t - */ -irqreturn_t mei_interrupt_quick_handler(int irq, void *dev_id) -{ - struct mei_device *dev = (struct mei_device *) dev_id; - u32 csr_reg = mei_hcsr_read(dev); - - if ((csr_reg & H_IS) != H_IS) - return IRQ_NONE; - - /* clear H_IS bit in H_CSR */ - mei_reg_write(dev, H_CSR, csr_reg); - - return IRQ_WAKE_THREAD; -} - -/** - * _mei_cmpl - processes completed operation. - * - * @cl: private data of the file object. - * @cb_pos: callback block. - */ -static void _mei_cmpl(struct mei_cl *cl, struct mei_cl_cb *cb_pos) -{ - if (cb_pos->major_file_operations == MEI_WRITE) { - mei_free_cb_private(cb_pos); - cb_pos = NULL; - cl->writing_state = MEI_WRITE_COMPLETE; - if (waitqueue_active(&cl->tx_wait)) - wake_up_interruptible(&cl->tx_wait); - - } else if (cb_pos->major_file_operations == MEI_READ && - MEI_READING == cl->reading_state) { - cl->reading_state = MEI_READ_COMPLETE; - if (waitqueue_active(&cl->rx_wait)) - wake_up_interruptible(&cl->rx_wait); - - } -} - -/** - * _mei_cmpl_iamthif - processes completed iamthif operation. - * - * @dev: the device structure. - * @cb_pos: callback block. - */ -static void _mei_cmpl_iamthif(struct mei_device *dev, struct mei_cl_cb *cb_pos) -{ - if (dev->iamthif_canceled != 1) { - dev->iamthif_state = MEI_IAMTHIF_READ_COMPLETE; - dev->iamthif_stall_timer = 0; - memcpy(cb_pos->response_buffer.data, - dev->iamthif_msg_buf, - dev->iamthif_msg_buf_index); - list_add_tail(&cb_pos->cb_list, - &dev->amthi_read_complete_list.mei_cb.cb_list); - dev_dbg(&dev->pdev->dev, "amthi read completed.\n"); - dev->iamthif_timer = jiffies; - dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n", - dev->iamthif_timer); - } else { - mei_run_next_iamthif_cmd(dev); - } - - dev_dbg(&dev->pdev->dev, "completing amthi call back.\n"); - wake_up_interruptible(&dev->iamthif_cl.wait); -} - - -/** - * mei_irq_thread_read_amthi_message - bottom half read routine after ISR to - * handle the read amthi message data processing. - * - * @complete_list: An instance of our list structure - * @dev: the device structure - * @mei_hdr: header of amthi message - * - * returns 0 on success, <0 on failure. - */ -static int mei_irq_thread_read_amthi_message(struct mei_io_list *complete_list, - struct mei_device *dev, - struct mei_msg_hdr *mei_hdr) -{ - struct mei_cl *cl; - struct mei_cl_cb *cb; - unsigned char *buffer; - - BUG_ON(mei_hdr->me_addr != dev->iamthif_cl.me_client_id); - BUG_ON(dev->iamthif_state != MEI_IAMTHIF_READING); - - buffer = dev->iamthif_msg_buf + dev->iamthif_msg_buf_index; - BUG_ON(dev->iamthif_mtu < dev->iamthif_msg_buf_index + mei_hdr->length); - - mei_read_slots(dev, buffer, mei_hdr->length); - - dev->iamthif_msg_buf_index += mei_hdr->length; - - if (!mei_hdr->msg_complete) - return 0; - - dev_dbg(&dev->pdev->dev, - "amthi_message_buffer_index =%d\n", - mei_hdr->length); - - dev_dbg(&dev->pdev->dev, "completed amthi read.\n "); - if (!dev->iamthif_current_cb) - return -ENODEV; - - cb = dev->iamthif_current_cb; - dev->iamthif_current_cb = NULL; - - cl = (struct mei_cl *)cb->file_private; - if (!cl) - return -ENODEV; - - dev->iamthif_stall_timer = 0; - cb->information = dev->iamthif_msg_buf_index; - cb->read_time = jiffies; - if (dev->iamthif_ioctl && cl == &dev->iamthif_cl) { - /* found the iamthif cb */ - dev_dbg(&dev->pdev->dev, "complete the amthi read cb.\n "); - dev_dbg(&dev->pdev->dev, "add the amthi read cb to complete.\n "); - list_add_tail(&cb->cb_list, - &complete_list->mei_cb.cb_list); - } - return 0; -} - -/** - * _mei_irq_thread_state_ok - checks if mei header matches file private data - * - * @cl: private data of the file object - * @mei_hdr: header of mei client message - * - * returns !=0 if matches, 0 if no match. - */ -static int _mei_irq_thread_state_ok(struct mei_cl *cl, - struct mei_msg_hdr *mei_hdr) -{ - return (cl->host_client_id == mei_hdr->host_addr && - cl->me_client_id == mei_hdr->me_addr && - cl->state == MEI_FILE_CONNECTED && - MEI_READ_COMPLETE != cl->reading_state); -} - -/** - * mei_irq_thread_read_client_message - bottom half read routine after ISR to - * handle the read mei client message data processing. - * - * @complete_list: An instance of our list structure - * @dev: the device structure - * @mei_hdr: header of mei client message - * - * returns 0 on success, <0 on failure. - */ -static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list, - struct mei_device *dev, - struct mei_msg_hdr *mei_hdr) -{ - struct mei_cl *cl; - struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; - unsigned char *buffer = NULL; - - dev_dbg(&dev->pdev->dev, "start client msg\n"); - if (list_empty(&dev->read_list.mei_cb.cb_list)) - goto quit; - - list_for_each_entry_safe(cb_pos, cb_next, - &dev->read_list.mei_cb.cb_list, cb_list) { - cl = (struct mei_cl *)cb_pos->file_private; - if (cl && _mei_irq_thread_state_ok(cl, mei_hdr)) { - cl->reading_state = MEI_READING; - buffer = cb_pos->response_buffer.data + cb_pos->information; - - if (cb_pos->response_buffer.size < - mei_hdr->length + cb_pos->information) { - dev_dbg(&dev->pdev->dev, "message overflow.\n"); - list_del(&cb_pos->cb_list); - return -ENOMEM; - } - if (buffer) - mei_read_slots(dev, buffer, mei_hdr->length); - - cb_pos->information += mei_hdr->length; - if (mei_hdr->msg_complete) { - cl->status = 0; - list_del(&cb_pos->cb_list); - dev_dbg(&dev->pdev->dev, - "completed read host client = %d," - "ME client = %d, " - "data length = %lu\n", - cl->host_client_id, - cl->me_client_id, - cb_pos->information); - - *(cb_pos->response_buffer.data + - cb_pos->information) = '\0'; - dev_dbg(&dev->pdev->dev, "cb_pos->res_buffer - %s\n", - cb_pos->response_buffer.data); - list_add_tail(&cb_pos->cb_list, - &complete_list->mei_cb.cb_list); - } - - break; - } - - } - -quit: - dev_dbg(&dev->pdev->dev, "message read\n"); - if (!buffer) { - mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length); - dev_dbg(&dev->pdev->dev, "discarding message, header =%08x.\n", - *(u32 *) dev->rd_msg_buf); - } - - return 0; -} - -/** - * _mei_irq_thread_iamthif_read - prepares to read iamthif data. - * - * @dev: the device structure. - * @slots: free slots. - * - * returns 0, OK; otherwise, error. - */ -static int _mei_irq_thread_iamthif_read(struct mei_device *dev, s32 *slots) -{ - - if (((*slots) * sizeof(u32)) < (sizeof(struct mei_msg_hdr) - + sizeof(struct hbm_flow_control))) { - return -EMSGSIZE; - } - *slots -= (sizeof(struct mei_msg_hdr) + - sizeof(struct hbm_flow_control) + 3) / 4; - if (mei_send_flow_control(dev, &dev->iamthif_cl)) { - dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n"); - return -EIO; - } - - dev_dbg(&dev->pdev->dev, "iamthif flow control success\n"); - dev->iamthif_state = MEI_IAMTHIF_READING; - dev->iamthif_flow_control_pending = false; - dev->iamthif_msg_buf_index = 0; - dev->iamthif_msg_buf_size = 0; - dev->iamthif_stall_timer = IAMTHIF_STALL_TIMER; - dev->mei_host_buffer_is_empty = mei_host_buffer_is_empty(dev); - return 0; -} - -/** - * _mei_irq_thread_close - processes close related operation. - * - * @dev: the device structure. - * @slots: free slots. - * @cb_pos: callback block. - * @cl: private data of the file object. - * @cmpl_list: complete list. - * - * returns 0, OK; otherwise, error. - */ -static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb_pos, - struct mei_cl *cl, - struct mei_io_list *cmpl_list) -{ - if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + - sizeof(struct hbm_client_disconnect_request))) { - *slots -= (sizeof(struct mei_msg_hdr) + - sizeof(struct hbm_client_disconnect_request) + 3) / 4; - - if (mei_disconnect(dev, cl)) { - cl->status = 0; - cb_pos->information = 0; - list_move_tail(&cb_pos->cb_list, - &cmpl_list->mei_cb.cb_list); - return -EMSGSIZE; - } else { - cl->state = MEI_FILE_DISCONNECTING; - cl->status = 0; - cb_pos->information = 0; - list_move_tail(&cb_pos->cb_list, - &dev->ctrl_rd_list.mei_cb.cb_list); - cl->timer_count = MEI_CONNECT_TIMEOUT; - } - } else { - /* return the cancel routine */ - return -EBADMSG; - } - - return 0; -} - -/** - * is_treat_specially_client - checks if the message belongs - * to the file private data. - * - * @cl: private data of the file object - * @rs: connect response bus message - * - */ -static bool is_treat_specially_client(struct mei_cl *cl, - struct hbm_client_connect_response *rs) -{ - - if (cl->host_client_id == rs->host_addr && - cl->me_client_id == rs->me_addr) { - if (!rs->status) { - cl->state = MEI_FILE_CONNECTED; - cl->status = 0; - - } else { - cl->state = MEI_FILE_DISCONNECTED; - cl->status = -ENODEV; - } - cl->timer_count = 0; - - return true; - } - return false; -} - -/** - * mei_client_connect_response - connects to response irq routine - * - * @dev: the device structure - * @rs: connect response bus message - */ -static void mei_client_connect_response(struct mei_device *dev, - struct hbm_client_connect_response *rs) -{ - - struct mei_cl *cl; - struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; - - dev_dbg(&dev->pdev->dev, - "connect_response:\n" - "ME Client = %d\n" - "Host Client = %d\n" - "Status = %d\n", - rs->me_addr, - rs->host_addr, - rs->status); - - /* if WD or iamthif client treat specially */ - - if (is_treat_specially_client(&(dev->wd_cl), rs)) { - dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n"); - mei_watchdog_register(dev); - - /* next step in the state maching */ - mei_host_init_iamthif(dev); - return; - } - - if (is_treat_specially_client(&(dev->iamthif_cl), rs)) { - dev->iamthif_state = MEI_IAMTHIF_IDLE; - return; - } - list_for_each_entry_safe(cb_pos, cb_next, - &dev->ctrl_rd_list.mei_cb.cb_list, cb_list) { - - cl = (struct mei_cl *)cb_pos->file_private; - if (!cl) { - list_del(&cb_pos->cb_list); - return; - } - if (MEI_IOCTL == cb_pos->major_file_operations) { - if (is_treat_specially_client(cl, rs)) { - list_del(&cb_pos->cb_list); - cl->status = 0; - cl->timer_count = 0; - break; - } - } - } -} - -/** - * mei_client_disconnect_response - disconnects from response irq routine - * - * @dev: the device structure - * @rs: disconnect response bus message - */ -static void mei_client_disconnect_response(struct mei_device *dev, - struct hbm_client_connect_response *rs) -{ - struct mei_cl *cl; - struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; - - dev_dbg(&dev->pdev->dev, - "disconnect_response:\n" - "ME Client = %d\n" - "Host Client = %d\n" - "Status = %d\n", - rs->me_addr, - rs->host_addr, - rs->status); - - list_for_each_entry_safe(cb_pos, cb_next, - &dev->ctrl_rd_list.mei_cb.cb_list, cb_list) { - cl = (struct mei_cl *)cb_pos->file_private; - - if (!cl) { - list_del(&cb_pos->cb_list); - return; - } - - dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in ctrl_rd_list.\n"); - if (cl->host_client_id == rs->host_addr && - cl->me_client_id == rs->me_addr) { - - list_del(&cb_pos->cb_list); - if (!rs->status) - cl->state = MEI_FILE_DISCONNECTED; - - cl->status = 0; - cl->timer_count = 0; - break; - } - } -} - -/** - * same_flow_addr - tells if they have the same address. - * - * @file: private data of the file object. - * @flow: flow control. - * - * returns !=0, same; 0,not. - */ -static int same_flow_addr(struct mei_cl *cl, struct hbm_flow_control *flow) -{ - return (cl->host_client_id == flow->host_addr && - cl->me_client_id == flow->me_addr); -} - -/** - * add_single_flow_creds - adds single buffer credentials. - * - * @file: private data ot the file object. - * @flow: flow control. - */ -static void add_single_flow_creds(struct mei_device *dev, - struct hbm_flow_control *flow) -{ - struct mei_me_client *client; - int i; - - for (i = 0; i < dev->me_clients_num; i++) { - client = &dev->me_clients[i]; - if (client && flow->me_addr == client->client_id) { - if (client->props.single_recv_buf) { - client->mei_flow_ctrl_creds++; - dev_dbg(&dev->pdev->dev, "recv flow ctrl msg ME %d (single).\n", - flow->me_addr); - dev_dbg(&dev->pdev->dev, "flow control credentials =%d.\n", - client->mei_flow_ctrl_creds); - } else { - BUG(); /* error in flow control */ - } - } - } -} - -/** - * mei_client_flow_control_response - flow control response irq routine - * - * @dev: the device structure - * @flow_control: flow control response bus message - */ -static void mei_client_flow_control_response(struct mei_device *dev, - struct hbm_flow_control *flow_control) -{ - struct mei_cl *cl_pos = NULL; - struct mei_cl *cl_next = NULL; - - if (!flow_control->host_addr) { - /* single receive buffer */ - add_single_flow_creds(dev, flow_control); - } else { - /* normal connection */ - list_for_each_entry_safe(cl_pos, cl_next, - &dev->file_list, link) { - dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in file_list\n"); - - dev_dbg(&dev->pdev->dev, "cl of host client %d ME client %d.\n", - cl_pos->host_client_id, - cl_pos->me_client_id); - dev_dbg(&dev->pdev->dev, "flow ctrl msg for host %d ME %d.\n", - flow_control->host_addr, - flow_control->me_addr); - if (same_flow_addr(cl_pos, flow_control)) { - dev_dbg(&dev->pdev->dev, "recv ctrl msg for host %d ME %d.\n", - flow_control->host_addr, - flow_control->me_addr); - cl_pos->mei_flow_ctrl_creds++; - dev_dbg(&dev->pdev->dev, "flow control credentials = %d.\n", - cl_pos->mei_flow_ctrl_creds); - break; - } - } - } -} - -/** - * same_disconn_addr - tells if they have the same address - * - * @file: private data of the file object. - * @disconn: disconnection request. - * - * returns !=0, same; 0,not. - */ -static int same_disconn_addr(struct mei_cl *cl, - struct hbm_client_disconnect_request *disconn) -{ - return (cl->host_client_id == disconn->host_addr && - cl->me_client_id == disconn->me_addr); -} - -/** - * mei_client_disconnect_request - disconnects from request irq routine - * - * @dev: the device structure. - * @disconnect_req: disconnect request bus message. - */ -static void mei_client_disconnect_request(struct mei_device *dev, - struct hbm_client_disconnect_request *disconnect_req) -{ - struct mei_msg_hdr *mei_hdr; - struct hbm_client_connect_response *disconnect_res; - struct mei_cl *cl_pos = NULL; - struct mei_cl *cl_next = NULL; - - list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { - if (same_disconn_addr(cl_pos, disconnect_req)) { - dev_dbg(&dev->pdev->dev, "disconnect request host client %d ME client %d.\n", - disconnect_req->host_addr, - disconnect_req->me_addr); - cl_pos->state = MEI_FILE_DISCONNECTED; - cl_pos->timer_count = 0; - if (cl_pos == &dev->wd_cl) { - dev->wd_due_counter = 0; - dev->wd_pending = false; - } else if (cl_pos == &dev->iamthif_cl) - dev->iamthif_timer = 0; - - /* prepare disconnect response */ - mei_hdr = - (struct mei_msg_hdr *) &dev->ext_msg_buf[0]; - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = - sizeof(struct hbm_client_connect_response); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - disconnect_res = - (struct hbm_client_connect_response *) - &dev->ext_msg_buf[1]; - disconnect_res->host_addr = cl_pos->host_client_id; - disconnect_res->me_addr = cl_pos->me_client_id; - disconnect_res->hbm_cmd = CLIENT_DISCONNECT_RES_CMD; - disconnect_res->status = 0; - dev->extra_write_index = 2; - break; - } - } -} - - -/** - * mei_irq_thread_read_bus_message - bottom half read routine after ISR to - * handle the read bus message cmd processing. - * - * @dev: the device structure - * @mei_hdr: header of bus message - */ -static void mei_irq_thread_read_bus_message(struct mei_device *dev, - struct mei_msg_hdr *mei_hdr) -{ - struct mei_bus_message *mei_msg; - struct hbm_host_version_response *version_res; - struct hbm_client_connect_response *connect_res; - struct hbm_client_connect_response *disconnect_res; - struct hbm_flow_control *flow_control; - struct hbm_props_response *props_res; - struct hbm_host_enum_response *enum_res; - struct hbm_client_disconnect_request *disconnect_req; - struct hbm_host_stop_request *host_stop_req; - int res; - - - /* read the message to our buffer */ - BUG_ON(mei_hdr->length >= sizeof(dev->rd_msg_buf)); - mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length); - mei_msg = (struct mei_bus_message *)dev->rd_msg_buf; - - switch (mei_msg->hbm_cmd) { - case HOST_START_RES_CMD: - version_res = (struct hbm_host_version_response *) mei_msg; - if (version_res->host_version_supported) { - dev->version.major_version = HBM_MAJOR_VERSION; - dev->version.minor_version = HBM_MINOR_VERSION; - if (dev->mei_state == MEI_INIT_CLIENTS && - dev->init_clients_state == MEI_START_MESSAGE) { - dev->init_clients_timer = 0; - mei_host_enum_clients_message(dev); - } else { - dev->recvd_msg = false; - dev_dbg(&dev->pdev->dev, "IMEI reset due to received host start response bus message.\n"); - mei_reset(dev, 1); - return; - } - } else { - dev->version = version_res->me_max_version; - /* send stop message */ - mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0]; - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_host_stop_request); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - host_stop_req = (struct hbm_host_stop_request *) - &dev->wr_msg_buf[1]; - - memset(host_stop_req, - 0, - sizeof(struct hbm_host_stop_request)); - host_stop_req->hbm_cmd = HOST_STOP_REQ_CMD; - host_stop_req->reason = DRIVER_STOP_REQUEST; - mei_write_message(dev, mei_hdr, - (unsigned char *) (host_stop_req), - mei_hdr->length); - dev_dbg(&dev->pdev->dev, "version mismatch.\n"); - return; - } - - dev->recvd_msg = true; - dev_dbg(&dev->pdev->dev, "host start response message received.\n"); - break; - - case CLIENT_CONNECT_RES_CMD: - connect_res = - (struct hbm_client_connect_response *) mei_msg; - mei_client_connect_response(dev, connect_res); - dev_dbg(&dev->pdev->dev, "client connect response message received.\n"); - wake_up(&dev->wait_recvd_msg); - break; - - case CLIENT_DISCONNECT_RES_CMD: - disconnect_res = - (struct hbm_client_connect_response *) mei_msg; - mei_client_disconnect_response(dev, disconnect_res); - dev_dbg(&dev->pdev->dev, "client disconnect response message received.\n"); - wake_up(&dev->wait_recvd_msg); - break; - - case MEI_FLOW_CONTROL_CMD: - flow_control = (struct hbm_flow_control *) mei_msg; - mei_client_flow_control_response(dev, flow_control); - dev_dbg(&dev->pdev->dev, "client flow control response message received.\n"); - break; - - case HOST_CLIENT_PROPERTIES_RES_CMD: - props_res = (struct hbm_props_response *)mei_msg; - if (props_res->status || !dev->me_clients) { - dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n"); - mei_reset(dev, 1); - return; - } - if (dev->me_clients[dev->me_client_presentation_num] - .client_id == props_res->address) { - - dev->me_clients[dev->me_client_presentation_num].props - = props_res->client_properties; - - if (dev->mei_state == MEI_INIT_CLIENTS && - dev->init_clients_state == - MEI_CLIENT_PROPERTIES_MESSAGE) { - dev->me_client_index++; - dev->me_client_presentation_num++; - - /** Send Client Properties request **/ - res = mei_host_client_properties(dev); - if (res < 0) { - dev_dbg(&dev->pdev->dev, "mei_host_client_properties() failed"); - return; - } else if (!res) { - /* - * No more clients to send to. - * Clear Map for indicating now ME clients - * with associated host client - */ - bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX); - dev->open_handle_count = 0; - - /* - * Reserving the first three client IDs - * Client Id 0 - Reserved for MEI Bus Message communications - * Client Id 1 - Reserved for Watchdog - * Client ID 2 - Reserved for AMTHI - */ - bitmap_set(dev->host_clients_map, 0, 3); - dev->mei_state = MEI_ENABLED; - - /* if wd initialization fails, initialization the AMTHI client, - * otherwise the AMTHI client will be initialized after the WD client connect response - * will be received - */ - if (mei_wd_host_init(dev)) - mei_host_init_iamthif(dev); - } - - } else { - dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message"); - mei_reset(dev, 1); - return; - } - } else { - dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message for wrong client ID\n"); - mei_reset(dev, 1); - return; - } - break; - - case HOST_ENUM_RES_CMD: - enum_res = (struct hbm_host_enum_response *) mei_msg; - memcpy(dev->me_clients_map, enum_res->valid_addresses, 32); - if (dev->mei_state == MEI_INIT_CLIENTS && - dev->init_clients_state == MEI_ENUM_CLIENTS_MESSAGE) { - dev->init_clients_timer = 0; - dev->me_client_presentation_num = 0; - dev->me_client_index = 0; - mei_allocate_me_clients_storage(dev); - dev->init_clients_state = - MEI_CLIENT_PROPERTIES_MESSAGE; - mei_host_client_properties(dev); - } else { - dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n"); - mei_reset(dev, 1); - return; - } - break; - - case HOST_STOP_RES_CMD: - dev->mei_state = MEI_DISABLED; - dev_dbg(&dev->pdev->dev, "resetting because of FW stop response.\n"); - mei_reset(dev, 1); - break; - - case CLIENT_DISCONNECT_REQ_CMD: - /* search for client */ - disconnect_req = - (struct hbm_client_disconnect_request *) mei_msg; - mei_client_disconnect_request(dev, disconnect_req); - break; - - case ME_STOP_REQ_CMD: - /* prepare stop request */ - mei_hdr = (struct mei_msg_hdr *) &dev->ext_msg_buf[0]; - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_host_stop_request); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - host_stop_req = - (struct hbm_host_stop_request *) &dev->ext_msg_buf[1]; - memset(host_stop_req, 0, sizeof(struct hbm_host_stop_request)); - host_stop_req->hbm_cmd = HOST_STOP_REQ_CMD; - host_stop_req->reason = DRIVER_STOP_REQUEST; - host_stop_req->reserved[0] = 0; - host_stop_req->reserved[1] = 0; - dev->extra_write_index = 2; - break; - - default: - BUG(); - break; - - } -} - - -/** - * _mei_hb_read - processes read related operation. - * - * @dev: the device structure. - * @slots: free slots. - * @cb_pos: callback block. - * @cl: private data of the file object. - * @cmpl_list: complete list. - * - * returns 0, OK; otherwise, error. - */ -static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb_pos, - struct mei_cl *cl, - struct mei_io_list *cmpl_list) -{ - if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + - sizeof(struct hbm_flow_control))) { - /* return the cancel routine */ - list_del(&cb_pos->cb_list); - return -EBADMSG; - } - - *slots -= (sizeof(struct mei_msg_hdr) + - sizeof(struct hbm_flow_control) + 3) / 4; - if (mei_send_flow_control(dev, cl)) { - cl->status = -ENODEV; - cb_pos->information = 0; - list_move_tail(&cb_pos->cb_list, &cmpl_list->mei_cb.cb_list); - return -ENODEV; - } - list_move_tail(&cb_pos->cb_list, &dev->read_list.mei_cb.cb_list); - - return 0; -} - - -/** - * _mei_irq_thread_ioctl - processes ioctl related operation. - * - * @dev: the device structure. - * @slots: free slots. - * @cb_pos: callback block. - * @cl: private data of the file object. - * @cmpl_list: complete list. - * - * returns 0, OK; otherwise, error. - */ -static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb_pos, - struct mei_cl *cl, - struct mei_io_list *cmpl_list) -{ - if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + - sizeof(struct hbm_client_connect_request))) { - cl->state = MEI_FILE_CONNECTING; - *slots -= (sizeof(struct mei_msg_hdr) + - sizeof(struct hbm_client_connect_request) + 3) / 4; - if (mei_connect(dev, cl)) { - cl->status = -ENODEV; - cb_pos->information = 0; - list_del(&cb_pos->cb_list); - return -ENODEV; - } else { - list_move_tail(&cb_pos->cb_list, - &dev->ctrl_rd_list.mei_cb.cb_list); - cl->timer_count = MEI_CONNECT_TIMEOUT; - } - } else { - /* return the cancel routine */ - list_del(&cb_pos->cb_list); - return -EBADMSG; - } - - return 0; -} - -/** - * _mei_irq_thread_cmpl - processes completed and no-iamthif operation. - * - * @dev: the device structure. - * @slots: free slots. - * @cb_pos: callback block. - * @cl: private data of the file object. - * @cmpl_list: complete list. - * - * returns 0, OK; otherwise, error. - */ -static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb_pos, - struct mei_cl *cl, - struct mei_io_list *cmpl_list) -{ - struct mei_msg_hdr *mei_hdr; - - if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + - (cb_pos->request_buffer.size - - cb_pos->information))) { - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = cl->host_client_id; - mei_hdr->me_addr = cl->me_client_id; - mei_hdr->length = cb_pos->request_buffer.size - - cb_pos->information; - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - dev_dbg(&dev->pdev->dev, "cb_pos->request_buffer.size =%d" - "mei_hdr->msg_complete = %d\n", - cb_pos->request_buffer.size, - mei_hdr->msg_complete); - dev_dbg(&dev->pdev->dev, "cb_pos->information =%lu\n", - cb_pos->information); - dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", - mei_hdr->length); - *slots -= (sizeof(struct mei_msg_hdr) + - mei_hdr->length + 3) / 4; - if (mei_write_message(dev, mei_hdr, - (unsigned char *) - (cb_pos->request_buffer.data + - cb_pos->information), - mei_hdr->length)) { - cl->status = -ENODEV; - list_move_tail(&cb_pos->cb_list, - &cmpl_list->mei_cb.cb_list); - return -ENODEV; - } else { - if (mei_flow_ctrl_reduce(dev, cl)) - return -ENODEV; - cl->status = 0; - cb_pos->information += mei_hdr->length; - list_move_tail(&cb_pos->cb_list, - &dev->write_waiting_list.mei_cb.cb_list); - } - } else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) { - /* buffer is still empty */ - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = cl->host_client_id; - mei_hdr->me_addr = cl->me_client_id; - mei_hdr->length = - (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr); - mei_hdr->msg_complete = 0; - mei_hdr->reserved = 0; - - (*slots) -= (sizeof(struct mei_msg_hdr) + - mei_hdr->length + 3) / 4; - if (mei_write_message(dev, mei_hdr, - (unsigned char *) - (cb_pos->request_buffer.data + - cb_pos->information), - mei_hdr->length)) { - cl->status = -ENODEV; - list_move_tail(&cb_pos->cb_list, - &cmpl_list->mei_cb.cb_list); - return -ENODEV; - } else { - cb_pos->information += mei_hdr->length; - dev_dbg(&dev->pdev->dev, - "cb_pos->request_buffer.size =%d" - " mei_hdr->msg_complete = %d\n", - cb_pos->request_buffer.size, - mei_hdr->msg_complete); - dev_dbg(&dev->pdev->dev, "cb_pos->information =%lu\n", - cb_pos->information); - dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", - mei_hdr->length); - } - return -EMSGSIZE; - } else { - return -EBADMSG; - } - - return 0; -} - -/** - * _mei_irq_thread_cmpl_iamthif - processes completed iamthif operation. - * - * @dev: the device structure. - * @slots: free slots. - * @cb_pos: callback block. - * @cl: private data of the file object. - * @cmpl_list: complete list. - * - * returns 0, OK; otherwise, error. - */ -static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb_pos, - struct mei_cl *cl, - struct mei_io_list *cmpl_list) -{ - struct mei_msg_hdr *mei_hdr; - - if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + - dev->iamthif_msg_buf_size - - dev->iamthif_msg_buf_index)) { - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = cl->host_client_id; - mei_hdr->me_addr = cl->me_client_id; - mei_hdr->length = dev->iamthif_msg_buf_size - - dev->iamthif_msg_buf_index; - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - *slots -= (sizeof(struct mei_msg_hdr) + - mei_hdr->length + 3) / 4; - - if (mei_write_message(dev, mei_hdr, - (dev->iamthif_msg_buf + - dev->iamthif_msg_buf_index), - mei_hdr->length)) { - dev->iamthif_state = MEI_IAMTHIF_IDLE; - cl->status = -ENODEV; - list_del(&cb_pos->cb_list); - return -ENODEV; - } else { - if (mei_flow_ctrl_reduce(dev, cl)) - return -ENODEV; - dev->iamthif_msg_buf_index += mei_hdr->length; - cb_pos->information = dev->iamthif_msg_buf_index; - cl->status = 0; - dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; - dev->iamthif_flow_control_pending = true; - /* save iamthif cb sent to amthi client */ - dev->iamthif_current_cb = cb_pos; - list_move_tail(&cb_pos->cb_list, - &dev->write_waiting_list.mei_cb.cb_list); - - } - } else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) { - /* buffer is still empty */ - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = cl->host_client_id; - mei_hdr->me_addr = cl->me_client_id; - mei_hdr->length = - (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr); - mei_hdr->msg_complete = 0; - mei_hdr->reserved = 0; - - *slots -= (sizeof(struct mei_msg_hdr) + - mei_hdr->length + 3) / 4; - - if (mei_write_message(dev, mei_hdr, - (dev->iamthif_msg_buf + - dev->iamthif_msg_buf_index), - mei_hdr->length)) { - cl->status = -ENODEV; - list_del(&cb_pos->cb_list); - } else { - dev->iamthif_msg_buf_index += mei_hdr->length; - } - return -EMSGSIZE; - } else { - return -EBADMSG; - } - - return 0; -} - -/** - * mei_irq_thread_read_handler - bottom half read routine after ISR to - * handle the read processing. - * - * @cmpl_list: An instance of our list structure - * @dev: the device structure - * @slots: slots to read. - * - * returns 0 on success, <0 on failure. - */ -static int mei_irq_thread_read_handler(struct mei_io_list *cmpl_list, - struct mei_device *dev, - s32 *slots) -{ - struct mei_msg_hdr *mei_hdr; - struct mei_cl *cl_pos = NULL; - struct mei_cl *cl_next = NULL; - int ret = 0; - - if (!dev->rd_msg_hdr) { - dev->rd_msg_hdr = mei_mecbrw_read(dev); - dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots); - (*slots)--; - dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots); - } - mei_hdr = (struct mei_msg_hdr *) &dev->rd_msg_hdr; - dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", mei_hdr->length); - - if (mei_hdr->reserved || !dev->rd_msg_hdr) { - dev_dbg(&dev->pdev->dev, "corrupted message header.\n"); - ret = -EBADMSG; - goto end; - } - - if (mei_hdr->host_addr || mei_hdr->me_addr) { - list_for_each_entry_safe(cl_pos, cl_next, - &dev->file_list, link) { - dev_dbg(&dev->pdev->dev, - "list_for_each_entry_safe read host" - " client = %d, ME client = %d\n", - cl_pos->host_client_id, - cl_pos->me_client_id); - if (cl_pos->host_client_id == mei_hdr->host_addr && - cl_pos->me_client_id == mei_hdr->me_addr) - break; - } - - if (&cl_pos->link == &dev->file_list) { - dev_dbg(&dev->pdev->dev, "corrupted message header\n"); - ret = -EBADMSG; - goto end; - } - } - if (((*slots) * sizeof(u32)) < mei_hdr->length) { - dev_dbg(&dev->pdev->dev, - "we can't read the message slots =%08x.\n", - *slots); - /* we can't read the message */ - ret = -ERANGE; - goto end; - } - - /* decide where to read the message too */ - if (!mei_hdr->host_addr) { - dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_bus_message.\n"); - mei_irq_thread_read_bus_message(dev, mei_hdr); - dev_dbg(&dev->pdev->dev, "end mei_irq_thread_read_bus_message.\n"); - } else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id && - (MEI_FILE_CONNECTED == dev->iamthif_cl.state) && - (dev->iamthif_state == MEI_IAMTHIF_READING)) { - dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n"); - dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", - mei_hdr->length); - ret = mei_irq_thread_read_amthi_message(cmpl_list, - dev, mei_hdr); - if (ret) - goto end; - - } else { - dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_client_message.\n"); - ret = mei_irq_thread_read_client_message(cmpl_list, - dev, mei_hdr); - if (ret) - goto end; - - } - - /* reset the number of slots and header */ - *slots = mei_count_full_read_slots(dev); - dev->rd_msg_hdr = 0; - - if (*slots == -EOVERFLOW) { - /* overflow - reset */ - dev_dbg(&dev->pdev->dev, "resetting due to slots overflow.\n"); - /* set the event since message has been read */ - ret = -ERANGE; - goto end; - } -end: - return ret; -} - - -/** - * mei_irq_thread_write_handler - bottom half write routine after - * ISR to handle the write processing. - * - * @cmpl_list: An instance of our list structure - * @dev: the device structure - * @slots: slots to write. - * - * returns 0 on success, <0 on failure. - */ -static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, - struct mei_device *dev, - s32 *slots) -{ - - struct mei_cl *cl; - struct mei_cl_cb *pos = NULL, *next = NULL; - struct mei_io_list *list; - int ret; - - if (!mei_host_buffer_is_empty(dev)) { - dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n"); - return 0; - } - *slots = mei_count_empty_write_slots(dev); - /* complete all waiting for write CB */ - dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n"); - - list = &dev->write_waiting_list; - list_for_each_entry_safe(pos, next, - &list->mei_cb.cb_list, cb_list) { - cl = (struct mei_cl *)pos->file_private; - if (cl == NULL) - continue; - - cl->status = 0; - list_del(&pos->cb_list); - if (MEI_WRITING == cl->writing_state && - (pos->major_file_operations == MEI_WRITE) && - (cl != &dev->iamthif_cl)) { - dev_dbg(&dev->pdev->dev, - "MEI WRITE COMPLETE\n"); - cl->writing_state = MEI_WRITE_COMPLETE; - list_add_tail(&pos->cb_list, - &cmpl_list->mei_cb.cb_list); - } - if (cl == &dev->iamthif_cl) { - dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n"); - if (dev->iamthif_flow_control_pending) { - ret = _mei_irq_thread_iamthif_read( - dev, slots); - if (ret) - return ret; - } - } - } - - if (dev->stop && !dev->wd_pending) { - dev->wd_stopped = true; - wake_up_interruptible(&dev->wait_stop_wd); - return 0; - } - - if (dev->extra_write_index) { - dev_dbg(&dev->pdev->dev, "extra_write_index =%d.\n", - dev->extra_write_index); - mei_write_message(dev, - (struct mei_msg_hdr *) &dev->ext_msg_buf[0], - (unsigned char *) &dev->ext_msg_buf[1], - (dev->extra_write_index - 1) * sizeof(u32)); - *slots -= dev->extra_write_index; - dev->extra_write_index = 0; - } - if (dev->mei_state == MEI_ENABLED) { - if (dev->wd_pending && - mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) { - if (mei_wd_send(dev)) - dev_dbg(&dev->pdev->dev, "wd send failed.\n"); - else - if (mei_flow_ctrl_reduce(dev, &dev->wd_cl)) - return -ENODEV; - - dev->wd_pending = false; - - if (dev->wd_timeout) { - *slots -= (sizeof(struct mei_msg_hdr) + - MEI_START_WD_DATA_SIZE + 3) / 4; - dev->wd_due_counter = 2; - } else { - *slots -= (sizeof(struct mei_msg_hdr) + - MEI_WD_PARAMS_SIZE + 3) / 4; - dev->wd_due_counter = 0; - } - - } - } - if (dev->stop) - return -ENODEV; - - /* complete control write list CB */ - dev_dbg(&dev->pdev->dev, "complete control write list cb.\n"); - list_for_each_entry_safe(pos, next, - &dev->ctrl_wr_list.mei_cb.cb_list, cb_list) { - cl = (struct mei_cl *) pos->file_private; - if (!cl) { - list_del(&pos->cb_list); - return -ENODEV; - } - switch (pos->major_file_operations) { - case MEI_CLOSE: - /* send disconnect message */ - ret = _mei_irq_thread_close(dev, slots, pos, cl, cmpl_list); - if (ret) - return ret; - - break; - case MEI_READ: - /* send flow control message */ - ret = _mei_irq_thread_read(dev, slots, pos, cl, cmpl_list); - if (ret) - return ret; - - break; - case MEI_IOCTL: - /* connect message */ - if (mei_other_client_is_connecting(dev, cl)) - continue; - ret = _mei_irq_thread_ioctl(dev, slots, pos, cl, cmpl_list); - if (ret) - return ret; - - break; - - default: - BUG(); - } - - } - /* complete write list CB */ - dev_dbg(&dev->pdev->dev, "complete write list cb.\n"); - list_for_each_entry_safe(pos, next, - &dev->write_list.mei_cb.cb_list, cb_list) { - cl = (struct mei_cl *)pos->file_private; - if (cl == NULL) - continue; - - if (cl != &dev->iamthif_cl) { - if (!mei_flow_ctrl_creds(dev, cl)) { - dev_dbg(&dev->pdev->dev, - "No flow control" - " credentials for client" - " %d, not sending.\n", - cl->host_client_id); - continue; - } - ret = _mei_irq_thread_cmpl(dev, slots, - pos, - cl, cmpl_list); - if (ret) - return ret; - - } else if (cl == &dev->iamthif_cl) { - /* IAMTHIF IOCTL */ - dev_dbg(&dev->pdev->dev, "complete amthi write cb.\n"); - if (!mei_flow_ctrl_creds(dev, cl)) { - dev_dbg(&dev->pdev->dev, - "No flow control" - " credentials for amthi" - " client %d.\n", - cl->host_client_id); - continue; - } - ret = _mei_irq_thread_cmpl_iamthif(dev, - slots, - pos, - cl, - cmpl_list); - if (ret) - return ret; - - } - - } - return 0; -} - - - -/** - * mei_timer - timer function. - * - * @work: pointer to the work_struct structure - * - * NOTE: This function is called by timer interrupt work - */ -void mei_timer(struct work_struct *work) -{ - unsigned long timeout; - struct mei_cl *cl_pos = NULL; - struct mei_cl *cl_next = NULL; - struct list_head *amthi_complete_list = NULL; - struct mei_cl_cb *cb_pos = NULL; - struct mei_cl_cb *cb_next = NULL; - - struct mei_device *dev = container_of(work, - struct mei_device, timer_work.work); - - - mutex_lock(&dev->device_lock); - if (dev->mei_state != MEI_ENABLED) { - if (dev->mei_state == MEI_INIT_CLIENTS) { - if (dev->init_clients_timer) { - if (--dev->init_clients_timer == 0) { - dev_dbg(&dev->pdev->dev, "IMEI reset due to init clients timeout ,init clients state = %d.\n", - dev->init_clients_state); - mei_reset(dev, 1); - } - } - } - goto out; - } - /*** connect/disconnect timeouts ***/ - list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { - if (cl_pos->timer_count) { - if (--cl_pos->timer_count == 0) { - dev_dbg(&dev->pdev->dev, "HECI reset due to connect/disconnect timeout.\n"); - mei_reset(dev, 1); - goto out; - } - } - } - - if (dev->iamthif_stall_timer) { - if (--dev->iamthif_stall_timer == 0) { - dev_dbg(&dev->pdev->dev, "resetting because of hang to amthi.\n"); - mei_reset(dev, 1); - dev->iamthif_msg_buf_size = 0; - dev->iamthif_msg_buf_index = 0; - dev->iamthif_canceled = false; - dev->iamthif_ioctl = true; - dev->iamthif_state = MEI_IAMTHIF_IDLE; - dev->iamthif_timer = 0; - - if (dev->iamthif_current_cb) - mei_free_cb_private(dev->iamthif_current_cb); - - dev->iamthif_file_object = NULL; - dev->iamthif_current_cb = NULL; - mei_run_next_iamthif_cmd(dev); - } - } - - if (dev->iamthif_timer) { - - timeout = dev->iamthif_timer + - msecs_to_jiffies(IAMTHIF_READ_TIMER); - - dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n", - dev->iamthif_timer); - dev_dbg(&dev->pdev->dev, "timeout = %ld\n", timeout); - dev_dbg(&dev->pdev->dev, "jiffies = %ld\n", jiffies); - if (time_after(jiffies, timeout)) { - /* - * User didn't read the AMTHI data on time (15sec) - * freeing AMTHI for other requests - */ - - dev_dbg(&dev->pdev->dev, "freeing AMTHI for other requests\n"); - - amthi_complete_list = &dev->amthi_read_complete_list. - mei_cb.cb_list; - - list_for_each_entry_safe(cb_pos, cb_next, amthi_complete_list, cb_list) { - - cl_pos = cb_pos->file_object->private_data; - - /* Finding the AMTHI entry. */ - if (cl_pos == &dev->iamthif_cl) - list_del(&cb_pos->cb_list); - } - if (dev->iamthif_current_cb) - mei_free_cb_private(dev->iamthif_current_cb); - - dev->iamthif_file_object->private_data = NULL; - dev->iamthif_file_object = NULL; - dev->iamthif_current_cb = NULL; - dev->iamthif_timer = 0; - mei_run_next_iamthif_cmd(dev); - - } - } -out: - schedule_delayed_work(&dev->timer_work, 2 * HZ); - mutex_unlock(&dev->device_lock); -} - -/** - * mei_interrupt_thread_handler - function called after ISR to handle the interrupt - * processing. - * - * @irq: The irq number - * @dev_id: pointer to the device structure - * - * returns irqreturn_t - * - */ -irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id) -{ - struct mei_device *dev = (struct mei_device *) dev_id; - struct mei_io_list complete_list; - struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; - struct mei_cl *cl; - s32 slots; - int rets; - bool bus_message_received; - - - dev_dbg(&dev->pdev->dev, "function called after ISR to handle the interrupt processing.\n"); - /* initialize our complete list */ - mutex_lock(&dev->device_lock); - mei_io_list_init(&complete_list); - dev->host_hw_state = mei_hcsr_read(dev); - - /* Ack the interrupt here - * In case of MSI we don't go through the quick handler */ - if (pci_dev_msi_enabled(dev->pdev)) - mei_reg_write(dev, H_CSR, dev->host_hw_state); - - dev->me_hw_state = mei_mecsr_read(dev); - - /* check if ME wants a reset */ - if ((dev->me_hw_state & ME_RDY_HRA) == 0 && - dev->mei_state != MEI_RESETING && - dev->mei_state != MEI_INITIALIZING) { - dev_dbg(&dev->pdev->dev, "FW not ready.\n"); - mei_reset(dev, 1); - mutex_unlock(&dev->device_lock); - return IRQ_HANDLED; - } - - /* check if we need to start the dev */ - if ((dev->host_hw_state & H_RDY) == 0) { - if ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA) { - dev_dbg(&dev->pdev->dev, "we need to start the dev.\n"); - dev->host_hw_state |= (H_IE | H_IG | H_RDY); - mei_hcsr_set(dev); - dev->mei_state = MEI_INIT_CLIENTS; - dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n"); - /* link is established - * start sending messages. - */ - mei_host_start_message(dev); - mutex_unlock(&dev->device_lock); - return IRQ_HANDLED; - } else { - dev_dbg(&dev->pdev->dev, "FW not ready.\n"); - mutex_unlock(&dev->device_lock); - return IRQ_HANDLED; - } - } - /* check slots available for reading */ - slots = mei_count_full_read_slots(dev); - dev_dbg(&dev->pdev->dev, "slots =%08x extra_write_index =%08x.\n", - slots, dev->extra_write_index); - while (slots > 0 && !dev->extra_write_index) { - dev_dbg(&dev->pdev->dev, "slots =%08x extra_write_index =%08x.\n", - slots, dev->extra_write_index); - dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_handler.\n"); - rets = mei_irq_thread_read_handler(&complete_list, dev, &slots); - if (rets) - goto end; - } - rets = mei_irq_thread_write_handler(&complete_list, dev, &slots); -end: - dev_dbg(&dev->pdev->dev, "end of bottom half function.\n"); - dev->host_hw_state = mei_hcsr_read(dev); - dev->mei_host_buffer_is_empty = mei_host_buffer_is_empty(dev); - - bus_message_received = false; - if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) { - dev_dbg(&dev->pdev->dev, "received waiting bus message\n"); - bus_message_received = true; - } - mutex_unlock(&dev->device_lock); - if (bus_message_received) { - dev_dbg(&dev->pdev->dev, "wake up dev->wait_recvd_msg\n"); - wake_up_interruptible(&dev->wait_recvd_msg); - bus_message_received = false; - } - if (list_empty(&complete_list.mei_cb.cb_list)) - return IRQ_HANDLED; - - - list_for_each_entry_safe(cb_pos, cb_next, - &complete_list.mei_cb.cb_list, cb_list) { - cl = (struct mei_cl *)cb_pos->file_private; - list_del(&cb_pos->cb_list); - if (cl) { - if (cl != &dev->iamthif_cl) { - dev_dbg(&dev->pdev->dev, "completing call back.\n"); - _mei_cmpl(cl, cb_pos); - cb_pos = NULL; - } else if (cl == &dev->iamthif_cl) { - _mei_cmpl_iamthif(dev, cb_pos); - } - } - } - return IRQ_HANDLED; -} diff --git a/drivers/staging/mei/iorw.c b/drivers/staging/mei/iorw.c deleted file mode 100644 index 0a80dc4..0000000 --- a/drivers/staging/mei/iorw.c +++ /dev/null @@ -1,590 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2012, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include "mei_dev.h" -#include "hw.h" -#include "mei.h" -#include "interface.h" - - - -/** - * mei_ioctl_connect_client - the connect to fw client IOCTL function - * - * @dev: the device structure - * @data: IOCTL connect data, input and output parameters - * @file: private data of the file object - * - * Locking: called under "dev->device_lock" lock - * - * returns 0 on success, <0 on failure. - */ -int mei_ioctl_connect_client(struct file *file, - struct mei_connect_client_data *data) -{ - struct mei_device *dev; - struct mei_cl_cb *cb; - struct mei_client *client; - struct mei_cl *cl; - struct mei_cl *cl_pos = NULL; - struct mei_cl *cl_next = NULL; - long timeout = CONNECT_TIMEOUT; - int i; - int err; - int rets; - - cl = file->private_data; - if (WARN_ON(!cl || !cl->dev)) - return -ENODEV; - - dev = cl->dev; - - dev_dbg(&dev->pdev->dev, "mei_ioctl_connect_client() Entry\n"); - - - /* buffered ioctl cb */ - cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); - if (!cb) { - rets = -ENOMEM; - goto end; - } - INIT_LIST_HEAD(&cb->cb_list); - - cb->major_file_operations = MEI_IOCTL; - - if (dev->mei_state != MEI_ENABLED) { - rets = -ENODEV; - goto end; - } - if (cl->state != MEI_FILE_INITIALIZING && - cl->state != MEI_FILE_DISCONNECTED) { - rets = -EBUSY; - goto end; - } - - /* find ME client we're trying to connect to */ - i = mei_find_me_client_index(dev, data->in_client_uuid); - if (i >= 0 && !dev->me_clients[i].props.fixed_address) { - cl->me_client_id = dev->me_clients[i].client_id; - cl->state = MEI_FILE_CONNECTING; - } - - dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n", - cl->me_client_id); - dev_dbg(&dev->pdev->dev, "FW Client - Protocol Version = %d\n", - dev->me_clients[i].props.protocol_version); - dev_dbg(&dev->pdev->dev, "FW Client - Max Msg Len = %d\n", - dev->me_clients[i].props.max_msg_length); - - /* if we're connecting to amthi client then we will use the - * existing connection - */ - if (uuid_le_cmp(data->in_client_uuid, mei_amthi_guid) == 0) { - dev_dbg(&dev->pdev->dev, "FW Client is amthi\n"); - if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) { - rets = -ENODEV; - goto end; - } - clear_bit(cl->host_client_id, dev->host_clients_map); - list_for_each_entry_safe(cl_pos, cl_next, - &dev->file_list, link) { - if (mei_cl_cmp_id(cl, cl_pos)) { - dev_dbg(&dev->pdev->dev, - "remove file private data node host" - " client = %d, ME client = %d.\n", - cl_pos->host_client_id, - cl_pos->me_client_id); - list_del(&cl_pos->link); - } - - } - dev_dbg(&dev->pdev->dev, "free file private data memory.\n"); - kfree(cl); - - cl = NULL; - file->private_data = &dev->iamthif_cl; - - client = &data->out_client_properties; - client->max_msg_length = - dev->me_clients[i].props.max_msg_length; - client->protocol_version = - dev->me_clients[i].props.protocol_version; - rets = dev->iamthif_cl.status; - - goto end; - } - - if (cl->state != MEI_FILE_CONNECTING) { - rets = -ENODEV; - goto end; - } - - - /* prepare the output buffer */ - client = &data->out_client_properties; - client->max_msg_length = dev->me_clients[i].props.max_msg_length; - client->protocol_version = dev->me_clients[i].props.protocol_version; - dev_dbg(&dev->pdev->dev, "Can connect?\n"); - if (dev->mei_host_buffer_is_empty - && !mei_other_client_is_connecting(dev, cl)) { - dev_dbg(&dev->pdev->dev, "Sending Connect Message\n"); - dev->mei_host_buffer_is_empty = false; - if (mei_connect(dev, cl)) { - dev_dbg(&dev->pdev->dev, "Sending connect message - failed\n"); - rets = -ENODEV; - goto end; - } else { - dev_dbg(&dev->pdev->dev, "Sending connect message - succeeded\n"); - cl->timer_count = MEI_CONNECT_TIMEOUT; - cb->file_private = cl; - list_add_tail(&cb->cb_list, - &dev->ctrl_rd_list.mei_cb. - cb_list); - } - - - } else { - dev_dbg(&dev->pdev->dev, "Queuing the connect request due to device busy\n"); - cb->file_private = cl; - dev_dbg(&dev->pdev->dev, "add connect cb to control write list.\n"); - list_add_tail(&cb->cb_list, - &dev->ctrl_wr_list.mei_cb.cb_list); - } - mutex_unlock(&dev->device_lock); - err = wait_event_timeout(dev->wait_recvd_msg, - (MEI_FILE_CONNECTED == cl->state || - MEI_FILE_DISCONNECTED == cl->state), - timeout * HZ); - - mutex_lock(&dev->device_lock); - if (MEI_FILE_CONNECTED == cl->state) { - dev_dbg(&dev->pdev->dev, "successfully connected to FW client.\n"); - rets = cl->status; - goto end; - } else { - dev_dbg(&dev->pdev->dev, "failed to connect to FW client.cl->state = %d.\n", - cl->state); - if (!err) { - dev_dbg(&dev->pdev->dev, - "wait_event_interruptible_timeout failed on client" - " connect message fw response message.\n"); - } - rets = -EFAULT; - - mei_io_list_flush(&dev->ctrl_rd_list, cl); - mei_io_list_flush(&dev->ctrl_wr_list, cl); - goto end; - } - rets = 0; -end: - dev_dbg(&dev->pdev->dev, "free connect cb memory."); - kfree(cb); - return rets; -} - -/** - * find_amthi_read_list_entry - finds a amthilist entry for current file - * - * @dev: the device structure - * @file: pointer to file object - * - * returns returned a list entry on success, NULL on failure. - */ -struct mei_cl_cb *find_amthi_read_list_entry( - struct mei_device *dev, - struct file *file) -{ - struct mei_cl *cl_temp; - struct mei_cl_cb *pos = NULL; - struct mei_cl_cb *next = NULL; - - list_for_each_entry_safe(pos, next, - &dev->amthi_read_complete_list.mei_cb.cb_list, cb_list) { - cl_temp = (struct mei_cl *)pos->file_private; - if (cl_temp && cl_temp == &dev->iamthif_cl && - pos->file_object == file) - return pos; - } - return NULL; -} - -/** - * amthi_read - read data from AMTHI client - * - * @dev: the device structure - * @if_num: minor number - * @file: pointer to file object - * @*ubuf: pointer to user data in user space - * @length: data length to read - * @offset: data read offset - * - * Locking: called under "dev->device_lock" lock - * - * returns - * returned data length on success, - * zero if no data to read, - * negative on failure. - */ -int amthi_read(struct mei_device *dev, struct file *file, - char __user *ubuf, size_t length, loff_t *offset) -{ - int rets; - int wait_ret; - struct mei_cl_cb *cb = NULL; - struct mei_cl *cl = file->private_data; - unsigned long timeout; - int i; - - /* Only Posible if we are in timeout */ - if (!cl || cl != &dev->iamthif_cl) { - dev_dbg(&dev->pdev->dev, "bad file ext.\n"); - return -ETIMEDOUT; - } - - for (i = 0; i < dev->me_clients_num; i++) { - if (dev->me_clients[i].client_id == - dev->iamthif_cl.me_client_id) - break; - } - - if (i == dev->me_clients_num) { - dev_dbg(&dev->pdev->dev, "amthi client not found.\n"); - return -ENODEV; - } - if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id)) - return -ENODEV; - - dev_dbg(&dev->pdev->dev, "checking amthi data\n"); - cb = find_amthi_read_list_entry(dev, file); - - /* Check for if we can block or not*/ - if (cb == NULL && file->f_flags & O_NONBLOCK) - return -EAGAIN; - - - dev_dbg(&dev->pdev->dev, "waiting for amthi data\n"); - while (cb == NULL) { - /* unlock the Mutex */ - mutex_unlock(&dev->device_lock); - - wait_ret = wait_event_interruptible(dev->iamthif_cl.wait, - (cb = find_amthi_read_list_entry(dev, file))); - - if (wait_ret) - return -ERESTARTSYS; - - dev_dbg(&dev->pdev->dev, "woke up from sleep\n"); - - /* Locking again the Mutex */ - mutex_lock(&dev->device_lock); - } - - - dev_dbg(&dev->pdev->dev, "Got amthi data\n"); - dev->iamthif_timer = 0; - - if (cb) { - timeout = cb->read_time + - msecs_to_jiffies(IAMTHIF_READ_TIMER); - dev_dbg(&dev->pdev->dev, "amthi timeout = %lud\n", - timeout); - - if (time_after(jiffies, timeout)) { - dev_dbg(&dev->pdev->dev, "amthi Time out\n"); - /* 15 sec for the message has expired */ - list_del(&cb->cb_list); - rets = -ETIMEDOUT; - goto free; - } - } - /* if the whole message will fit remove it from the list */ - if (cb->information >= *offset && length >= (cb->information - *offset)) - list_del(&cb->cb_list); - else if (cb->information > 0 && cb->information <= *offset) { - /* end of the message has been reached */ - list_del(&cb->cb_list); - rets = 0; - goto free; - } - /* else means that not full buffer will be read and do not - * remove message from deletion list - */ - - dev_dbg(&dev->pdev->dev, "amthi cb->response_buffer size - %d\n", - cb->response_buffer.size); - dev_dbg(&dev->pdev->dev, "amthi cb->information - %lu\n", - cb->information); - - /* length is being turncated to PAGE_SIZE, however, - * the information may be longer */ - length = min_t(size_t, length, (cb->information - *offset)); - - if (copy_to_user(ubuf, cb->response_buffer.data + *offset, length)) - rets = -EFAULT; - else { - rets = length; - if ((*offset + length) < cb->information) { - *offset += length; - goto out; - } - } -free: - dev_dbg(&dev->pdev->dev, "free amthi cb memory.\n"); - *offset = 0; - mei_free_cb_private(cb); -out: - return rets; -} - -/** - * mei_start_read - the start read client message function. - * - * @dev: the device structure - * @if_num: minor number - * @cl: private data of the file object - * - * returns 0 on success, <0 on failure. - */ -int mei_start_read(struct mei_device *dev, struct mei_cl *cl) -{ - struct mei_cl_cb *cb; - int rets = 0; - int i; - - if (cl->state != MEI_FILE_CONNECTED) - return -ENODEV; - - if (dev->mei_state != MEI_ENABLED) - return -ENODEV; - - dev_dbg(&dev->pdev->dev, "check if read is pending.\n"); - if (cl->read_pending || cl->read_cb) { - dev_dbg(&dev->pdev->dev, "read is pending.\n"); - return -EBUSY; - } - - cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); - if (!cb) - return -ENOMEM; - - dev_dbg(&dev->pdev->dev, "allocation call back successful. host client = %d, ME client = %d\n", - cl->host_client_id, cl->me_client_id); - - for (i = 0; i < dev->me_clients_num; i++) { - if (dev->me_clients[i].client_id == cl->me_client_id) - break; - - } - - if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id)) { - rets = -ENODEV; - goto unlock; - } - - if (i == dev->me_clients_num) { - rets = -ENODEV; - goto unlock; - } - - cb->response_buffer.size = dev->me_clients[i].props.max_msg_length; - cb->response_buffer.data = - kmalloc(cb->response_buffer.size, GFP_KERNEL); - if (!cb->response_buffer.data) { - rets = -ENOMEM; - goto unlock; - } - dev_dbg(&dev->pdev->dev, "allocation call back data success.\n"); - cb->major_file_operations = MEI_READ; - /* make sure information is zero before we start */ - cb->information = 0; - cb->file_private = (void *) cl; - cl->read_cb = cb; - if (dev->mei_host_buffer_is_empty) { - dev->mei_host_buffer_is_empty = false; - if (mei_send_flow_control(dev, cl)) { - rets = -ENODEV; - goto unlock; - } - list_add_tail(&cb->cb_list, &dev->read_list.mei_cb.cb_list); - } else { - list_add_tail(&cb->cb_list, &dev->ctrl_wr_list.mei_cb.cb_list); - } - return rets; -unlock: - mei_free_cb_private(cb); - return rets; -} - -/** - * amthi_write - write iamthif data to amthi client - * - * @dev: the device structure - * @cb: mei call back struct - * - * returns 0 on success, <0 on failure. - */ -int amthi_write(struct mei_device *dev, struct mei_cl_cb *cb) -{ - struct mei_msg_hdr mei_hdr; - int ret; - - if (!dev || !cb) - return -ENODEV; - - dev_dbg(&dev->pdev->dev, "write data to amthi client.\n"); - - dev->iamthif_state = MEI_IAMTHIF_WRITING; - dev->iamthif_current_cb = cb; - dev->iamthif_file_object = cb->file_object; - dev->iamthif_canceled = false; - dev->iamthif_ioctl = true; - dev->iamthif_msg_buf_size = cb->request_buffer.size; - memcpy(dev->iamthif_msg_buf, cb->request_buffer.data, - cb->request_buffer.size); - - ret = mei_flow_ctrl_creds(dev, &dev->iamthif_cl); - if (ret < 0) - return ret; - - if (ret && dev->mei_host_buffer_is_empty) { - ret = 0; - dev->mei_host_buffer_is_empty = false; - if (cb->request_buffer.size > - (((dev->host_hw_state & H_CBD) >> 24) * sizeof(u32)) - -sizeof(struct mei_msg_hdr)) { - mei_hdr.length = - (((dev->host_hw_state & H_CBD) >> 24) * - sizeof(u32)) - sizeof(struct mei_msg_hdr); - mei_hdr.msg_complete = 0; - } else { - mei_hdr.length = cb->request_buffer.size; - mei_hdr.msg_complete = 1; - } - - mei_hdr.host_addr = dev->iamthif_cl.host_client_id; - mei_hdr.me_addr = dev->iamthif_cl.me_client_id; - mei_hdr.reserved = 0; - dev->iamthif_msg_buf_index += mei_hdr.length; - if (mei_write_message(dev, &mei_hdr, - (unsigned char *)(dev->iamthif_msg_buf), - mei_hdr.length)) - return -ENODEV; - - if (mei_hdr.msg_complete) { - if (mei_flow_ctrl_reduce(dev, &dev->iamthif_cl)) - return -ENODEV; - dev->iamthif_flow_control_pending = true; - dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; - dev_dbg(&dev->pdev->dev, "add amthi cb to write waiting list\n"); - dev->iamthif_current_cb = cb; - dev->iamthif_file_object = cb->file_object; - list_add_tail(&cb->cb_list, - &dev->write_waiting_list.mei_cb.cb_list); - } else { - dev_dbg(&dev->pdev->dev, "message does not complete, " - "so add amthi cb to write list.\n"); - list_add_tail(&cb->cb_list, - &dev->write_list.mei_cb.cb_list); - } - } else { - if (!(dev->mei_host_buffer_is_empty)) - dev_dbg(&dev->pdev->dev, "host buffer is not empty"); - - dev_dbg(&dev->pdev->dev, "No flow control credentials, " - "so add iamthif cb to write list.\n"); - list_add_tail(&cb->cb_list, &dev->write_list.mei_cb.cb_list); - } - return 0; -} - -/** - * iamthif_ioctl_send_msg - send cmd data to amthi client - * - * @dev: the device structure - * - * returns 0 on success, <0 on failure. - */ -void mei_run_next_iamthif_cmd(struct mei_device *dev) -{ - struct mei_cl *cl_tmp; - struct mei_cl_cb *pos = NULL; - struct mei_cl_cb *next = NULL; - int status; - - if (!dev) - return; - - dev->iamthif_msg_buf_size = 0; - dev->iamthif_msg_buf_index = 0; - dev->iamthif_canceled = false; - dev->iamthif_ioctl = true; - dev->iamthif_state = MEI_IAMTHIF_IDLE; - dev->iamthif_timer = 0; - dev->iamthif_file_object = NULL; - - dev_dbg(&dev->pdev->dev, "complete amthi cmd_list cb.\n"); - - list_for_each_entry_safe(pos, next, - &dev->amthi_cmd_list.mei_cb.cb_list, cb_list) { - list_del(&pos->cb_list); - cl_tmp = (struct mei_cl *)pos->file_private; - - if (cl_tmp && cl_tmp == &dev->iamthif_cl) { - status = amthi_write(dev, pos); - if (status) { - dev_dbg(&dev->pdev->dev, - "amthi write failed status = %d\n", - status); - return; - } - break; - } - } -} - -/** - * mei_free_cb_private - free mei_cb_private related memory - * - * @cb: mei callback struct - */ -void mei_free_cb_private(struct mei_cl_cb *cb) -{ - if (cb == NULL) - return; - - kfree(cb->request_buffer.data); - kfree(cb->response_buffer.data); - kfree(cb); -} diff --git a/drivers/staging/mei/main.c b/drivers/staging/mei/main.c deleted file mode 100644 index 20f80df..0000000 --- a/drivers/staging/mei/main.c +++ /dev/null @@ -1,1230 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2012, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mei_dev.h" -#include "mei.h" -#include "interface.h" - -static const char mei_driver_name[] = "mei"; - -/* The device pointer */ -/* Currently this driver works as long as there is only a single AMT device. */ -struct pci_dev *mei_device; - -/* mei_pci_tbl - PCI Device ID Table */ -static DEFINE_PCI_DEVICE_TABLE(mei_pci_tbl) = { - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82946GZ)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G35)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82Q965)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G965)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GM965)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GME965)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q35)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82G33)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q33)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82X38)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_3200)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_6)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_7)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_8)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_9)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_10)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_1)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_2)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_3)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_4)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_1)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_2)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_3)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_4)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_IBXPK_1)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_IBXPK_2)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_CPT_1)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PBG_1)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_1)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_2)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_3)}, - - /* required last entry */ - {0, } -}; - -MODULE_DEVICE_TABLE(pci, mei_pci_tbl); - -static DEFINE_MUTEX(mei_mutex); - - -/** - * mei_clear_list - removes all callbacks associated with file - * from mei_cb_list - * - * @dev: device structure. - * @file: file structure - * @mei_cb_list: callbacks list - * - * mei_clear_list is called to clear resources associated with file - * when application calls close function or Ctrl-C was pressed - * - * returns true if callback removed from the list, false otherwise - */ -static bool mei_clear_list(struct mei_device *dev, - struct file *file, struct list_head *mei_cb_list) -{ - struct mei_cl_cb *cb_pos = NULL; - struct mei_cl_cb *cb_next = NULL; - struct file *file_temp; - bool removed = false; - - /* list all list member */ - list_for_each_entry_safe(cb_pos, cb_next, mei_cb_list, cb_list) { - file_temp = (struct file *)cb_pos->file_object; - /* check if list member associated with a file */ - if (file_temp == file) { - /* remove member from the list */ - list_del(&cb_pos->cb_list); - /* check if cb equal to current iamthif cb */ - if (dev->iamthif_current_cb == cb_pos) { - dev->iamthif_current_cb = NULL; - /* send flow control to iamthif client */ - mei_send_flow_control(dev, &dev->iamthif_cl); - } - /* free all allocated buffers */ - mei_free_cb_private(cb_pos); - cb_pos = NULL; - removed = true; - } - } - return removed; -} - -/** - * mei_clear_lists - removes all callbacks associated with file - * - * @dev: device structure - * @file: file structure - * - * mei_clear_lists is called to clear resources associated with file - * when application calls close function or Ctrl-C was pressed - * - * returns true if callback removed from the list, false otherwise - */ -static bool mei_clear_lists(struct mei_device *dev, struct file *file) -{ - bool removed = false; - - /* remove callbacks associated with a file */ - mei_clear_list(dev, file, &dev->amthi_cmd_list.mei_cb.cb_list); - if (mei_clear_list(dev, file, - &dev->amthi_read_complete_list.mei_cb.cb_list)) - removed = true; - - mei_clear_list(dev, file, &dev->ctrl_rd_list.mei_cb.cb_list); - - if (mei_clear_list(dev, file, &dev->ctrl_wr_list.mei_cb.cb_list)) - removed = true; - - if (mei_clear_list(dev, file, &dev->write_waiting_list.mei_cb.cb_list)) - removed = true; - - if (mei_clear_list(dev, file, &dev->write_list.mei_cb.cb_list)) - removed = true; - - /* check if iamthif_current_cb not NULL */ - if (dev->iamthif_current_cb && !removed) { - /* check file and iamthif current cb association */ - if (dev->iamthif_current_cb->file_object == file) { - /* remove cb */ - mei_free_cb_private(dev->iamthif_current_cb); - dev->iamthif_current_cb = NULL; - removed = true; - } - } - return removed; -} -/** - * find_read_list_entry - find read list entry - * - * @dev: device structure - * @file: pointer to file structure - * - * returns cb on success, NULL on error - */ -static struct mei_cl_cb *find_read_list_entry( - struct mei_device *dev, - struct mei_cl *cl) -{ - struct mei_cl_cb *pos = NULL; - struct mei_cl_cb *next = NULL; - - dev_dbg(&dev->pdev->dev, "remove read_list CB\n"); - list_for_each_entry_safe(pos, next, - &dev->read_list.mei_cb.cb_list, cb_list) { - struct mei_cl *cl_temp; - cl_temp = (struct mei_cl *)pos->file_private; - - if (mei_cl_cmp_id(cl, cl_temp)) - return pos; - } - return NULL; -} - -/** - * mei_open - the open function - * - * @inode: pointer to inode structure - * @file: pointer to file structure - * - * returns 0 on success, <0 on error - */ -static int mei_open(struct inode *inode, struct file *file) -{ - struct mei_cl *cl; - struct mei_device *dev; - unsigned long cl_id; - int err; - - err = -ENODEV; - if (!mei_device) - goto out; - - dev = pci_get_drvdata(mei_device); - if (!dev) - goto out; - - mutex_lock(&dev->device_lock); - err = -ENOMEM; - cl = mei_cl_allocate(dev); - if (!cl) - goto out_unlock; - - err = -ENODEV; - if (dev->mei_state != MEI_ENABLED) { - dev_dbg(&dev->pdev->dev, "mei_state != MEI_ENABLED mei_state= %d\n", - dev->mei_state); - goto out_unlock; - } - err = -EMFILE; - if (dev->open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT) - goto out_unlock; - - cl_id = find_first_zero_bit(dev->host_clients_map, MEI_CLIENTS_MAX); - if (cl_id >= MEI_CLIENTS_MAX) - goto out_unlock; - - cl->host_client_id = cl_id; - - dev_dbg(&dev->pdev->dev, "client_id = %d\n", cl->host_client_id); - - dev->open_handle_count++; - - list_add_tail(&cl->link, &dev->file_list); - - set_bit(cl->host_client_id, dev->host_clients_map); - cl->state = MEI_FILE_INITIALIZING; - cl->sm_state = 0; - - file->private_data = cl; - mutex_unlock(&dev->device_lock); - - return nonseekable_open(inode, file); - -out_unlock: - mutex_unlock(&dev->device_lock); - kfree(cl); -out: - return err; -} - -/** - * mei_release - the release function - * - * @inode: pointer to inode structure - * @file: pointer to file structure - * - * returns 0 on success, <0 on error - */ -static int mei_release(struct inode *inode, struct file *file) -{ - struct mei_cl *cl = file->private_data; - struct mei_cl_cb *cb; - struct mei_device *dev; - int rets = 0; - - if (WARN_ON(!cl || !cl->dev)) - return -ENODEV; - - dev = cl->dev; - - mutex_lock(&dev->device_lock); - if (cl != &dev->iamthif_cl) { - if (cl->state == MEI_FILE_CONNECTED) { - cl->state = MEI_FILE_DISCONNECTING; - dev_dbg(&dev->pdev->dev, - "disconnecting client host client = %d, " - "ME client = %d\n", - cl->host_client_id, - cl->me_client_id); - rets = mei_disconnect_host_client(dev, cl); - } - mei_cl_flush_queues(cl); - dev_dbg(&dev->pdev->dev, "remove client host client = %d, ME client = %d\n", - cl->host_client_id, - cl->me_client_id); - - if (dev->open_handle_count > 0) { - clear_bit(cl->host_client_id, dev->host_clients_map); - dev->open_handle_count--; - } - mei_remove_client_from_file_list(dev, cl->host_client_id); - - /* free read cb */ - cb = NULL; - if (cl->read_cb) { - cb = find_read_list_entry(dev, cl); - /* Remove entry from read list */ - if (cb) - list_del(&cb->cb_list); - - cb = cl->read_cb; - cl->read_cb = NULL; - } - - file->private_data = NULL; - - if (cb) { - mei_free_cb_private(cb); - cb = NULL; - } - - kfree(cl); - } else { - if (dev->open_handle_count > 0) - dev->open_handle_count--; - - if (dev->iamthif_file_object == file && - dev->iamthif_state != MEI_IAMTHIF_IDLE) { - - dev_dbg(&dev->pdev->dev, "amthi canceled iamthif state %d\n", - dev->iamthif_state); - dev->iamthif_canceled = true; - if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE) { - dev_dbg(&dev->pdev->dev, "run next amthi iamthif cb\n"); - mei_run_next_iamthif_cmd(dev); - } - } - - if (mei_clear_lists(dev, file)) - dev->iamthif_state = MEI_IAMTHIF_IDLE; - - } - mutex_unlock(&dev->device_lock); - return rets; -} - - -/** - * mei_read - the read function. - * - * @file: pointer to file structure - * @ubuf: pointer to user buffer - * @length: buffer length - * @offset: data offset in buffer - * - * returns >=0 data length on success , <0 on error - */ -static ssize_t mei_read(struct file *file, char __user *ubuf, - size_t length, loff_t *offset) -{ - struct mei_cl *cl = file->private_data; - struct mei_cl_cb *cb_pos = NULL; - struct mei_cl_cb *cb = NULL; - struct mei_device *dev; - int i; - int rets; - int err; - - - if (WARN_ON(!cl || !cl->dev)) - return -ENODEV; - - dev = cl->dev; - - mutex_lock(&dev->device_lock); - if (dev->mei_state != MEI_ENABLED) { - rets = -ENODEV; - goto out; - } - - if ((cl->sm_state & MEI_WD_STATE_INDEPENDENCE_MSG_SENT) == 0) { - /* Do not allow to read watchdog client */ - i = mei_find_me_client_index(dev, mei_wd_guid); - if (i >= 0) { - struct mei_me_client *me_client = &dev->me_clients[i]; - - if (cl->me_client_id == me_client->client_id) { - rets = -EBADF; - goto out; - } - } - } else { - cl->sm_state &= ~MEI_WD_STATE_INDEPENDENCE_MSG_SENT; - } - - if (cl == &dev->iamthif_cl) { - rets = amthi_read(dev, file, ubuf, length, offset); - goto out; - } - - if (cl->read_cb && cl->read_cb->information > *offset) { - cb = cl->read_cb; - goto copy_buffer; - } else if (cl->read_cb && cl->read_cb->information > 0 && - cl->read_cb->information <= *offset) { - cb = cl->read_cb; - rets = 0; - goto free; - } else if ((!cl->read_cb || !cl->read_cb->information) && - *offset > 0) { - /*Offset needs to be cleaned for contiguous reads*/ - *offset = 0; - rets = 0; - goto out; - } - - err = mei_start_read(dev, cl); - if (err && err != -EBUSY) { - dev_dbg(&dev->pdev->dev, - "mei start read failure with status = %d\n", err); - rets = err; - goto out; - } - - if (MEI_READ_COMPLETE != cl->reading_state && - !waitqueue_active(&cl->rx_wait)) { - if (file->f_flags & O_NONBLOCK) { - rets = -EAGAIN; - goto out; - } - - mutex_unlock(&dev->device_lock); - - if (wait_event_interruptible(cl->rx_wait, - (MEI_READ_COMPLETE == cl->reading_state || - MEI_FILE_INITIALIZING == cl->state || - MEI_FILE_DISCONNECTED == cl->state || - MEI_FILE_DISCONNECTING == cl->state))) { - if (signal_pending(current)) - return -EINTR; - return -ERESTARTSYS; - } - - mutex_lock(&dev->device_lock); - if (MEI_FILE_INITIALIZING == cl->state || - MEI_FILE_DISCONNECTED == cl->state || - MEI_FILE_DISCONNECTING == cl->state) { - rets = -EBUSY; - goto out; - } - } - - cb = cl->read_cb; - - if (!cb) { - rets = -ENODEV; - goto out; - } - if (cl->reading_state != MEI_READ_COMPLETE) { - rets = 0; - goto out; - } - /* now copy the data to user space */ -copy_buffer: - dev_dbg(&dev->pdev->dev, "cb->response_buffer size - %d\n", - cb->response_buffer.size); - dev_dbg(&dev->pdev->dev, "cb->information - %lu\n", - cb->information); - if (length == 0 || ubuf == NULL || *offset > cb->information) { - rets = -EMSGSIZE; - goto free; - } - - /* length is being truncated to PAGE_SIZE, however, */ - /* information size may be longer */ - length = min_t(size_t, length, (cb->information - *offset)); - - if (copy_to_user(ubuf, cb->response_buffer.data + *offset, length)) { - rets = -EFAULT; - goto free; - } - - rets = length; - *offset += length; - if ((unsigned long)*offset < cb->information) - goto out; - -free: - cb_pos = find_read_list_entry(dev, cl); - /* Remove entry from read list */ - if (cb_pos) - list_del(&cb_pos->cb_list); - mei_free_cb_private(cb); - cl->reading_state = MEI_IDLE; - cl->read_cb = NULL; - cl->read_pending = 0; -out: - dev_dbg(&dev->pdev->dev, "end mei read rets= %d\n", rets); - mutex_unlock(&dev->device_lock); - return rets; -} - -/** - * mei_write - the write function. - * - * @file: pointer to file structure - * @ubuf: pointer to user buffer - * @length: buffer length - * @offset: data offset in buffer - * - * returns >=0 data length on success , <0 on error - */ -static ssize_t mei_write(struct file *file, const char __user *ubuf, - size_t length, loff_t *offset) -{ - struct mei_cl *cl = file->private_data; - struct mei_cl_cb *write_cb = NULL; - struct mei_msg_hdr mei_hdr; - struct mei_device *dev; - unsigned long timeout = 0; - int rets; - int i; - - if (WARN_ON(!cl || !cl->dev)) - return -ENODEV; - - dev = cl->dev; - - mutex_lock(&dev->device_lock); - - if (dev->mei_state != MEI_ENABLED) { - mutex_unlock(&dev->device_lock); - return -ENODEV; - } - - if (cl == &dev->iamthif_cl) { - write_cb = find_amthi_read_list_entry(dev, file); - - if (write_cb) { - timeout = write_cb->read_time + - msecs_to_jiffies(IAMTHIF_READ_TIMER); - - if (time_after(jiffies, timeout) || - cl->reading_state == MEI_READ_COMPLETE) { - *offset = 0; - list_del(&write_cb->cb_list); - mei_free_cb_private(write_cb); - write_cb = NULL; - } - } - } - - /* free entry used in read */ - if (cl->reading_state == MEI_READ_COMPLETE) { - *offset = 0; - write_cb = find_read_list_entry(dev, cl); - if (write_cb) { - list_del(&write_cb->cb_list); - mei_free_cb_private(write_cb); - write_cb = NULL; - cl->reading_state = MEI_IDLE; - cl->read_cb = NULL; - cl->read_pending = 0; - } - } else if (cl->reading_state == MEI_IDLE && !cl->read_pending) - *offset = 0; - - - write_cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); - if (!write_cb) { - mutex_unlock(&dev->device_lock); - return -ENOMEM; - } - - write_cb->file_object = file; - write_cb->file_private = cl; - write_cb->request_buffer.data = kmalloc(length, GFP_KERNEL); - rets = -ENOMEM; - if (!write_cb->request_buffer.data) - goto unlock_dev; - - dev_dbg(&dev->pdev->dev, "length =%d\n", (int) length); - - rets = -EFAULT; - if (copy_from_user(write_cb->request_buffer.data, ubuf, length)) - goto unlock_dev; - - cl->sm_state = 0; - if (length == 4 && - ((memcmp(mei_wd_state_independence_msg[0], - write_cb->request_buffer.data, 4) == 0) || - (memcmp(mei_wd_state_independence_msg[1], - write_cb->request_buffer.data, 4) == 0) || - (memcmp(mei_wd_state_independence_msg[2], - write_cb->request_buffer.data, 4) == 0))) - cl->sm_state |= MEI_WD_STATE_INDEPENDENCE_MSG_SENT; - - INIT_LIST_HEAD(&write_cb->cb_list); - if (cl == &dev->iamthif_cl) { - write_cb->response_buffer.data = - kmalloc(dev->iamthif_mtu, GFP_KERNEL); - if (!write_cb->response_buffer.data) { - rets = -ENOMEM; - goto unlock_dev; - } - if (dev->mei_state != MEI_ENABLED) { - rets = -ENODEV; - goto unlock_dev; - } - for (i = 0; i < dev->me_clients_num; i++) { - if (dev->me_clients[i].client_id == - dev->iamthif_cl.me_client_id) - break; - } - - if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id)) { - rets = -ENODEV; - goto unlock_dev; - } - if (i == dev->me_clients_num || - (dev->me_clients[i].client_id != - dev->iamthif_cl.me_client_id)) { - rets = -ENODEV; - goto unlock_dev; - } else if (length > dev->me_clients[i].props.max_msg_length || - length <= 0) { - rets = -EMSGSIZE; - goto unlock_dev; - } - - write_cb->response_buffer.size = dev->iamthif_mtu; - write_cb->major_file_operations = MEI_IOCTL; - write_cb->information = 0; - write_cb->request_buffer.size = length; - if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) { - rets = -ENODEV; - goto unlock_dev; - } - - if (!list_empty(&dev->amthi_cmd_list.mei_cb.cb_list) || - dev->iamthif_state != MEI_IAMTHIF_IDLE) { - dev_dbg(&dev->pdev->dev, "amthi_state = %d\n", - (int) dev->iamthif_state); - dev_dbg(&dev->pdev->dev, "add amthi cb to amthi cmd waiting list\n"); - list_add_tail(&write_cb->cb_list, - &dev->amthi_cmd_list.mei_cb.cb_list); - rets = length; - } else { - dev_dbg(&dev->pdev->dev, "call amthi write\n"); - rets = amthi_write(dev, write_cb); - - if (rets) { - dev_dbg(&dev->pdev->dev, "amthi write failed with status = %d\n", - rets); - goto unlock_dev; - } - rets = length; - } - mutex_unlock(&dev->device_lock); - return rets; - } - - write_cb->major_file_operations = MEI_WRITE; - /* make sure information is zero before we start */ - - write_cb->information = 0; - write_cb->request_buffer.size = length; - - dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n", - cl->host_client_id, cl->me_client_id); - if (cl->state != MEI_FILE_CONNECTED) { - rets = -ENODEV; - dev_dbg(&dev->pdev->dev, "host client = %d, is not connected to ME client = %d", - cl->host_client_id, - cl->me_client_id); - goto unlock_dev; - } - for (i = 0; i < dev->me_clients_num; i++) { - if (dev->me_clients[i].client_id == - cl->me_client_id) - break; - } - if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id)) { - rets = -ENODEV; - goto unlock_dev; - } - if (i == dev->me_clients_num) { - rets = -ENODEV; - goto unlock_dev; - } - if (length > dev->me_clients[i].props.max_msg_length || length <= 0) { - rets = -EINVAL; - goto unlock_dev; - } - write_cb->file_private = cl; - - rets = mei_flow_ctrl_creds(dev, cl); - if (rets < 0) - goto unlock_dev; - - if (rets && dev->mei_host_buffer_is_empty) { - rets = 0; - dev->mei_host_buffer_is_empty = false; - if (length > ((((dev->host_hw_state & H_CBD) >> 24) * - sizeof(u32)) - sizeof(struct mei_msg_hdr))) { - - mei_hdr.length = - (((dev->host_hw_state & H_CBD) >> 24) * - sizeof(u32)) - - sizeof(struct mei_msg_hdr); - mei_hdr.msg_complete = 0; - } else { - mei_hdr.length = length; - mei_hdr.msg_complete = 1; - } - mei_hdr.host_addr = cl->host_client_id; - mei_hdr.me_addr = cl->me_client_id; - mei_hdr.reserved = 0; - dev_dbg(&dev->pdev->dev, "call mei_write_message header=%08x.\n", - *((u32 *) &mei_hdr)); - if (mei_write_message(dev, &mei_hdr, - (unsigned char *) (write_cb->request_buffer.data), - mei_hdr.length)) { - rets = -ENODEV; - goto unlock_dev; - } - cl->writing_state = MEI_WRITING; - write_cb->information = mei_hdr.length; - if (mei_hdr.msg_complete) { - if (mei_flow_ctrl_reduce(dev, cl)) { - rets = -ENODEV; - goto unlock_dev; - } - list_add_tail(&write_cb->cb_list, - &dev->write_waiting_list.mei_cb.cb_list); - } else { - list_add_tail(&write_cb->cb_list, - &dev->write_list.mei_cb.cb_list); - } - - } else { - - write_cb->information = 0; - cl->writing_state = MEI_WRITING; - list_add_tail(&write_cb->cb_list, - &dev->write_list.mei_cb.cb_list); - } - mutex_unlock(&dev->device_lock); - return length; - -unlock_dev: - mutex_unlock(&dev->device_lock); - mei_free_cb_private(write_cb); - return rets; -} - - -/** - * mei_ioctl - the IOCTL function - * - * @file: pointer to file structure - * @cmd: ioctl command - * @data: pointer to mei message structure - * - * returns 0 on success , <0 on error - */ -static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data) -{ - struct mei_device *dev; - struct mei_cl *cl = file->private_data; - struct mei_connect_client_data *connect_data = NULL; - int rets; - - if (cmd != IOCTL_MEI_CONNECT_CLIENT) - return -EINVAL; - - if (WARN_ON(!cl || !cl->dev)) - return -ENODEV; - - dev = cl->dev; - - dev_dbg(&dev->pdev->dev, "IOCTL cmd = 0x%x", cmd); - - mutex_lock(&dev->device_lock); - if (dev->mei_state != MEI_ENABLED) { - rets = -ENODEV; - goto out; - } - - dev_dbg(&dev->pdev->dev, ": IOCTL_MEI_CONNECT_CLIENT.\n"); - - connect_data = kzalloc(sizeof(struct mei_connect_client_data), - GFP_KERNEL); - if (!connect_data) { - rets = -ENOMEM; - goto out; - } - dev_dbg(&dev->pdev->dev, "copy connect data from user\n"); - if (copy_from_user(connect_data, (char __user *)data, - sizeof(struct mei_connect_client_data))) { - dev_dbg(&dev->pdev->dev, "failed to copy data from userland\n"); - rets = -EFAULT; - goto out; - } - rets = mei_ioctl_connect_client(file, connect_data); - - /* if all is ok, copying the data back to user. */ - if (rets) - goto out; - - dev_dbg(&dev->pdev->dev, "copy connect data to user\n"); - if (copy_to_user((char __user *)data, connect_data, - sizeof(struct mei_connect_client_data))) { - dev_dbg(&dev->pdev->dev, "failed to copy data to userland\n"); - rets = -EFAULT; - goto out; - } - -out: - kfree(connect_data); - mutex_unlock(&dev->device_lock); - return rets; -} - -/** - * mei_compat_ioctl - the compat IOCTL function - * - * @file: pointer to file structure - * @cmd: ioctl command - * @data: pointer to mei message structure - * - * returns 0 on success , <0 on error - */ -#ifdef CONFIG_COMPAT -static long mei_compat_ioctl(struct file *file, - unsigned int cmd, unsigned long data) -{ - return mei_ioctl(file, cmd, (unsigned long)compat_ptr(data)); -} -#endif - - -/** - * mei_poll - the poll function - * - * @file: pointer to file structure - * @wait: pointer to poll_table structure - * - * returns poll mask - */ -static unsigned int mei_poll(struct file *file, poll_table *wait) -{ - struct mei_cl *cl = file->private_data; - struct mei_device *dev; - unsigned int mask = 0; - - if (WARN_ON(!cl || !cl->dev)) - return mask; - - dev = cl->dev; - - mutex_lock(&dev->device_lock); - - if (dev->mei_state != MEI_ENABLED) - goto out; - - - if (cl == &dev->iamthif_cl) { - mutex_unlock(&dev->device_lock); - poll_wait(file, &dev->iamthif_cl.wait, wait); - mutex_lock(&dev->device_lock); - if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE && - dev->iamthif_file_object == file) { - mask |= (POLLIN | POLLRDNORM); - dev_dbg(&dev->pdev->dev, "run next amthi cb\n"); - mei_run_next_iamthif_cmd(dev); - } - goto out; - } - - mutex_unlock(&dev->device_lock); - poll_wait(file, &cl->tx_wait, wait); - mutex_lock(&dev->device_lock); - if (MEI_WRITE_COMPLETE == cl->writing_state) - mask |= (POLLIN | POLLRDNORM); - -out: - mutex_unlock(&dev->device_lock); - return mask; -} - -/* - * file operations structure will be used for mei char device. - */ -static const struct file_operations mei_fops = { - .owner = THIS_MODULE, - .read = mei_read, - .unlocked_ioctl = mei_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = mei_compat_ioctl, -#endif - .open = mei_open, - .release = mei_release, - .write = mei_write, - .poll = mei_poll, - .llseek = no_llseek -}; - - -/* - * Misc Device Struct - */ -static struct miscdevice mei_misc_device = { - .name = "mei", - .fops = &mei_fops, - .minor = MISC_DYNAMIC_MINOR, -}; - -/** - * mei_probe - Device Initialization Routine - * - * @pdev: PCI device structure - * @ent: entry in kcs_pci_tbl - * - * returns 0 on success, <0 on failure. - */ -static int __devinit mei_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct mei_device *dev; - int err; - - mutex_lock(&mei_mutex); - if (mei_device) { - err = -EEXIST; - goto end; - } - /* enable pci dev */ - err = pci_enable_device(pdev); - if (err) { - printk(KERN_ERR "mei: Failed to enable pci device.\n"); - goto end; - } - /* set PCI host mastering */ - pci_set_master(pdev); - /* pci request regions for mei driver */ - err = pci_request_regions(pdev, mei_driver_name); - if (err) { - printk(KERN_ERR "mei: Failed to get pci regions.\n"); - goto disable_device; - } - /* allocates and initializes the mei dev structure */ - dev = mei_device_init(pdev); - if (!dev) { - err = -ENOMEM; - goto release_regions; - } - /* mapping IO device memory */ - dev->mem_addr = pci_iomap(pdev, 0, 0); - if (!dev->mem_addr) { - printk(KERN_ERR "mei: mapping I/O device memory failure.\n"); - err = -ENOMEM; - goto free_device; - } - pci_enable_msi(pdev); - - /* request and enable interrupt */ - if (pci_dev_msi_enabled(pdev)) - err = request_threaded_irq(pdev->irq, - NULL, - mei_interrupt_thread_handler, - 0, mei_driver_name, dev); - else - err = request_threaded_irq(pdev->irq, - mei_interrupt_quick_handler, - mei_interrupt_thread_handler, - IRQF_SHARED, mei_driver_name, dev); - - if (err) { - printk(KERN_ERR "mei: request_threaded_irq failure. irq = %d\n", - pdev->irq); - goto unmap_memory; - } - INIT_DELAYED_WORK(&dev->timer_work, mei_timer); - if (mei_hw_init(dev)) { - printk(KERN_ERR "mei: Init hw failure.\n"); - err = -ENODEV; - goto release_irq; - } - - err = misc_register(&mei_misc_device); - if (err) - goto release_irq; - - mei_device = pdev; - pci_set_drvdata(pdev, dev); - - - schedule_delayed_work(&dev->timer_work, HZ); - - mutex_unlock(&mei_mutex); - - pr_debug("initialization successful.\n"); - - return 0; - -release_irq: - /* disable interrupts */ - dev->host_hw_state = mei_hcsr_read(dev); - mei_disable_interrupts(dev); - flush_scheduled_work(); - free_irq(pdev->irq, dev); - pci_disable_msi(pdev); -unmap_memory: - pci_iounmap(pdev, dev->mem_addr); -free_device: - kfree(dev); -release_regions: - pci_release_regions(pdev); -disable_device: - pci_disable_device(pdev); -end: - mutex_unlock(&mei_mutex); - printk(KERN_ERR "mei: Driver initialization failed.\n"); - return err; -} - -/** - * mei_remove - Device Removal Routine - * - * @pdev: PCI device structure - * - * mei_remove is called by the PCI subsystem to alert the driver - * that it should release a PCI device. - */ -static void __devexit mei_remove(struct pci_dev *pdev) -{ - struct mei_device *dev; - - if (mei_device != pdev) - return; - - dev = pci_get_drvdata(pdev); - if (!dev) - return; - - mutex_lock(&dev->device_lock); - - mei_wd_stop(dev, false); - - mei_device = NULL; - - if (dev->iamthif_cl.state == MEI_FILE_CONNECTED) { - dev->iamthif_cl.state = MEI_FILE_DISCONNECTING; - mei_disconnect_host_client(dev, &dev->iamthif_cl); - } - if (dev->wd_cl.state == MEI_FILE_CONNECTED) { - dev->wd_cl.state = MEI_FILE_DISCONNECTING; - mei_disconnect_host_client(dev, &dev->wd_cl); - } - - /* Unregistering watchdog device */ - mei_watchdog_unregister(dev); - - /* remove entry if already in list */ - dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n"); - mei_remove_client_from_file_list(dev, dev->wd_cl.host_client_id); - mei_remove_client_from_file_list(dev, dev->iamthif_cl.host_client_id); - - dev->iamthif_current_cb = NULL; - dev->me_clients_num = 0; - - mutex_unlock(&dev->device_lock); - - flush_scheduled_work(); - - /* disable interrupts */ - mei_disable_interrupts(dev); - - free_irq(pdev->irq, dev); - pci_disable_msi(pdev); - pci_set_drvdata(pdev, NULL); - - if (dev->mem_addr) - pci_iounmap(pdev, dev->mem_addr); - - kfree(dev); - - pci_release_regions(pdev); - pci_disable_device(pdev); -} -#ifdef CONFIG_PM -static int mei_pci_suspend(struct device *device) -{ - struct pci_dev *pdev = to_pci_dev(device); - struct mei_device *dev = pci_get_drvdata(pdev); - int err; - - if (!dev) - return -ENODEV; - mutex_lock(&dev->device_lock); - /* Stop watchdog if exists */ - err = mei_wd_stop(dev, true); - /* Set new mei state */ - if (dev->mei_state == MEI_ENABLED || - dev->mei_state == MEI_RECOVERING_FROM_RESET) { - dev->mei_state = MEI_POWER_DOWN; - mei_reset(dev, 0); - } - mutex_unlock(&dev->device_lock); - - free_irq(pdev->irq, dev); - pci_disable_msi(pdev); - - return err; -} - -static int mei_pci_resume(struct device *device) -{ - struct pci_dev *pdev = to_pci_dev(device); - struct mei_device *dev; - int err; - - dev = pci_get_drvdata(pdev); - if (!dev) - return -ENODEV; - - pci_enable_msi(pdev); - - /* request and enable interrupt */ - if (pci_dev_msi_enabled(pdev)) - err = request_threaded_irq(pdev->irq, - NULL, - mei_interrupt_thread_handler, - 0, mei_driver_name, dev); - else - err = request_threaded_irq(pdev->irq, - mei_interrupt_quick_handler, - mei_interrupt_thread_handler, - IRQF_SHARED, mei_driver_name, dev); - - if (err) { - printk(KERN_ERR "mei: Request_irq failure. irq = %d\n", - pdev->irq); - return err; - } - - mutex_lock(&dev->device_lock); - dev->mei_state = MEI_POWER_UP; - mei_reset(dev, 1); - mutex_unlock(&dev->device_lock); - - /* Start timer if stopped in suspend */ - schedule_delayed_work(&dev->timer_work, HZ); - - return err; -} -static SIMPLE_DEV_PM_OPS(mei_pm_ops, mei_pci_suspend, mei_pci_resume); -#define MEI_PM_OPS (&mei_pm_ops) -#else -#define MEI_PM_OPS NULL -#endif /* CONFIG_PM */ -/* - * PCI driver structure - */ -static struct pci_driver mei_driver = { - .name = mei_driver_name, - .id_table = mei_pci_tbl, - .probe = mei_probe, - .remove = __devexit_p(mei_remove), - .shutdown = __devexit_p(mei_remove), - .driver.pm = MEI_PM_OPS, -}; - -/** - * mei_init_module - Driver Registration Routine - * - * mei_init_module is the first routine called when the driver is - * loaded. All it does is to register with the PCI subsystem. - * - * returns 0 on success, <0 on failure. - */ -static int __init mei_init_module(void) -{ - int ret; - - pr_debug("loading.\n"); - /* init pci module */ - ret = pci_register_driver(&mei_driver); - if (ret < 0) - printk(KERN_ERR "mei: Error registering driver.\n"); - - return ret; -} - -module_init(mei_init_module); - -/** - * mei_exit_module - Driver Exit Cleanup Routine - * - * mei_exit_module is called just before the driver is removed - * from memory. - */ -static void __exit mei_exit_module(void) -{ - misc_deregister(&mei_misc_device); - pci_unregister_driver(&mei_driver); - - pr_debug("unloaded successfully.\n"); -} - -module_exit(mei_exit_module); - - -MODULE_AUTHOR("Intel Corporation"); -MODULE_DESCRIPTION("Intel(R) Management Engine Interface"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/mei/mei-amt-version.c b/drivers/staging/mei/mei-amt-version.c deleted file mode 100644 index ac2a507..0000000 --- a/drivers/staging/mei/mei-amt-version.c +++ /dev/null @@ -1,481 +0,0 @@ -/****************************************************************************** - * Intel Management Engine Interface (Intel MEI) Linux driver - * Intel MEI Interface Header - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2012 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Corporation. - * linux-mei@linux.intel.com - * http://www.intel.com - * - * BSD LICENSE - * - * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "mei.h" - -/***************************************************************************** - * Intel Management Engine Interface - *****************************************************************************/ - -#define mei_msg(_me, fmt, ARGS...) do { \ - if (_me->verbose) \ - fprintf(stderr, fmt, ##ARGS); \ -} while (0) - -#define mei_err(_me, fmt, ARGS...) do { \ - fprintf(stderr, "Error: " fmt, ##ARGS); \ -} while (0) - -struct mei { - uuid_le guid; - bool initialized; - bool verbose; - unsigned int buf_size; - unsigned char prot_ver; - int fd; -}; - -static void mei_deinit(struct mei *cl) -{ - if (cl->fd != -1) - close(cl->fd); - cl->fd = -1; - cl->buf_size = 0; - cl->prot_ver = 0; - cl->initialized = false; -} - -static bool mei_init(struct mei *me, const uuid_le *guid, - unsigned char req_protocol_version, bool verbose) -{ - int result; - struct mei_client *cl; - struct mei_connect_client_data data; - - mei_deinit(me); - - me->verbose = verbose; - - me->fd = open("/dev/mei", O_RDWR); - if (me->fd == -1) { - mei_err(me, "Cannot establish a handle to the Intel MEI driver\n"); - goto err; - } - memcpy(&me->guid, guid, sizeof(*guid)); - memset(&data, 0, sizeof(data)); - me->initialized = true; - - memcpy(&data.in_client_uuid, &me->guid, sizeof(me->guid)); - result = ioctl(me->fd, IOCTL_MEI_CONNECT_CLIENT, &data); - if (result) { - mei_err(me, "IOCTL_MEI_CONNECT_CLIENT receive message. err=%d\n", result); - goto err; - } - cl = &data.out_client_properties; - mei_msg(me, "max_message_length %d\n", cl->max_msg_length); - mei_msg(me, "protocol_version %d\n", cl->protocol_version); - - if ((req_protocol_version > 0) && - (cl->protocol_version != req_protocol_version)) { - mei_err(me, "Intel MEI protocol version not supported\n"); - goto err; - } - - me->buf_size = cl->max_msg_length; - me->prot_ver = cl->protocol_version; - - return true; -err: - mei_deinit(me); - return false; -} - -static ssize_t mei_recv_msg(struct mei *me, unsigned char *buffer, - ssize_t len, unsigned long timeout) -{ - ssize_t rc; - - mei_msg(me, "call read length = %zd\n", len); - - rc = read(me->fd, buffer, len); - if (rc < 0) { - mei_err(me, "read failed with status %zd %s\n", - rc, strerror(errno)); - mei_deinit(me); - } else { - mei_msg(me, "read succeeded with result %zd\n", rc); - } - return rc; -} - -static ssize_t mei_send_msg(struct mei *me, const unsigned char *buffer, - ssize_t len, unsigned long timeout) -{ - struct timeval tv; - ssize_t written; - ssize_t rc; - fd_set set; - - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000000; - - mei_msg(me, "call write length = %zd\n", len); - - written = write(me->fd, buffer, len); - if (written < 0) { - rc = -errno; - mei_err(me, "write failed with status %zd %s\n", - written, strerror(errno)); - goto out; - } - - FD_ZERO(&set); - FD_SET(me->fd, &set); - rc = select(me->fd + 1 , &set, NULL, NULL, &tv); - if (rc > 0 && FD_ISSET(me->fd, &set)) { - mei_msg(me, "write success\n"); - } else if (rc == 0) { - mei_err(me, "write failed on timeout with status\n"); - goto out; - } else { /* rc < 0 */ - mei_err(me, "write failed on select with status %zd\n", rc); - goto out; - } - - rc = written; -out: - if (rc < 0) - mei_deinit(me); - - return rc; -} - -/*************************************************************************** - * Intel Advanced Management Technolgy ME Client - ***************************************************************************/ - -#define AMT_MAJOR_VERSION 1 -#define AMT_MINOR_VERSION 1 - -#define AMT_STATUS_SUCCESS 0x0 -#define AMT_STATUS_INTERNAL_ERROR 0x1 -#define AMT_STATUS_NOT_READY 0x2 -#define AMT_STATUS_INVALID_AMT_MODE 0x3 -#define AMT_STATUS_INVALID_MESSAGE_LENGTH 0x4 - -#define AMT_STATUS_HOST_IF_EMPTY_RESPONSE 0x4000 -#define AMT_STATUS_SDK_RESOURCES 0x1004 - - -#define AMT_BIOS_VERSION_LEN 65 -#define AMT_VERSIONS_NUMBER 50 -#define AMT_UNICODE_STRING_LEN 20 - -struct amt_unicode_string { - uint16_t length; - char string[AMT_UNICODE_STRING_LEN]; -} __attribute__((packed)); - -struct amt_version_type { - struct amt_unicode_string description; - struct amt_unicode_string version; -} __attribute__((packed)); - -struct amt_version { - uint8_t major; - uint8_t minor; -} __attribute__((packed)); - -struct amt_code_versions { - uint8_t bios[AMT_BIOS_VERSION_LEN]; - uint32_t count; - struct amt_version_type versions[AMT_VERSIONS_NUMBER]; -} __attribute__((packed)); - -/*************************************************************************** - * Intel Advanced Management Technolgy Host Interface - ***************************************************************************/ - -struct amt_host_if_msg_header { - struct amt_version version; - uint16_t _reserved; - uint32_t command; - uint32_t length; -} __attribute__((packed)); - -struct amt_host_if_resp_header { - struct amt_host_if_msg_header header; - uint32_t status; - unsigned char data[0]; -} __attribute__((packed)); - -const uuid_le MEI_IAMTHIF = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, \ - 0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, 0x81, 0x4c); - -#define AMT_HOST_IF_CODE_VERSIONS_REQUEST 0x0400001A -#define AMT_HOST_IF_CODE_VERSIONS_RESPONSE 0x0480001A - -const struct amt_host_if_msg_header CODE_VERSION_REQ = { - .version = {AMT_MAJOR_VERSION, AMT_MINOR_VERSION}, - ._reserved = 0, - .command = AMT_HOST_IF_CODE_VERSIONS_REQUEST, - .length = 0 -}; - - -struct amt_host_if { - struct mei mei_cl; - unsigned long send_timeout; - bool initialized; -}; - - -static bool amt_host_if_init(struct amt_host_if *acmd, - unsigned long send_timeout, bool verbose) -{ - acmd->send_timeout = (send_timeout) ? send_timeout : 20000; - acmd->initialized = mei_init(&acmd->mei_cl, &MEI_IAMTHIF, 0, verbose); - return acmd->initialized; -} - -static void amt_host_if_deinit(struct amt_host_if *acmd) -{ - mei_deinit(&acmd->mei_cl); - acmd->initialized = false; -} - -static uint32_t amt_verify_code_versions(const struct amt_host_if_resp_header *resp) -{ - uint32_t status = AMT_STATUS_SUCCESS; - struct amt_code_versions *code_ver; - size_t code_ver_len; - uint32_t ver_type_cnt; - uint32_t len; - uint32_t i; - - code_ver = (struct amt_code_versions *)resp->data; - /* length - sizeof(status) */ - code_ver_len = resp->header.length - sizeof(uint32_t); - ver_type_cnt = code_ver_len - - sizeof(code_ver->bios) - - sizeof(code_ver->count); - if (code_ver->count != ver_type_cnt / sizeof(struct amt_version_type)) { - status = AMT_STATUS_INTERNAL_ERROR; - goto out; - } - - for (i = 0; i < code_ver->count; i++) { - len = code_ver->versions[i].description.length; - - if (len > AMT_UNICODE_STRING_LEN) { - status = AMT_STATUS_INTERNAL_ERROR; - goto out; - } - - len = code_ver->versions[i].version.length; - if (code_ver->versions[i].version.string[len] != '\0' || - len != strlen(code_ver->versions[i].version.string)) { - status = AMT_STATUS_INTERNAL_ERROR; - goto out; - } - } -out: - return status; -} - -static uint32_t amt_verify_response_header(uint32_t command, - const struct amt_host_if_msg_header *resp_hdr, - uint32_t response_size) -{ - if (response_size < sizeof(struct amt_host_if_resp_header)) { - return AMT_STATUS_INTERNAL_ERROR; - } else if (response_size != (resp_hdr->length + - sizeof(struct amt_host_if_msg_header))) { - return AMT_STATUS_INTERNAL_ERROR; - } else if (resp_hdr->command != command) { - return AMT_STATUS_INTERNAL_ERROR; - } else if (resp_hdr->_reserved != 0) { - return AMT_STATUS_INTERNAL_ERROR; - } else if (resp_hdr->version.major != AMT_MAJOR_VERSION || - resp_hdr->version.minor < AMT_MINOR_VERSION) { - return AMT_STATUS_INTERNAL_ERROR; - } - return AMT_STATUS_SUCCESS; -} - -static uint32_t amt_host_if_call(struct amt_host_if *acmd, - const unsigned char *command, ssize_t command_sz, - uint8_t **read_buf, uint32_t rcmd, - unsigned int expected_sz) -{ - uint32_t in_buf_sz; - uint32_t out_buf_sz; - ssize_t written; - uint32_t status; - struct amt_host_if_resp_header *msg_hdr; - - in_buf_sz = acmd->mei_cl.buf_size; - *read_buf = (uint8_t *)malloc(sizeof(uint8_t) * in_buf_sz); - if (*read_buf == NULL) - return AMT_STATUS_SDK_RESOURCES; - memset(*read_buf, 0, in_buf_sz); - msg_hdr = (struct amt_host_if_resp_header *)*read_buf; - - written = mei_send_msg(&acmd->mei_cl, - command, command_sz, acmd->send_timeout); - if (written != command_sz) - return AMT_STATUS_INTERNAL_ERROR; - - out_buf_sz = mei_recv_msg(&acmd->mei_cl, *read_buf, in_buf_sz, 2000); - if (out_buf_sz <= 0) - return AMT_STATUS_HOST_IF_EMPTY_RESPONSE; - - status = msg_hdr->status; - if (status != AMT_STATUS_SUCCESS) - return status; - - status = amt_verify_response_header(rcmd, - &msg_hdr->header, out_buf_sz); - if (status != AMT_STATUS_SUCCESS) - return status; - - if (expected_sz && expected_sz != out_buf_sz) - return AMT_STATUS_INTERNAL_ERROR; - - return AMT_STATUS_SUCCESS; -} - - -static uint32_t amt_get_code_versions(struct amt_host_if *cmd, - struct amt_code_versions *versions) -{ - struct amt_host_if_resp_header *response = NULL; - uint32_t status; - - status = amt_host_if_call(cmd, - (const unsigned char *)&CODE_VERSION_REQ, - sizeof(CODE_VERSION_REQ), - (uint8_t **)&response, - AMT_HOST_IF_CODE_VERSIONS_RESPONSE, 0); - - if (status != AMT_STATUS_SUCCESS) - goto out; - - status = amt_verify_code_versions(response); - if (status != AMT_STATUS_SUCCESS) - goto out; - - memcpy(versions, response->data, sizeof(struct amt_code_versions)); -out: - if (response != NULL) - free(response); - - return status; -} - -/************************** end of amt_host_if_command ***********************/ -int main(int argc, char **argv) -{ - struct amt_code_versions ver; - struct amt_host_if acmd; - unsigned int i; - uint32_t status; - int ret; - bool verbose; - - verbose = (argc > 1 && strcmp(argv[1], "-v") == 0); - - if (!amt_host_if_init(&acmd, 5000, verbose)) { - ret = 1; - goto out; - } - - status = amt_get_code_versions(&acmd, &ver); - - amt_host_if_deinit(&acmd); - - switch (status) { - case AMT_STATUS_HOST_IF_EMPTY_RESPONSE: - printf("Intel AMT: DISABLED\n"); - ret = 0; - break; - case AMT_STATUS_SUCCESS: - printf("Intel AMT: ENABLED\n"); - for (i = 0; i < ver.count; i++) { - printf("%s:\t%s\n", ver.versions[i].description.string, - ver.versions[i].version.string); - } - ret = 0; - break; - default: - printf("An error has occurred\n"); - ret = 1; - break; - } - -out: - return ret; -} diff --git a/drivers/staging/mei/mei.h b/drivers/staging/mei/mei.h deleted file mode 100644 index bc0d8b6..0000000 --- a/drivers/staging/mei/mei.h +++ /dev/null @@ -1,110 +0,0 @@ -/****************************************************************************** - * Intel Management Engine Interface (Intel MEI) Linux driver - * Intel MEI Interface Header - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Corporation. - * linux-mei@linux.intel.com - * http://www.intel.com - * - * BSD LICENSE - * - * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ - -#ifndef _LINUX_MEI_H -#define _LINUX_MEI_H - -#include - -/* - * This IOCTL is used to associate the current file descriptor with a - * FW Client (given by UUID). This opens a communication channel - * between a host client and a FW client. From this point every read and write - * will communicate with the associated FW client. - * Only in close() (file_operation release()) the communication between - * the clients is disconnected - * - * The IOCTL argument is a struct with a union that contains - * the input parameter and the output parameter for this IOCTL. - * - * The input parameter is UUID of the FW Client. - * The output parameter is the properties of the FW client - * (FW protocol version and max message size). - * - */ -#define IOCTL_MEI_CONNECT_CLIENT \ - _IOWR('H' , 0x01, struct mei_connect_client_data) - -/* - * Intel MEI client information struct - */ -struct mei_client { - __u32 max_msg_length; - __u8 protocol_version; - __u8 reserved[3]; -}; - -/* - * IOCTL Connect Client Data structure - */ -struct mei_connect_client_data { - union { - uuid_le in_client_uuid; - struct mei_client out_client_properties; - }; -}; - -#endif /* _LINUX_MEI_H */ diff --git a/drivers/staging/mei/mei.txt b/drivers/staging/mei/mei.txt deleted file mode 100644 index 2785697..0000000 --- a/drivers/staging/mei/mei.txt +++ /dev/null @@ -1,215 +0,0 @@ -Intel(R) Management Engine Interface (Intel(R) MEI) -======================= - -Introduction -======================= - -The Intel Management Engine (Intel ME) is an isolated and protected computing -resource (Co-processor) residing inside certain Intel chipsets. The Intel ME -provides support for computer/IT management features. The feature set -depends on the Intel chipset SKU. - -The Intel Management Engine Interface (Intel MEI, previously known as HECI) -is the interface between the Host and Intel ME. This interface is exposed -to the host as a PCI device. The Intel MEI Driver is in charge of the -communication channel between a host application and the Intel ME feature. - -Each Intel ME feature (Intel ME Client) is addressed by a GUID/UUID and -each client has its own protocol. The protocol is message-based with a -header and payload up to 512 bytes. - -Prominent usage of the Intel ME Interface is to communicate with Intel(R) -Active Management Technology (Intel AMT)implemented in firmware running on -the Intel ME. - -Intel AMT provides the ability to manage a host remotely out-of-band (OOB) -even when the operating system running on the host processor has crashed or -is in a sleep state. - -Some examples of Intel AMT usage are: - - Monitoring hardware state and platform components - - Remote power off/on (useful for green computing or overnight IT - maintenance) - - OS updates - - Storage of useful platform information such as software assets - - Built-in hardware KVM - - Selective network isolation of Ethernet and IP protocol flows based - on policies set by a remote management console - - IDE device redirection from remote management console - -Intel AMT (OOB) communication is based on SOAP (deprecated -starting with Release 6.0) over HTTP/S or WS-Management protocol over -HTTP/S that are received from a remote management console application. - -For more information about Intel AMT: -http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide - -Intel MEI Driver -======================= - -The driver exposes a misc device called /dev/mei. - -An application maintains communication with an Intel ME feature while -/dev/mei is open. The binding to a specific features is performed by calling -MEI_CONNECT_CLIENT_IOCTL, which passes the desired UUID. -The number of instances of an Intel ME feature that can be opened -at the same time depends on the Intel ME feature, but most of the -features allow only a single instance. - -The Intel AMT Host Interface (Intel AMTHI) feature supports multiple -simultaneous user applications. Therefore, the Intel MEI driver handles -this internally by maintaining request queues for the applications. - -The driver is oblivious to data that is passed between firmware feature -and host application. - -Because some of the Intel ME features can change the system -configuration, the driver by default allows only a privileged -user to access it. - -A code snippet for an application communicating with -Intel AMTHI client: - struct mei_connect_client_data data; - fd = open(MEI_DEVICE); - - data.d.in_client_uuid = AMTHI_UUID; - - ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &data); - - printf("Ver=%d, MaxLen=%ld\n", - data.d.in_client_uuid.protocol_version, - data.d.in_client_uuid.max_msg_length); - - [...] - - write(fd, amthi_req_data, amthi_req_data_len); - - [...] - - read(fd, &amthi_res_data, amthi_res_data_len); - - [...] - close(fd); - -IOCTL: -====== -The Intel MEI Driver supports the following IOCTL command: - IOCTL_MEI_CONNECT_CLIENT Connect to firmware Feature (client). - - usage: - struct mei_connect_client_data clientData; - ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &clientData); - - inputs: - mei_connect_client_data struct contain the following - input field: - - in_client_uuid - UUID of the FW Feature that needs - to connect to. - outputs: - out_client_properties - Client Properties: MTU and Protocol Version. - - error returns: - EINVAL Wrong IOCTL Number - ENODEV Device or Connection is not initialized or ready. - (e.g. Wrong UUID) - ENOMEM Unable to allocate memory to client internal data. - EFAULT Fatal Error (e.g. Unable to access user input data) - EBUSY Connection Already Open - - Notes: - max_msg_length (MTU) in client properties describes the maximum - data that can be sent or received. (e.g. if MTU=2K, can send - requests up to bytes 2k and received responses upto 2k bytes). - -Intel ME Applications: -============== - -1) Intel Local Management Service (Intel LMS) - - Applications running locally on the platform communicate with Intel AMT Release - 2.0 and later releases in the same way that network applications do via SOAP - over HTTP (deprecated starting with Release 6.0) or with WS-Management over - SOAP over HTTP. This means that some Intel AMT features can be accessed from a - local application using the same network interface as a remote application - communicating with Intel AMT over the network. - - When a local application sends a message addressed to the local Intel AMT host - name, the Intel LMS, which listens for traffic directed to the host name, - intercepts the message and routes it to the Intel MEI. - For more information: - http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide - Under "About Intel AMT" => "Local Access" - - For downloading Intel LMS: - http://software.intel.com/en-us/articles/download-the-latest-intel-amt-open-source-drivers/ - - The Intel LMS opens a connection using the Intel MEI driver to the Intel LMS - firmware feature using a defined UUID and then communicates with the feature - using a protocol called Intel AMT Port Forwarding Protocol(Intel APF protocol). - The protocol is used to maintain multiple sessions with Intel AMT from a - single application. - - See the protocol specification in the Intel AMT Software Development Kit(SDK) - http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide - Under "SDK Resources" => "Intel(R) vPro(TM) Gateway(MPS)" - => "Information for Intel(R) vPro(TM) Gateway Developers" - => "Description of the Intel AMT Port Forwarding (APF)Protocol" - - 2) Intel AMT Remote configuration using a Local Agent - A Local Agent enables IT personnel to configure Intel AMT out-of-the-box - without requiring installing additional data to enable setup. The remote - configuration process may involve an ISV-developed remote configuration - agent that runs on the host. - For more information: - http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide - Under "Setup and Configuration of Intel AMT" => - "SDK Tools Supporting Setup and Configuration" => - "Using the Local Agent Sample" - - An open source Intel AMT configuration utility, implementing a local agent - that accesses the Intel MEI driver, can be found here: - http://software.intel.com/en-us/articles/download-the-latest-intel-amt-open-source-drivers/ - - -Intel AMT OS Health Watchdog: -============================= -The Intel AMT Watchdog is an OS Health (Hang/Crash) watchdog. -Whenever the OS hangs or crashes, Intel AMT will send an event -to any subscriber to this event. This mechanism means that -IT knows when a platform crashes even when there is a hard failure on the host. - -The Intel AMT Watchdog is composed of two parts: - 1) Firmware feature - receives the heartbeats - and sends an event when the heartbeats stop. - 2) Intel MEI driver - connects to the watchdog feature, configures the - watchdog and sends the heartbeats. - -The Intel MEI driver uses the kernel watchdog to configure the Intel AMT -Watchdog and to send heartbeats to it. The default timeout of the -watchdog is 120 seconds. - -If the Intel AMT Watchdog feature does not exist (i.e. the connection failed), -the Intel MEI driver will disable the sending of heartbeats. - -Supported Chipsets: -================== -7 Series Chipset Family -6 Series Chipset Family -5 Series Chipset Family -4 Series Chipset Family -Mobile 4 Series Chipset Family -ICH9 -82946GZ/GL -82G35 Express -82Q963/Q965 -82P965/G965 -Mobile PM965/GM965 -Mobile GME965/GLE960 -82Q35 Express -82G33/G31/P35/P31 Express -82Q33 Express -82X38/X48 Express - ---- -linux-mei@linux.intel.com diff --git a/drivers/staging/mei/mei_dev.h b/drivers/staging/mei/mei_dev.h deleted file mode 100644 index 10b1b4e..0000000 --- a/drivers/staging/mei/mei_dev.h +++ /dev/null @@ -1,428 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2012, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - -#ifndef _MEI_DEV_H_ -#define _MEI_DEV_H_ - -#include -#include -#include "mei.h" -#include "hw.h" - -/* - * watch dog definition - */ -#define MEI_WATCHDOG_DATA_SIZE 16 -#define MEI_START_WD_DATA_SIZE 20 -#define MEI_WD_PARAMS_SIZE 4 -#define MEI_WD_STATE_INDEPENDENCE_MSG_SENT (1 << 0) - -#define MEI_RD_MSG_BUF_SIZE (128 * sizeof(u32)) - -/* - * MEI PCI Device object - */ -extern struct pci_dev *mei_device; - - -/* - * AMTHI Client UUID - */ -extern const uuid_le mei_amthi_guid; - -/* - * Watchdog Client UUID - */ -extern const uuid_le mei_wd_guid; - -/* - * Watchdog independence state message - */ -extern const u8 mei_wd_state_independence_msg[3][4]; - -/* - * Number of File descriptors/handles - * that can be opened to the driver. - * - * Limit to 253: 255 Total Clients - * minus internal client for AMTHI - * minus internal client for Watchdog - */ -#define MEI_MAX_OPEN_HANDLE_COUNT 253 - -/* - * Number of Maximum MEI Clients - */ -#define MEI_CLIENTS_MAX 255 - -/* File state */ -enum file_state { - MEI_FILE_INITIALIZING = 0, - MEI_FILE_CONNECTING, - MEI_FILE_CONNECTED, - MEI_FILE_DISCONNECTING, - MEI_FILE_DISCONNECTED -}; - -/* MEI device states */ -enum mei_states { - MEI_INITIALIZING = 0, - MEI_INIT_CLIENTS, - MEI_ENABLED, - MEI_RESETING, - MEI_DISABLED, - MEI_RECOVERING_FROM_RESET, - MEI_POWER_DOWN, - MEI_POWER_UP -}; - -/* init clients states*/ -enum mei_init_clients_states { - MEI_START_MESSAGE = 0, - MEI_ENUM_CLIENTS_MESSAGE, - MEI_CLIENT_PROPERTIES_MESSAGE -}; - -enum iamthif_states { - MEI_IAMTHIF_IDLE, - MEI_IAMTHIF_WRITING, - MEI_IAMTHIF_FLOW_CONTROL, - MEI_IAMTHIF_READING, - MEI_IAMTHIF_READ_COMPLETE -}; - -enum mei_file_transaction_states { - MEI_IDLE, - MEI_WRITING, - MEI_WRITE_COMPLETE, - MEI_FLOW_CONTROL, - MEI_READING, - MEI_READ_COMPLETE -}; - -/* MEI CB */ -enum mei_cb_major_types { - MEI_READ = 0, - MEI_WRITE, - MEI_IOCTL, - MEI_OPEN, - MEI_CLOSE -}; - -/* - * Intel MEI message data struct - */ -struct mei_message_data { - u32 size; - unsigned char *data; -} __packed; - - -struct mei_cl_cb { - struct list_head cb_list; - enum mei_cb_major_types major_file_operations; - void *file_private; - struct mei_message_data request_buffer; - struct mei_message_data response_buffer; - unsigned long information; - unsigned long read_time; - struct file *file_object; -}; - -/* MEI client instance carried as file->pirvate_data*/ -struct mei_cl { - struct list_head link; - struct mei_device *dev; - enum file_state state; - wait_queue_head_t tx_wait; - wait_queue_head_t rx_wait; - wait_queue_head_t wait; - int read_pending; - int status; - /* ID of client connected */ - u8 host_client_id; - u8 me_client_id; - u8 mei_flow_ctrl_creds; - u8 timer_count; - enum mei_file_transaction_states reading_state; - enum mei_file_transaction_states writing_state; - int sm_state; - struct mei_cl_cb *read_cb; -}; - -struct mei_io_list { - struct mei_cl_cb mei_cb; -}; - -/* MEI private device struct */ -struct mei_device { - struct pci_dev *pdev; /* pointer to pci device struct */ - /* - * lists of queues - */ - /* array of pointers to aio lists */ - struct mei_io_list read_list; /* driver read queue */ - struct mei_io_list write_list; /* driver write queue */ - struct mei_io_list write_waiting_list; /* write waiting queue */ - struct mei_io_list ctrl_wr_list; /* managed write IOCTL list */ - struct mei_io_list ctrl_rd_list; /* managed read IOCTL list */ - struct mei_io_list amthi_cmd_list; /* amthi list for cmd waiting */ - - /* driver managed amthi list for reading completed amthi cmd data */ - struct mei_io_list amthi_read_complete_list; - /* - * list of files - */ - struct list_head file_list; - long open_handle_count; - /* - * memory of device - */ - unsigned int mem_base; - unsigned int mem_length; - void __iomem *mem_addr; - /* - * lock for the device - */ - struct mutex device_lock; /* device lock */ - struct delayed_work timer_work; /* MEI timer delayed work (timeouts) */ - bool recvd_msg; - /* - * hw states of host and fw(ME) - */ - u32 host_hw_state; - u32 me_hw_state; - /* - * waiting queue for receive message from FW - */ - wait_queue_head_t wait_recvd_msg; - wait_queue_head_t wait_stop_wd; - - /* - * mei device states - */ - enum mei_states mei_state; - enum mei_init_clients_states init_clients_state; - u16 init_clients_timer; - bool stop; - bool need_reset; - - u32 extra_write_index; - unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE]; /* control messages */ - u32 wr_msg_buf[128]; /* used for control messages */ - u32 ext_msg_buf[8]; /* for control responses */ - u32 rd_msg_hdr; - - struct hbm_version version; - - struct mei_me_client *me_clients; /* Note: memory has to be allocated */ - DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX); - DECLARE_BITMAP(host_clients_map, MEI_CLIENTS_MAX); - u8 me_clients_num; - u8 me_client_presentation_num; - u8 me_client_index; - bool mei_host_buffer_is_empty; - - struct mei_cl wd_cl; - bool wd_pending; - bool wd_stopped; - bool wd_bypass; /* if false, don't refresh watchdog ME client */ - u16 wd_timeout; /* seconds ((wd_data[1] << 8) + wd_data[0]) */ - u16 wd_due_counter; - unsigned char wd_data[MEI_START_WD_DATA_SIZE]; - - - - struct file *iamthif_file_object; - struct mei_cl iamthif_cl; - struct mei_cl_cb *iamthif_current_cb; - int iamthif_mtu; - unsigned long iamthif_timer; - u32 iamthif_stall_timer; - unsigned char *iamthif_msg_buf; /* Note: memory has to be allocated */ - u32 iamthif_msg_buf_size; - u32 iamthif_msg_buf_index; - enum iamthif_states iamthif_state; - bool iamthif_flow_control_pending; - bool iamthif_ioctl; - bool iamthif_canceled; - - bool wd_interface_reg; -}; - - -/* - * mei init function prototypes - */ -struct mei_device *mei_device_init(struct pci_dev *pdev); -void mei_reset(struct mei_device *dev, int interrupts); -int mei_hw_init(struct mei_device *dev); -int mei_task_initialize_clients(void *data); -int mei_initialize_clients(struct mei_device *dev); -int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl); -void mei_remove_client_from_file_list(struct mei_device *dev, u8 host_client_id); -void mei_host_init_iamthif(struct mei_device *dev); -void mei_allocate_me_clients_storage(struct mei_device *dev); - - -u8 mei_find_me_client_update_filext(struct mei_device *dev, - struct mei_cl *priv, - const uuid_le *cguid, u8 client_id); - -/* - * MEI IO List Functions - */ -void mei_io_list_init(struct mei_io_list *list); -void mei_io_list_flush(struct mei_io_list *list, struct mei_cl *cl); - -/* - * MEI ME Client Functions - */ - -struct mei_cl *mei_cl_allocate(struct mei_device *dev); -void mei_cl_init(struct mei_cl *cl, struct mei_device *dev); -int mei_cl_flush_queues(struct mei_cl *cl); -/** - * mei_cl_cmp_id - tells if file private data have same id - * - * @fe1: private data of 1. file object - * @fe2: private data of 2. file object - * - * returns true - if ids are the same and not NULL - */ -static inline bool mei_cl_cmp_id(const struct mei_cl *cl1, - const struct mei_cl *cl2) -{ - return cl1 && cl2 && - (cl1->host_client_id == cl2->host_client_id) && - (cl1->me_client_id == cl2->me_client_id); -} - - - -/* - * MEI Host Client Functions - */ -void mei_host_start_message(struct mei_device *dev); -void mei_host_enum_clients_message(struct mei_device *dev); -int mei_host_client_properties(struct mei_device *dev); - -/* - * MEI interrupt functions prototype - */ -irqreturn_t mei_interrupt_quick_handler(int irq, void *dev_id); -irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id); -void mei_timer(struct work_struct *work); - -/* - * MEI input output function prototype - */ -int mei_ioctl_connect_client(struct file *file, - struct mei_connect_client_data *data); - -int mei_start_read(struct mei_device *dev, struct mei_cl *cl); - -int amthi_write(struct mei_device *dev, struct mei_cl_cb *priv_cb); - -int amthi_read(struct mei_device *dev, struct file *file, - char __user *ubuf, size_t length, loff_t *offset); - -struct mei_cl_cb *find_amthi_read_list_entry(struct mei_device *dev, - struct file *file); - -void mei_run_next_iamthif_cmd(struct mei_device *dev); - -void mei_free_cb_private(struct mei_cl_cb *priv_cb); - -int mei_find_me_client_index(const struct mei_device *dev, uuid_le cuuid); - -/* - * Register Access Function - */ - -/** - * mei_reg_read - Reads 32bit data from the mei device - * - * @dev: the device structure - * @offset: offset from which to read the data - * - * returns register value (u32) - */ -static inline u32 mei_reg_read(struct mei_device *dev, unsigned long offset) -{ - return ioread32(dev->mem_addr + offset); -} - -/** - * mei_reg_write - Writes 32bit data to the mei device - * - * @dev: the device structure - * @offset: offset from which to write the data - * @value: register value to write (u32) - */ -static inline void mei_reg_write(struct mei_device *dev, - unsigned long offset, u32 value) -{ - iowrite32(value, dev->mem_addr + offset); -} - -/** - * mei_hcsr_read - Reads 32bit data from the host CSR - * - * @dev: the device structure - * - * returns the byte read. - */ -static inline u32 mei_hcsr_read(struct mei_device *dev) -{ - return mei_reg_read(dev, H_CSR); -} - -/** - * mei_mecsr_read - Reads 32bit data from the ME CSR - * - * @dev: the device structure - * - * returns ME_CSR_HA register value (u32) - */ -static inline u32 mei_mecsr_read(struct mei_device *dev) -{ - return mei_reg_read(dev, ME_CSR_HA); -} - -/** - * get_me_cb_rw - Reads 32bit data from the mei ME_CB_RW register - * - * @dev: the device structure - * - * returns ME_CB_RW register value (u32) - */ -static inline u32 mei_mecbrw_read(struct mei_device *dev) -{ - return mei_reg_read(dev, ME_CB_RW); -} - - -/* - * mei interface function prototypes - */ -void mei_hcsr_set(struct mei_device *dev); -void mei_csr_clear_his(struct mei_device *dev); - -void mei_enable_interrupts(struct mei_device *dev); -void mei_disable_interrupts(struct mei_device *dev); - -#endif diff --git a/drivers/staging/mei/wd.c b/drivers/staging/mei/wd.c deleted file mode 100644 index 1e62851..0000000 --- a/drivers/staging/mei/wd.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2012, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ -#include -#include -#include -#include -#include -#include -#include - -#include "mei_dev.h" -#include "hw.h" -#include "interface.h" -#include "mei.h" - -static const u8 mei_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 }; -static const u8 mei_stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 }; - -const u8 mei_wd_state_independence_msg[3][4] = { - {0x05, 0x02, 0x51, 0x10}, - {0x05, 0x02, 0x52, 0x10}, - {0x07, 0x02, 0x01, 0x10} -}; - -/* - * AMT Watchdog Device - */ -#define INTEL_AMT_WATCHDOG_ID "INTCAMT" - -/* UUIDs for AMT F/W clients */ -const uuid_le mei_wd_guid = UUID_LE(0x05B79A6F, 0x4628, 0x4D7F, 0x89, - 0x9D, 0xA9, 0x15, 0x14, 0xCB, - 0x32, 0xAB); - -static void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout) -{ - dev_dbg(&dev->pdev->dev, "wd: set timeout=%d.\n", timeout); - memcpy(dev->wd_data, mei_start_wd_params, MEI_WD_PARAMS_SIZE); - memcpy(dev->wd_data + MEI_WD_PARAMS_SIZE, &timeout, sizeof(u16)); -} - -/** - * host_init_wd - mei initialization wd. - * - * @dev: the device structure - * returns -ENENT if wd client cannot be found - * -EIO if write has failed - */ -int mei_wd_host_init(struct mei_device *dev) -{ - mei_cl_init(&dev->wd_cl, dev); - - /* look for WD client and connect to it */ - dev->wd_cl.state = MEI_FILE_DISCONNECTED; - dev->wd_timeout = AMT_WD_DEFAULT_TIMEOUT; - - /* find ME WD client */ - mei_find_me_client_update_filext(dev, &dev->wd_cl, - &mei_wd_guid, MEI_WD_HOST_CLIENT_ID); - - dev_dbg(&dev->pdev->dev, "wd: check client\n"); - if (MEI_FILE_CONNECTING != dev->wd_cl.state) { - dev_info(&dev->pdev->dev, "wd: failed to find the client\n"); - return -ENOENT; - } - - if (mei_connect(dev, &dev->wd_cl)) { - dev_err(&dev->pdev->dev, "wd: failed to connect to the client\n"); - dev->wd_cl.state = MEI_FILE_DISCONNECTED; - dev->wd_cl.host_client_id = 0; - return -EIO; - } - dev->wd_cl.timer_count = CONNECT_TIMEOUT; - - return 0; -} - -/** - * mei_wd_send - sends watch dog message to fw. - * - * @dev: the device structure - * - * returns 0 if success, - * -EIO when message send fails - * -EINVAL when invalid message is to be sent - */ -int mei_wd_send(struct mei_device *dev) -{ - struct mei_msg_hdr *mei_hdr; - - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = dev->wd_cl.host_client_id; - mei_hdr->me_addr = dev->wd_cl.me_client_id; - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - if (!memcmp(dev->wd_data, mei_start_wd_params, MEI_WD_PARAMS_SIZE)) - mei_hdr->length = MEI_START_WD_DATA_SIZE; - else if (!memcmp(dev->wd_data, mei_stop_wd_params, MEI_WD_PARAMS_SIZE)) - mei_hdr->length = MEI_WD_PARAMS_SIZE; - else - return -EINVAL; - - return mei_write_message(dev, mei_hdr, dev->wd_data, mei_hdr->length); -} - -/** - * mei_wd_stop - sends watchdog stop message to fw. - * - * @dev: the device structure - * @preserve: indicate if to keep the timeout value - * - * returns 0 if success, - * -EIO when message send fails - * -EINVAL when invalid message is to be sent - */ -int mei_wd_stop(struct mei_device *dev, bool preserve) -{ - int ret; - u16 wd_timeout = dev->wd_timeout; - - cancel_delayed_work(&dev->timer_work); - if (dev->wd_cl.state != MEI_FILE_CONNECTED || !dev->wd_timeout) - return 0; - - dev->wd_timeout = 0; - dev->wd_due_counter = 0; - memcpy(dev->wd_data, mei_stop_wd_params, MEI_WD_PARAMS_SIZE); - dev->stop = true; - - ret = mei_flow_ctrl_creds(dev, &dev->wd_cl); - if (ret < 0) - goto out; - - if (ret && dev->mei_host_buffer_is_empty) { - ret = 0; - dev->mei_host_buffer_is_empty = false; - - if (!mei_wd_send(dev)) { - ret = mei_flow_ctrl_reduce(dev, &dev->wd_cl); - if (ret) - goto out; - } else { - dev_err(&dev->pdev->dev, "wd: send stop failed\n"); - } - - dev->wd_pending = false; - } else { - dev->wd_pending = true; - } - dev->wd_stopped = false; - mutex_unlock(&dev->device_lock); - - ret = wait_event_interruptible_timeout(dev->wait_stop_wd, - dev->wd_stopped, 10 * HZ); - mutex_lock(&dev->device_lock); - if (dev->wd_stopped) { - dev_dbg(&dev->pdev->dev, "wd: stop completed ret=%d.\n", ret); - ret = 0; - } else { - if (!ret) - ret = -ETIMEDOUT; - dev_warn(&dev->pdev->dev, - "wd: stop failed to complete ret=%d.\n", ret); - } - - if (preserve) - dev->wd_timeout = wd_timeout; - -out: - return ret; -} - -/* - * mei_wd_ops_start - wd start command from the watchdog core. - * - * @wd_dev - watchdog device struct - * - * returns 0 if success, negative errno code for failure - */ -static int mei_wd_ops_start(struct watchdog_device *wd_dev) -{ - int err = -ENODEV; - struct mei_device *dev; - - dev = pci_get_drvdata(mei_device); - if (!dev) - return -ENODEV; - - mutex_lock(&dev->device_lock); - - if (dev->mei_state != MEI_ENABLED) { - dev_dbg(&dev->pdev->dev, - "wd: mei_state != MEI_ENABLED mei_state = %d\n", - dev->mei_state); - goto end_unlock; - } - - if (dev->wd_cl.state != MEI_FILE_CONNECTED) { - dev_dbg(&dev->pdev->dev, - "MEI Driver is not connected to Watchdog Client\n"); - goto end_unlock; - } - - mei_wd_set_start_timeout(dev, dev->wd_timeout); - - err = 0; -end_unlock: - mutex_unlock(&dev->device_lock); - return err; -} - -/* - * mei_wd_ops_stop - wd stop command from the watchdog core. - * - * @wd_dev - watchdog device struct - * - * returns 0 if success, negative errno code for failure - */ -static int mei_wd_ops_stop(struct watchdog_device *wd_dev) -{ - struct mei_device *dev; - dev = pci_get_drvdata(mei_device); - - if (!dev) - return -ENODEV; - - mutex_lock(&dev->device_lock); - mei_wd_stop(dev, false); - mutex_unlock(&dev->device_lock); - - return 0; -} - -/* - * mei_wd_ops_ping - wd ping command from the watchdog core. - * - * @wd_dev - watchdog device struct - * - * returns 0 if success, negative errno code for failure - */ -static int mei_wd_ops_ping(struct watchdog_device *wd_dev) -{ - int ret = 0; - struct mei_device *dev; - dev = pci_get_drvdata(mei_device); - - if (!dev) - return -ENODEV; - - mutex_lock(&dev->device_lock); - - if (dev->wd_cl.state != MEI_FILE_CONNECTED) { - dev_err(&dev->pdev->dev, "wd: not connected.\n"); - ret = -ENODEV; - goto end; - } - - /* Check if we can send the ping to HW*/ - if (dev->mei_host_buffer_is_empty && - mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) { - - dev->mei_host_buffer_is_empty = false; - dev_dbg(&dev->pdev->dev, "wd: sending ping\n"); - - if (mei_wd_send(dev)) { - dev_err(&dev->pdev->dev, "wd: send failed.\n"); - ret = -EIO; - goto end; - } - - if (mei_flow_ctrl_reduce(dev, &dev->wd_cl)) { - dev_err(&dev->pdev->dev, - "wd: mei_flow_ctrl_reduce() failed.\n"); - ret = -EIO; - goto end; - } - - } else { - dev->wd_pending = true; - } - -end: - mutex_unlock(&dev->device_lock); - return ret; -} - -/* - * mei_wd_ops_set_timeout - wd set timeout command from the watchdog core. - * - * @wd_dev - watchdog device struct - * @timeout - timeout value to set - * - * returns 0 if success, negative errno code for failure - */ -static int mei_wd_ops_set_timeout(struct watchdog_device *wd_dev, unsigned int timeout) -{ - struct mei_device *dev; - dev = pci_get_drvdata(mei_device); - - if (!dev) - return -ENODEV; - - /* Check Timeout value */ - if (timeout < AMT_WD_MIN_TIMEOUT || timeout > AMT_WD_MAX_TIMEOUT) - return -EINVAL; - - mutex_lock(&dev->device_lock); - - dev->wd_timeout = timeout; - wd_dev->timeout = timeout; - mei_wd_set_start_timeout(dev, dev->wd_timeout); - - mutex_unlock(&dev->device_lock); - - return 0; -} - -/* - * Watchdog Device structs - */ -static const struct watchdog_ops wd_ops = { - .owner = THIS_MODULE, - .start = mei_wd_ops_start, - .stop = mei_wd_ops_stop, - .ping = mei_wd_ops_ping, - .set_timeout = mei_wd_ops_set_timeout, -}; -static const struct watchdog_info wd_info = { - .identity = INTEL_AMT_WATCHDOG_ID, - .options = WDIOF_KEEPALIVEPING, -}; - -static struct watchdog_device amt_wd_dev = { - .info = &wd_info, - .ops = &wd_ops, - .timeout = AMT_WD_DEFAULT_TIMEOUT, - .min_timeout = AMT_WD_MIN_TIMEOUT, - .max_timeout = AMT_WD_MAX_TIMEOUT, -}; - - -void mei_watchdog_register(struct mei_device *dev) -{ - dev_dbg(&dev->pdev->dev, "dev->wd_timeout =%d.\n", dev->wd_timeout); - - dev->wd_due_counter = !!dev->wd_timeout; - - if (watchdog_register_device(&amt_wd_dev)) { - dev_err(&dev->pdev->dev, - "wd: unable to register watchdog device.\n"); - dev->wd_interface_reg = false; - } else { - dev_dbg(&dev->pdev->dev, - "wd: successfully register watchdog interface.\n"); - dev->wd_interface_reg = true; - } -} - -void mei_watchdog_unregister(struct mei_device *dev) -{ - if (dev->wd_interface_reg) - watchdog_unregister_device(&amt_wd_dev); - dev->wd_interface_reg = false; -} - -- cgit v0.10.2 From bf3313a1b6bd819fc4ca6f54b465481fb8b5f0a8 Mon Sep 17 00:00:00 2001 From: joseph daniel Date: Tue, 1 May 2012 00:30:34 +0600 Subject: staging: et131x: Fix coding style issues Signed-off-by: joseph daniel Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 886f565..5b11c5e 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -1710,7 +1710,8 @@ static int et131x_mdio_read(struct mii_bus *bus, int phy_addr, int reg) return value; } -static int et131x_mdio_write(struct mii_bus *bus, int phy_addr, int reg, u16 value) +static int et131x_mdio_write(struct mii_bus *bus, int phy_addr, + int reg, u16 value) { struct net_device *netdev = bus->priv; struct et131x_adapter *adapter = netdev_priv(netdev); @@ -4013,7 +4014,7 @@ static int et131x_pci_init(struct et131x_adapter *adapter, dev_err(&pdev->dev, "Missing PCIe capabilities\n"); goto err_out; } - + /* Let's set up the PORT LOGIC Register. First we need to know what * the max_payload_size is */ @@ -4060,7 +4061,7 @@ static int et131x_pci_init(struct et131x_adapter *adapter, goto err_out; } - ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | ( 0x04 << 12); + ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | (0x04 << 12); if (pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl)) { dev_err(&pdev->dev, @@ -4824,7 +4825,8 @@ static int et131x_open(struct net_device *netdev) adapter->error_timer.data = (unsigned long)adapter; add_timer(&adapter->error_timer); - result = request_irq(irq, et131x_isr, IRQF_SHARED, netdev->name, netdev); + result = request_irq(irq, et131x_isr, + IRQF_SHARED, netdev->name, netdev); if (result) { dev_err(&pdev->dev, "could not register IRQ %d\n", irq); return result; -- cgit v0.10.2 From ffae3055d23275b7b0abd4c1b0b750662b62ccf1 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 30 Apr 2012 13:45:41 -0700 Subject: staging: rtl8192u Fix a typo. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192u/r8180_93cx6.c b/drivers/staging/rtl8192u/r8180_93cx6.c index 0e8ff75..3c515b7 100644 --- a/drivers/staging/rtl8192u/r8180_93cx6.c +++ b/drivers/staging/rtl8192u/r8180_93cx6.c @@ -14,7 +14,7 @@ Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. - We want to thanks the Authors of those projects and the Ndiswrapper + We want to thank the Authors of those projects and the Ndiswrapper project Authors. */ diff --git a/drivers/staging/rtl8192u/r8180_93cx6.h b/drivers/staging/rtl8192u/r8180_93cx6.h index 3527d32..5cea51e 100644 --- a/drivers/staging/rtl8192u/r8180_93cx6.h +++ b/drivers/staging/rtl8192u/r8180_93cx6.h @@ -7,7 +7,7 @@ Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - We want to thanks the Authors of such projects and the Ndiswrapper project Authors. + We want to thank the Authors of such projects and the Ndiswrapper project Authors. */ /*This files contains card eeprom (93c46 or 93c56) programming routines*/ diff --git a/drivers/staging/rtl8192u/r8192U.h b/drivers/staging/rtl8192u/r8192U.h index adeb724..ebcb5b0 100644 --- a/drivers/staging/rtl8192u/r8192U.h +++ b/drivers/staging/rtl8192u/r8192U.h @@ -11,7 +11,7 @@ Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - We want to thanks the Authors of those projects and the Ndiswrapper + We want to thank the Authors of those projects and the Ndiswrapper project Authors. */ diff --git a/drivers/staging/rtl8192u/r8192U_hw.h b/drivers/staging/rtl8192u/r8192U_hw.h index b0ee4dd..1bfe871 100644 --- a/drivers/staging/rtl8192u/r8192U_hw.h +++ b/drivers/staging/rtl8192u/r8192U_hw.h @@ -10,7 +10,7 @@ Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. - We want to thanks the Authors of those projects + We want to thank the Authors of those projects and the Ndiswrapper project Authors. */ diff --git a/drivers/staging/rtl8192u/r8192U_wx.c b/drivers/staging/rtl8192u/r8192U_wx.c index 2ce0fc8..71f2d23 100644 --- a/drivers/staging/rtl8192u/r8192U_wx.c +++ b/drivers/staging/rtl8192u/r8192U_wx.c @@ -13,7 +13,7 @@ Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. - We want to thanks the Authors of those projects and the Ndiswrapper + We want to thank the Authors of those projects and the Ndiswrapper project Authors. */ diff --git a/drivers/staging/rtl8192u/r8192U_wx.h b/drivers/staging/rtl8192u/r8192U_wx.h index 1388664..9f6b105 100644 --- a/drivers/staging/rtl8192u/r8192U_wx.h +++ b/drivers/staging/rtl8192u/r8192U_wx.h @@ -7,7 +7,7 @@ Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - We want to thanks the Authors of such projects and the Ndiswrapper project Authors. + We want to thank the Authors of such projects and the Ndiswrapper project Authors. */ /* this file (will) contains wireless extension handlers*/ -- cgit v0.10.2 From 8ef3a7ed35a09431336faf2f3ce53d4d0959cea1 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 30 Apr 2012 14:39:21 -0700 Subject: staging:rtl8192u Fix typos and comments Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192u/r8192U.h b/drivers/staging/rtl8192u/r8192U.h index ebcb5b0..b4e99f4 100644 --- a/drivers/staging/rtl8192u/r8192U.h +++ b/drivers/staging/rtl8192u/r8192U.h @@ -98,7 +98,7 @@ do { if(rt_global_debug_component & component) \ #define COMP_INIT BIT2 // during driver initialization / halt / reset. -#define COMP_RECV BIT3 // Revive part data path. +#define COMP_RECV BIT3 // Receive data path. #define COMP_SEND BIT4 // Send part path. #define COMP_IO BIT5 // I/O Related. Added by Annie, 2006-03-02. #define COMP_POWER BIT6 // 802.11 Power Save mode or System/Device Power state related. @@ -322,7 +322,7 @@ typedef struct _tx_fwinfo_819x_usb { u8 TxSubCarrier:2; // This is used for legacy OFDM rate only. u8 STBC:2; u8 AllowAggregation:1; - u8 RtsHT:1; //Interprete RtsRate field as high throughput data rate + u8 RtsHT:1; //Interpret RtsRate field as high throughput data rate u8 RtsShort:1; //Short PLCP for CCK, or short GI for 11n MCS u8 RtsBandwidth:1; // This is used for HT MCS rate only. u8 RtsSubcarrier:2; // This is used for legacy OFDM rate only. diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index be86045..5981d66 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -203,7 +203,7 @@ static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv) { Dot11d_Init(ieee); ieee->bGlobalDomain = false; - //actually 8225 & 8256 rf chip only support B,G,24N mode + //actually 8225 & 8256 rf chips only support B,G,24N mode if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256)) { min_chan = 1; @@ -1476,7 +1476,7 @@ static void rtl8192_tx_isr(struct urb *tx_urb) if(tcb_desc->queue_index != TXCMD_QUEUE) { if(tx_urb->status == 0) { dev->trans_start = jiffies; - // As act as station mode, destination shall be unicast address. + // Act as station mode, destination shall be unicast address. //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom); //priv->ieee80211->stats.tx_packets++; priv->stats.txoktotal++; @@ -1527,8 +1527,8 @@ static void rtl8192_tx_isr(struct urb *tx_urb) * function, it should contain enough tx irq; * 2. check packet type; * 3. initialize sendlist, check whether the to-be send packet no greater than 1 - * 4. aggregates the packets, and fill firmware info and tx desc to it, etc. - * 5. check whether the packet could be sent, otherwise just insert to wait head + * 4. aggregates the packets, and fill firmware info and tx desc into it, etc. + * 5. check whether the packet could be sent, otherwise just insert into wait head * */ skb = skb_dequeue(&priv->ieee80211->skb_drv_aggQ[queue_index]); if(!check_nic_enough_desc(dev, queue_index)) { @@ -2783,7 +2783,7 @@ static void rtl8192_init_priv_variable(struct net_device* dev) (TCR_MXDMA_2048<ShortRetryLimit<LongRetryLimit<bInHctTest) pHalData->ReceiveConfig = pHalData->CSMethod | @@ -3437,7 +3437,7 @@ if(Adapter->ResetProgress == RESET_TYPE_NORESET) { // User disable RF via registry. RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n")); MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW); - // Those action will be discard in MgntActSet_RF_State because of the same state + // Those actions will be discard in MgntActSet_RF_State because of the same state for(eRFPath = 0; eRFPath NumTotalRFPath; eRFPath++) PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0); } @@ -3458,7 +3458,7 @@ if(Adapter->ResetProgress == RESET_TYPE_NORESET) if(pHalData->eRFPowerState == eRfOff) { MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason); - // Those action will be discard in MgntActSet_RF_State because of the same state + // Those actions will be discard in MgntActSet_RF_State because of the same state for(eRFPath = 0; eRFPath NumTotalRFPath; eRFPath++) PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0); } @@ -4516,7 +4516,7 @@ u8 HwRateToMRate90(bool bIsHT, u8 rate) /** * Function: UpdateRxPktTimeStamp - * Overview: Record down the TSF time stamp when receiving a packet + * Overview: Record the TSF time stamp when receiving a packet * * Input: * PADAPTER Adapter @@ -4558,8 +4558,8 @@ long rtl819x_translate_todbm(u8 signal_strength_index )// 0-100 index. /* 2008/01/22 MH We can not declare RSSI/EVM total value of sliding window to be a local static. Otherwise, it may increase when we return from S3/S4. The - value will be kept in memory or disk. We must declare the value in adapter - and it will be reinitialized when return from S3/S4. */ + value will be kept in memory or disk. Declare the value in the adaptor + and it will be reinitialized when returned from S3/S4. */ void rtl8192_process_phyinfo(struct r8192_priv * priv,u8* buffer, struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats) { bool bcheck = false; @@ -5092,7 +5092,7 @@ static void rtl8192_query_rxphystatus( rx_evmX = (char)(tmp_rxevm); // Do not use shift operation like "rx_evmX >>= 1" because the compiler of free build environment - // fill most significant bit to "zero" when doing shifting operation which may change a negative + // will set the most significant bit to "zero" when doing shifting operation which may change a negative // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore. rx_evmX /= 2; //dbm @@ -5211,7 +5211,7 @@ void TranslateRxSignalStuff819xUsb(struct sk_buff *skb, /** * Function: UpdateReceivedRateHistogramStatistics -* Overview: Record down the received data rate +* Overview: Record the received data rate * * Input: * struct net_device *dev diff --git a/drivers/staging/rtl8192u/r8192U_dm.c b/drivers/staging/rtl8192u/r8192U_dm.c index 3f79e61..996e658 100644 --- a/drivers/staging/rtl8192u/r8192U_dm.c +++ b/drivers/staging/rtl8192u/r8192U_dm.c @@ -1457,7 +1457,7 @@ static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); - // Tx Power tracking by Thermal Meter require Firmware R/W 3-wire. This mechanism + // Tx Power tracking by Thermal Meter requires Firmware R/W 3-wire. This mechanism // can be enabled only when Firmware R/W 3-wire is enabled. Otherwise, frequent r/w // 3-wire by driver causes RF to go into a wrong state. if(priv->ieee80211->FwRWRF) @@ -1520,7 +1520,7 @@ static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev) if(!TM_Trigger) { - //Attention!! You have to write all 12bits data to RF, or it may cause RF to crash + //Attention!! You have to write all 12bits of data to RF, or it may cause RF to crash //actually write reg0x02 bit1=0, then bit1=1. //DbgPrint("Trigger ThermalMeter, write RF reg0x2 = 0x4d to 0x4f\n"); rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); @@ -2161,7 +2161,7 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( pHalData->UndecoratedSmoothedPWDB, DM_DigTable.RssiLowThresh, DM_DigTable.RssiHighThresh, DM_DigTable.Dig_State);*/ /* 1. When RSSI decrease, We have to judge if it is smaller than a threshold - and then execute below step. */ + and then execute the step below. */ if ((priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh)) { /* 2008/02/05 MH When we execute silent reset, the DIG PHY parameters @@ -2221,7 +2221,7 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( } /* 2. When RSSI increase, We have to judge if it is larger than a threshold - and then execute below step. */ + and then execute the step below. */ if ((priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) ) { u8 reset_flag = 0; @@ -2329,7 +2329,7 @@ static void dm_ctrl_initgain_byrssi_highpwr( } /* 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if - it is larger than a threshold and then execute below step. */ + it is larger than a threshold and then execute the step below. */ // 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue. if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh) { @@ -2842,7 +2842,7 @@ static void dm_check_rfctrl_gpio(struct net_device * dev) //struct r8192_priv *priv = ieee80211_priv(dev); // Work around for DTM test, we will not enable HW - radio on/off because r/w - // page 1 register before extra bus is enabled causing system fails when resuming + // page 1 register before extra bus is enabled causing system failures when resuming // from S4. 20080218, Emily // Stop to execute workitem to prevent S3/S4 bug. @@ -3392,7 +3392,7 @@ extern void dm_fsync_timer_callback(unsigned long data) } else { - // Stop continue count + // Stop the continued count priv->ContiuneDiffCount = 0; } @@ -3523,7 +3523,7 @@ static void dm_StartSWFsync(struct net_device *dev) RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__); // Initial rate record to zero, start to record. priv->rate_record = 0; - // Initial continue diff count to zero, start to record. + // Initialize continue diff count to zero, start to record. priv->ContiuneDiffCount = 0; priv->rateCountDiffRecord = 0; priv->bswitch_fsync = false; diff --git a/drivers/staging/rtl8192u/r819xU_cmdpkt.c b/drivers/staging/rtl8192u/r819xU_cmdpkt.c index ec1eeb7..a8a6dc2 100644 --- a/drivers/staging/rtl8192u/r819xU_cmdpkt.c +++ b/drivers/staging/rtl8192u/r819xU_cmdpkt.c @@ -726,7 +726,7 @@ cmpk_message_handle_rx( /* 4. Check every received command packet content according to different element type. Because FW may aggregate RX command packet to minimize transmit time between DRV and FW.*/ - // Add a counter to prevent the lock in the loop to be to long + // Add a counter to prevent the lock in the loop from being held too long while (total_length > 0 || exe_cnt++ >100) { /* 2007/01/17 MH We support aggregation of different cmd in the same packet. */ diff --git a/drivers/staging/rtl8192u/r819xU_firmware.c b/drivers/staging/rtl8192u/r819xU_firmware.c index fe5776d..b12d190 100644 --- a/drivers/staging/rtl8192u/r819xU_firmware.c +++ b/drivers/staging/rtl8192u/r819xU_firmware.c @@ -279,7 +279,7 @@ bool init_firmware(struct net_device *dev) */ for(init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; init_step++) { /* - * Open Image file, and map file to continuous memory if open file success. + * Open image file, and map file to continuous memory if open file success. * or read image file from array. Default load from IMG file */ if(rst_opt == OPT_SYSTEM_RESET) { diff --git a/drivers/staging/rtl8192u/r819xU_phy.c b/drivers/staging/rtl8192u/r819xU_phy.c index 636d6fd..dd1954d 100644 --- a/drivers/staging/rtl8192u/r819xU_phy.c +++ b/drivers/staging/rtl8192u/r819xU_phy.c @@ -176,7 +176,7 @@ u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x1); - // TODO: we should not delay such a long time. Ask help from SD3 + // TODO: we should not delay such a long time. Ask for help from SD3 msleep(1); ret = rtl8192_QueryBBReg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData); @@ -1425,7 +1425,7 @@ void rtl8192_SwChnl_WorkItem(struct net_device *dev) } /****************************************************************************** - *function: This function scheduled actual workitem to set channel + *function: This function scheduled actual work item to set channel * input: net_device dev * u8 channel //channel to set * output: none -- cgit v0.10.2 From 4c234ebcf4c98b20b8e3fa121b2382c375c3aa57 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Tue, 1 May 2012 08:34:14 -0700 Subject: staging: "rtl8192e/r8192u" typo change ContiuneDiffCount. As mentioned by jesper juhl, we should probably change ContiuneDiffCount to ContinueDiffCount. Below you will find the changes to do so. I have compile tested this and everything builds with the changes, as for testing on the hardware I am unable to do. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index cebb748..320d5fc 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -943,7 +943,7 @@ struct r8192_priv { bool bfsync_processing; u32 rate_record; u32 rateCountDiffRecord; - u32 ContiuneDiffCount; + u32 ContinueDiffCount; bool bswitch_fsync; u8 framesync; u32 framesyncC34; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index 2dfb0f0..481b1e4 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -2615,22 +2615,22 @@ void dm_fsync_timer_callback(unsigned long data) rate_count_diff; if (DiffNum >= priv->rtllib->fsync_seconddiff_ratethreshold) - priv->ContiuneDiffCount++; + priv->ContinueDiffCount++; else - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; - if (priv->ContiuneDiffCount >= 2) { + if (priv->ContinueDiffCount >= 2) { bSwitchFromCountDiff = true; - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; } } else { - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; } if (rate_count_diff <= priv->rtllib->fsync_firstdiff_ratethreshold) { bSwitchFromCountDiff = true; - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; } priv->rate_record = rate_count; priv->rateCountDiffRecord = rate_count_diff; @@ -2677,10 +2677,10 @@ void dm_fsync_timer_callback(unsigned long data) write_nic_byte(dev, 0xC36, 0x5c); write_nic_byte(dev, 0xC3e, 0x96); } - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); } - RT_TRACE(COMP_HALDM, "ContiuneDiffCount %d\n", priv->ContiuneDiffCount); + RT_TRACE(COMP_HALDM, "ContinueDiffCount %d\n", priv->ContinueDiffCount); RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d " "bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff, priv->bswitch_fsync); @@ -2723,7 +2723,7 @@ static void dm_EndSWFsync(struct net_device *dev) write_nic_byte(dev, 0xC3e, 0x96); } - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); } @@ -2735,7 +2735,7 @@ static void dm_StartSWFsync(struct net_device *dev) RT_TRACE(COMP_HALDM, "%s\n", __func__); priv->rate_record = 0; - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; priv->rateCountDiffRecord = 0; priv->bswitch_fsync = false; diff --git a/drivers/staging/rtl8192u/r8192U.h b/drivers/staging/rtl8192u/r8192U.h index b4e99f4..57e3383 100644 --- a/drivers/staging/rtl8192u/r8192U.h +++ b/drivers/staging/rtl8192u/r8192U.h @@ -1116,7 +1116,7 @@ typedef struct r8192_priv bool bfsync_processing; // 500ms Fsync timer is active or not u32 rate_record; u32 rateCountDiffRecord; - u32 ContiuneDiffCount; + u32 ContinueDiffCount; bool bswitch_fsync; u8 framesync; diff --git a/drivers/staging/rtl8192u/r8192U_dm.c b/drivers/staging/rtl8192u/r8192U_dm.c index 996e658..cd8dc85 100644 --- a/drivers/staging/rtl8192u/r8192U_dm.c +++ b/drivers/staging/rtl8192u/r8192U_dm.c @@ -3379,28 +3379,28 @@ extern void dm_fsync_timer_callback(unsigned long data) u32 DiffNum = priv->rateCountDiffRecord - rate_count_diff; // Continue count if(DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold) - priv->ContiuneDiffCount++; + priv->ContinueDiffCount++; else - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; // Continue count over - if(priv->ContiuneDiffCount >=2) + if(priv->ContinueDiffCount >=2) { bSwitchFromCountDiff = true; - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; } } else { // Stop the continued count - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; } //If Count diff <= FsyncRateCountThreshold if(rate_count_diff <= priv->ieee80211->fsync_firstdiff_ratethreshold) { bSwitchFromCountDiff = true; - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; } priv->rate_record = rate_count; priv->rateCountDiffRecord = rate_count_diff; @@ -3468,14 +3468,14 @@ extern void dm_fsync_timer_callback(unsigned long data) #endif write_nic_byte(dev, 0xC3e, 0x96); } - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; #ifdef RTL8190P write_nic_dword(dev, rOFDM0_RxDetector2, 0x164052cd); #else write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); #endif } - RT_TRACE(COMP_HALDM, "ContiuneDiffCount %d\n", priv->ContiuneDiffCount); + RT_TRACE(COMP_HALDM, "ContinueDiffCount %d\n", priv->ContinueDiffCount); RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync); } @@ -3507,7 +3507,7 @@ static void dm_EndSWFsync(struct net_device *dev) write_nic_byte(dev, 0xC3e, 0x96); } - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; #ifndef RTL8190P write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); #endif @@ -3524,7 +3524,7 @@ static void dm_StartSWFsync(struct net_device *dev) // Initial rate record to zero, start to record. priv->rate_record = 0; // Initialize continue diff count to zero, start to record. - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; priv->rateCountDiffRecord = 0; priv->bswitch_fsync = false; -- cgit v0.10.2 From e265af1bfa48dbacfe5727237ce6d756ce96431e Mon Sep 17 00:00:00 2001 From: Ravishankar Karkala Mallikarjunayya Date: Tue, 1 May 2012 11:55:06 +0530 Subject: Staging: comedi: fix line over 80 character issue in usbduxfast.c This is a patch to the usbduxfast.c file that fixes up a line over 80 character warning found by the checkpatch.pl tool. Signed-off-by: Ravishankar Karkala Mallikarjunayya Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 2b4d251..c672ea3 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -455,14 +455,15 @@ static int usbduxfastsub_start(struct usbduxfastsub_s *udfs) /* 7f92 to zero */ local_transfer_buffer[0] = 0; /* bRequest, "Firmware" */ - ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), USBDUXFASTSUB_FIRMWARE, - VENDOR_DIR_OUT, /* bmRequestType */ - USBDUXFASTSUB_CPUCS, /* Value */ - 0x0000, /* Index */ - /* address of the transfer buffer */ - local_transfer_buffer, - 1, /* Length */ - EZTIMEOUT); /* Timeout */ + ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), + USBDUXFASTSUB_FIRMWARE, + VENDOR_DIR_OUT, /* bmRequestType */ + USBDUXFASTSUB_CPUCS, /* Value */ + 0x0000, /* Index */ + /* address of the transfer buffer */ + local_transfer_buffer, + 1, /* Length */ + EZTIMEOUT); /* Timeout */ if (ret < 0) { printk("comedi_: usbduxfast_: control msg failed (start)\n"); return ret; @@ -479,7 +480,8 @@ static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs) /* 7f92 to one */ local_transfer_buffer[0] = 1; /* bRequest, "Firmware" */ - ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), USBDUXFASTSUB_FIRMWARE, + ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), + USBDUXFASTSUB_FIRMWARE, VENDOR_DIR_OUT, /* bmRequestType */ USBDUXFASTSUB_CPUCS, /* Value */ 0x0000, /* Index */ @@ -506,14 +508,15 @@ static int usbduxfastsub_upload(struct usbduxfastsub_s *udfs, startAddr, local_transfer_buffer[0]); #endif /* brequest, firmware */ - ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), USBDUXFASTSUB_FIRMWARE, - VENDOR_DIR_OUT, /* bmRequestType */ - startAddr, /* value */ - 0x0000, /* index */ - /* our local safe buffer */ - local_transfer_buffer, - len, /* length */ - EZTIMEOUT); /* timeout */ + ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), + USBDUXFASTSUB_FIRMWARE, + VENDOR_DIR_OUT, /* bmRequestType */ + startAddr, /* value */ + 0x0000, /* index */ + /* our local safe buffer */ + local_transfer_buffer, + len, /* length */ + EZTIMEOUT); /* timeout */ #ifdef CONFIG_COMEDI_DEBUG printk(KERN_DEBUG "comedi_: usbduxfast: result=%d\n", ret); -- cgit v0.10.2 From 6a8576360a77be2c39ef2e151b5a60b214f67fd6 Mon Sep 17 00:00:00 2001 From: Ravishankar Karkala Mallikarjunayya Date: Tue, 1 May 2012 11:55:07 +0530 Subject: Staging: comedi: fix printk issue in pcmmio.c This is a patch to the pcmmio.c file that fixes up a printk warning found by the checkpatch.pl tool. Signed-off-by: Ravishankar Karkala Mallikarjunayya Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index e05d157..d7f98d5 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -337,7 +337,7 @@ static int pcmmio_dio_insn_bits(struct comedi_device *dev, } #ifdef DAMMIT_ITS_BROKEN /* DEBUG */ - printk("data_out_byte %02x\n", (unsigned)byte); + printk(KERN_DEBUG "data_out_byte %02x\n", (unsigned)byte); #endif /* save the digital input lines for this byte.. */ s->state |= ((unsigned int)byte) << offset; -- cgit v0.10.2 From 65c5cfa695fa38272e393841ee80fd53ef2ef12e Mon Sep 17 00:00:00 2001 From: Ravishankar Karkala Mallikarjunayya Date: Tue, 1 May 2012 11:55:08 +0530 Subject: Staging: comedi: fix line indentation issue in dt9812.c Replaced the spaces with a tab. Signed-off-by: Ravishankar Karkala Mallikarjunayya Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index 89a49dd..72110fc 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -196,7 +196,7 @@ struct dt9812_flash_data { }; #define DT9812_MAX_NUM_MULTI_BYTE_RDS \ - ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / sizeof(u8)) + ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / sizeof(u8)) struct dt9812_read_multi { u8 count; @@ -209,8 +209,8 @@ struct dt9812_write_byte { }; #define DT9812_MAX_NUM_MULTI_BYTE_WRTS \ - ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / \ - sizeof(struct dt9812_write_byte)) + ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / \ + sizeof(struct dt9812_write_byte)) struct dt9812_write_multi { u8 count; @@ -224,7 +224,8 @@ struct dt9812_rmw_byte { }; #define DT9812_MAX_NUM_MULTI_BYTE_RMWS \ - ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / sizeof(struct dt9812_rmw_byte)) + ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / \ + sizeof(struct dt9812_rmw_byte)) struct dt9812_rmw_multi { u8 count; -- cgit v0.10.2 From a7a55d4a0fe08be4df1cabde83a44824626af533 Mon Sep 17 00:00:00 2001 From: Ravishankar Karkala Mallikarjunayya Date: Tue, 1 May 2012 11:55:09 +0530 Subject: Staging: comedi: Checkpatch cleanups. drivers/staging/comedi/drivers/dt9812.c:369: ERROR: "foo * bar" should be "foo *bar" drivers/staging/comedi/drivers/dt9812.c:369: ERROR: "foo * bar" should be "foo *bar" drivers/staging/comedi/drivers/dt9812.c:395: ERROR: "foo * bar" should be "foo *bar" drivers/staging/comedi/drivers/dt9812.c:396: ERROR: "foo * bar" should be "foo *bar" drivers/staging/comedi/drivers/dt9812.c:434: ERROR: "foo * bar" should be "foo *bar" drivers/staging/comedi/drivers/dt9812.c:480: ERROR: "foo * bar" should be "foo *bar" drivers/staging/comedi/drivers/dt9812.c:556: ERROR: "foo * bar" should be "foo *bar" drivers/staging/comedi/drivers/dt9812.c:623: ERROR: "foo * bar" should be "foo *bar" Signed-off-by: Ravishankar Karkala Mallikarjunayya Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index 72110fc..cd3a44a 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -366,7 +366,7 @@ static int dt9812_read_info(struct usb_dt9812 *dev, int offset, void *buf, } static int dt9812_read_multiple_registers(struct usb_dt9812 *dev, int reg_count, - u8 * address, u8 * value) + u8 *address, u8 *value) { struct dt9812_usb_cmd cmd; int i, count, retval; @@ -392,8 +392,8 @@ static int dt9812_read_multiple_registers(struct usb_dt9812 *dev, int reg_count, } static int dt9812_write_multiple_registers(struct usb_dt9812 *dev, - int reg_count, u8 * address, - u8 * value) + int reg_count, u8 *address, + u8 *value) { struct dt9812_usb_cmd cmd; int i, count, retval; @@ -431,7 +431,7 @@ static int dt9812_rmw_multiple_registers(struct usb_dt9812 *dev, int reg_count, return retval; } -static int dt9812_digital_in(struct slot_dt9812 *slot, u8 * bits) +static int dt9812_digital_in(struct slot_dt9812 *slot, u8 *bits) { int result = -ENODEV; @@ -477,7 +477,7 @@ static int dt9812_digital_out(struct slot_dt9812 *slot, u8 bits) return result; } -static int dt9812_digital_out_shadow(struct slot_dt9812 *slot, u8 * bits) +static int dt9812_digital_out_shadow(struct slot_dt9812 *slot, u8 *bits) { int result = -ENODEV; @@ -553,7 +553,7 @@ static void dt9812_configure_gain(struct usb_dt9812 *dev, } } -static int dt9812_analog_in(struct slot_dt9812 *slot, int channel, u16 * value, +static int dt9812_analog_in(struct slot_dt9812 *slot, int channel, u16 *value, enum dt9812_gain gain) { struct dt9812_rmw_byte rmw[3]; @@ -620,7 +620,7 @@ exit: } static int dt9812_analog_out_shadow(struct slot_dt9812 *slot, int channel, - u16 * value) + u16 *value) { int result = -ENODEV; -- cgit v0.10.2 From 5bb196ad29c58c3e69dde8ed34b99a07c0719e7f Mon Sep 17 00:00:00 2001 From: Ravishankar Karkala Mallikarjunayya Date: Tue, 1 May 2012 11:55:10 +0530 Subject: Staging: comedi: fix line over 80 character issue in rtd520.c This is a patch to the rtd520.c file that fixes up a line over 80 character warning found by the checkpatch.pl tool. Signed-off-by: Ravishankar Karkala Mallikarjunayya Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 1559d57..0c15b82 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -369,8 +369,11 @@ struct rtdPrivate { u8 utcCtrl[4]; /* crtl mode for 3 utc + read back */ u8 dioStatus; /* could be read back (dio0Ctrl) */ #ifdef USE_DMA - /* Always DMA 1/2 FIFO. Buffer (dmaBuff?) is (at least) twice that size. - After transferring, interrupt processes 1/2 FIFO and passes to comedi */ + /* + * Always DMA 1/2 FIFO. Buffer (dmaBuff?) is (at least) twice that + * size. After transferring, interrupt processes 1/2 FIFO and + * passes to comedi + */ s16 dma0Offset; /* current processing offset (0, 1/2) */ uint16_t *dma0Buff[DMA_CHAIN_COUNT]; /* DMA buffers (for ADC) */ dma_addr_t dma0BuffPhysAddr[DMA_CHAIN_COUNT]; /* physical addresses */ @@ -573,7 +576,8 @@ struct rtdPrivate { /* User output N source select (write only) */ #define RtdUsrOutSource(dev, n, v) \ - writel(v, devpriv->las0+((n <= 0) ? LAS0_UOUT0_SELECT : LAS0_UOUT1_SELECT)) + writel(v, devpriv->las0+((n <= 0) ? LAS0_UOUT0_SELECT : \ + LAS0_UOUT1_SELECT)) /* Digital IO */ #define RtdDio0Read(dev) \ @@ -600,7 +604,8 @@ struct rtdPrivate { /* Write one data value (sign + 12bit + marker bits) */ /* Note: matches what DMA would put. Actual value << 3 */ #define RtdDacFifoPut(dev, n, v) \ - writew((v), devpriv->las1 + (((n) == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO)) + writew((v), devpriv->las1 + (((n) == 0) ? LAS1_DAC1_FIFO : \ + LAS1_DAC2_FIFO)) /* Start single DAC conversion */ #define RtdDacUpdate(dev, n) \ @@ -617,7 +622,8 @@ struct rtdPrivate { /* Reset DAC FIFO */ #define RtdDacClearFifo(dev, n) \ - writel(0, devpriv->las0+(((n) == 0) ? LAS0_DAC1_RESET : LAS0_DAC2_RESET)) + writel(0, devpriv->las0+(((n) == 0) ? LAS0_DAC1_RESET : \ + LAS0_DAC2_RESET)) /* Set source for DMA 0 (write only, shadow?) */ #define RtdDma0Source(dev, n) \ @@ -713,7 +719,10 @@ static int rtd_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd); static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s); static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s); -/* static int rtd_ai_poll (struct comedi_device *dev,struct comedi_subdevice *s); */ +/* + * static int rtd_ai_poll(struct comedi_device *dev, + * struct comedi_subdevice *s); + */ static int rtd_ns_to_timer(unsigned int *ns, int roundMode); static irqreturn_t rtd_interrupt(int irq, void *d); static int rtd520_probe_fifo_depth(struct comedi_device *dev); @@ -833,7 +842,9 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) DPRINTK("rtd520: PCI latency = %d\n", pci_latency); } - /* Undocumented EPLD version (doesn't match RTD driver results) */ + /* + * Undocumented EPLD version (doesn't match RTD driver results) + */ /*DPRINTK ("rtd520: Reading epld from %p\n", devpriv->las0+0); epld_version = readl (devpriv->las0+0); @@ -946,9 +957,11 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) #ifdef USE_DMA if (dev->irq > 0) { printk("( DMA buff=%d )\n", DMA_CHAIN_COUNT); - /* The PLX9080 has 2 DMA controllers, but there could be 4 sources: - ADC, digital, DAC1, and DAC2. Since only the ADC supports cmd mode - right now, this isn't an issue (yet) */ + /* + * The PLX9080 has 2 DMA controllers, but there could be + * 4 sources: ADC, digital, DAC1, and DAC2. Since only the + * ADC supports cmd mode right now, this isn't an issue (yet) + */ devpriv->dma0Offset = 0; for (index = 0; index < DMA_CHAIN_COUNT; index++) { @@ -964,10 +977,14 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) } /*DPRINTK ("buff[%d] @ %p virtual, %x PCI\n", index, - devpriv->dma0Buff[index], devpriv->dma0BuffPhysAddr[index]); */ + devpriv->dma0Buff[index], + devpriv->dma0BuffPhysAddr[index]); */ } - /* setup DMA descriptor ring (use cpu_to_le32 for byte ordering?) */ + /* + * setup DMA descriptor ring (use cpu_to_le32 for byte + * ordering?) + */ devpriv->dma0Chain = pci_alloc_consistent(devpriv->pci_dev, sizeof(struct plx_dma_desc) * @@ -1254,7 +1271,8 @@ static int rtd520_probe_fifo_depth(struct comedi_device *dev) } } if (i == limit) { - printk(KERN_INFO "\ncomedi: %s: failed to probe fifo size.\n", DRV_NAME); + printk(KERN_INFO "\ncomedi: %s: failed to probe fifo size.\n", + DRV_NAME); return -EIO; } RtdAdcClearFifo(dev); @@ -1354,9 +1372,10 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, d = RtdAdcFifoGet(dev); /* get 2s comp value */ d = d >> 3; /* low 3 bits are marker lines */ - if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) - sample = d + 2048; /* convert to comedi unsigned data */ - else + if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) { + /* convert to comedi unsigned data */ + sample = d + 2048; + } else sample = d; if (!comedi_buf_put(s->async, sample)) @@ -1382,9 +1401,10 @@ static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s) } d = d >> 3; /* low 3 bits are marker lines */ - if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) - sample = d + 2048; /* convert to comedi unsigned data */ - else + if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) { + /* convert to comedi unsigned data */ + sample = d + 2048; + } else sample = d; if (!comedi_buf_put(s->async, sample)) @@ -1501,7 +1521,9 @@ static int ai_process_dma(struct comedi_device *dev, struct comedi_subdevice *s) comedi_buf_memcpy_to(s->async, 0, dp, n); comedi_buf_write_free(s->async, n); - /* always at least 1 scan -- 1/2 FIFO is larger than our max scan list */ + /* + * always at least 1 scan -- 1/2 FIFO is larger than our max scan list + */ s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; if (++devpriv->dma0Offset >= DMA_CHAIN_COUNT) { /* next buffer */ -- cgit v0.10.2 From 2d2111ea2cf25cc60f7027130ceb34af2d03745d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 1 May 2012 17:03:48 -0700 Subject: staging: comedi: fix build errors caused by module_init/module_exit refactor A couple build errors were introduced with the module_init/module_exit refactor. The struct comedi_driver variable was being accessed directly in the attach and detach routines. Instead of doing this, access the variable indirectly using the driver pointer in struct comedi_device. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c index 4846d98..a82b343 100644 --- a/drivers/staging/comedi/drivers/pcmda12.c +++ b/drivers/staging/comedi/drivers/pcmda12.c @@ -172,10 +172,10 @@ static int pcmda12_attach(struct comedi_device *dev, iobase = it->options[0]; printk(KERN_INFO - "comedi%d: %s: io: %lx %s ", dev->minor, driver.driver_name, + "comedi%d: %s: io: %lx %s ", dev->minor, dev->driver->driver_name, iobase, it->options[1] ? "simultaneous xfer mode enabled" : ""); - if (!request_region(iobase, IOSIZE, driver.driver_name)) { + if (!request_region(iobase, IOSIZE, dev->driver->driver_name)) { printk("I/O port conflict\n"); return -EIO; } @@ -230,7 +230,7 @@ static int pcmda12_attach(struct comedi_device *dev, static int pcmda12_detach(struct comedi_device *dev) { printk(KERN_INFO - "comedi%d: %s: remove\n", dev->minor, driver.driver_name); + "comedi%d: %s: remove\n", dev->minor, dev->driver->driver_name); if (dev->iobase) release_region(dev->iobase, IOSIZE); return 0; diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index d7f98d5..9ee1da5 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -1022,13 +1022,13 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) irq[0] = it->options[1]; printk(KERN_INFO "comedi%d: %s: io: %lx attaching...\n", dev->minor, - driver.driver_name, iobase); + dev->driver->driver_name, iobase); dev->iobase = iobase; if (!iobase || !request_region(iobase, thisboard->total_iosize, - driver.driver_name)) { + dev->driver->driver_name)) { printk(KERN_ERR "comedi%d: I/O port conflict\n", dev->minor); return -EIO; } @@ -1227,7 +1227,8 @@ static int pcmmio_detach(struct comedi_device *dev) { int i; - printk(KERN_INFO "comedi%d: %s: remove\n", dev->minor, driver.driver_name); + printk(KERN_INFO "comedi%d: %s: remove\n", dev->minor, + dev->driver->driver_name); if (dev->iobase) release_region(dev->iobase, thisboard->total_iosize); diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index de4f486..47a3ee6 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -757,13 +757,13 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) irq[1] = it->options[2]; dev_dbg(dev->hw_dev, "comedi%d: %s: io: %lx attached\n", dev->minor, - driver.driver_name, iobase); + dev->driver->driver_name, iobase); dev->iobase = iobase; if (!iobase || !request_region(iobase, thisboard->num_asics * ASIC_IOSIZE, - driver.driver_name)) { + dev->driver->driver_name)) { dev_err(dev->hw_dev, "I/O port conflict\n"); return -EIO; } @@ -913,7 +913,7 @@ static int pcmuio_detach(struct comedi_device *dev) int i; dev_dbg(dev->hw_dev, "comedi%d: %s: remove\n", dev->minor, - driver.driver_name); + dev->driver->driver_name); if (dev->iobase) release_region(dev->iobase, ASIC_IOSIZE * thisboard->num_asics); -- cgit v0.10.2 From e8ccc11fbd32d26884943ea2001c3dea6c7ea14a Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Wed, 2 May 2012 01:13:33 +0200 Subject: staging: iio: call iio_device_unregister() in max517_remove() Reported-by: Lars-Peter Clausen Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/dac/max517.c b/drivers/staging/iio/dac/max517.c index a3f588df..65d6349 100644 --- a/drivers/staging/iio/dac/max517.c +++ b/drivers/staging/iio/dac/max517.c @@ -264,6 +264,7 @@ exit: static int max517_remove(struct i2c_client *client) { + iio_device_unregister(i2c_get_clientdata(client)); iio_device_free(i2c_get_clientdata(client)); return 0; -- cgit v0.10.2 From 204162572ff4a679a47c68a5d5b3ac2bcba3830e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 1 May 2012 17:20:04 -0700 Subject: staging: comedi: Add helper macro for comedi_driver boilerplate Introduce the module_comedi_driver macro which is a convenience macro for comedi driver modules similar to module_platform_driver. It is intended to be used by drivers where the init/exit section does nothing but register/unregister the comedi driver. By using this macro it is possible to eliminate a few lines of boilerplate code per comedi driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 02e4ae0..8828609 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -298,6 +298,18 @@ int comedi_device_attach(struct comedi_device *dev, int comedi_driver_register(struct comedi_driver *); int comedi_driver_unregister(struct comedi_driver *); +/** + * module_comedi_driver() - Helper macro for registering a comedi driver + * @__comedi_driver: comedi_driver struct + * + * Helper macro for comedi drivers which do not do anything special in module + * init/exit. This eliminates a lot of boilerplate. Each module may only use + * this macro once, and calling it replaces module_init() and module_exit(). + */ +#define module_comedi_driver(__comedi_driver) \ + module_driver(__comedi_driver, comedi_driver_register, \ + comedi_driver_unregister) + void init_polling(void); void cleanup_polling(void); void start_polling(struct comedi_device *); -- cgit v0.10.2 From 61cd983c4c312b6a679f7ee3ba31aec20c044a41 Mon Sep 17 00:00:00 2001 From: Tomas Melin Date: Wed, 2 May 2012 19:15:17 +0300 Subject: Staging: Comedi adv_pci1710 : Corrected over 80 column warnings Indentation problems aswell as various comments and code lines longer than 80 chars fixed in file adv_pci1710.c Signed-off-by: Tomas Melin Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 9eaae0d..f3f6a65 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1222,14 +1222,14 @@ static void setup_channel_list(struct comedi_device *dev, DPRINTK("SegLen: %d\n", seglen); for (i = 0; i < seglen; i++) { /* store range list to card */ chanprog = muxonechan[CR_CHAN(chanlist[i])]; - outw(chanprog, dev->iobase + PCI171x_MUX); /* select channel */ + outw(chanprog, dev->iobase + PCI171x_MUX); /* select channel */ range = this_board->rangecode_ai[CR_RANGE(chanlist[i])]; if (CR_AREF(chanlist[i]) == AREF_DIFF) range |= 0x0020; - outw(range, dev->iobase + PCI171x_RANGE); /* select gain */ + outw(range, dev->iobase + PCI171x_RANGE); /* select gain */ #ifdef PCI171x_PARANOIDCHECK devpriv->act_chanlist[i] = - (CR_CHAN(chanlist[i]) << 12) & 0xf000; + (CR_CHAN(chanlist[i]) << 12) & 0xf000; #endif DPRINTK("GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range, devpriv->act_chanlist[i]); @@ -1237,13 +1237,14 @@ static void setup_channel_list(struct comedi_device *dev, #ifdef PCI171x_PARANOIDCHECK for ( ; i < n_chan; i++) { /* store remainder of channel list */ devpriv->act_chanlist[i] = - (CR_CHAN(chanlist[i]) << 12) & 0xf000; + (CR_CHAN(chanlist[i]) << 12) & 0xf000; } #endif devpriv->ai_et_MuxVal = - CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8); - outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX); /* select channel interval to scan */ + CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8); + /* select channel interval to scan */ + outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX); DPRINTK("MUX: %4x L%4x.H%4x\n", CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8), CR_CHAN(chanlist[0]), CR_CHAN(chanlist[seglen - 1])); -- cgit v0.10.2 From 8a508ff407ea2ac0ca731962e011fad1534b52e4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten lin Date: Wed, 2 May 2012 17:08:38 -0700 Subject: vme: vme_tsi148.c: local functions should not be exposed globally Functions not referenced outside of a source file should be marked static to prevent them from being exposed globally. Quiets the sparse warnings: warning: symbol 'tsi148_alloc_consistent' was not declared. Should it be static? warning: symbol 'tsi148_free_consistent' was not declared. Should it be static? Signed-off-by: H Hartley Sweeten Acked-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/vme/bridges/vme_tsi148.c b/drivers/vme/bridges/vme_tsi148.c index 081e9c4..f6385f7 100644 --- a/drivers/vme/bridges/vme_tsi148.c +++ b/drivers/vme/bridges/vme_tsi148.c @@ -2141,7 +2141,7 @@ static int tsi148_slot_get(struct vme_bridge *tsi148_bridge) return (int)slot; } -void *tsi148_alloc_consistent(struct device *parent, size_t size, +static void *tsi148_alloc_consistent(struct device *parent, size_t size, dma_addr_t *dma) { struct pci_dev *pdev; @@ -2152,8 +2152,8 @@ void *tsi148_alloc_consistent(struct device *parent, size_t size, return pci_alloc_consistent(pdev, size, dma); } -void tsi148_free_consistent(struct device *parent, size_t size, void *vaddr, - dma_addr_t dma) +static void tsi148_free_consistent(struct device *parent, size_t size, + void *vaddr, dma_addr_t dma) { struct pci_dev *pdev; -- cgit v0.10.2 From a11cfdf4589f2f9f70d398d123c459d33dfc6bb2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 2 May 2012 17:12:22 -0700 Subject: vme: vme_ca91cx42.c: local functions should not be exposed globally Functions not referenced outside of a source file should be marked static to prevent them from being exposed globally. Quiets the sparse warnings: warning: symbol 'ca91cx42_alloc_consistent' was not declared. Should it be static? warning: symbol 'ca91cx42_free_consistent' was not declared. Should it be static? Signed-off-by: H Hartley Sweeten Acked-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/vme/bridges/vme_ca91cx42.c b/drivers/vme/bridges/vme_ca91cx42.c index a3c0f84..e0df92e 100644 --- a/drivers/vme/bridges/vme_ca91cx42.c +++ b/drivers/vme/bridges/vme_ca91cx42.c @@ -1501,7 +1501,7 @@ static int ca91cx42_slot_get(struct vme_bridge *ca91cx42_bridge) } -void *ca91cx42_alloc_consistent(struct device *parent, size_t size, +static void *ca91cx42_alloc_consistent(struct device *parent, size_t size, dma_addr_t *dma) { struct pci_dev *pdev; @@ -1512,8 +1512,8 @@ void *ca91cx42_alloc_consistent(struct device *parent, size_t size, return pci_alloc_consistent(pdev, size, dma); } -void ca91cx42_free_consistent(struct device *parent, size_t size, void *vaddr, - dma_addr_t dma) +static void ca91cx42_free_consistent(struct device *parent, size_t size, + void *vaddr, dma_addr_t dma) { struct pci_dev *pdev; -- cgit v0.10.2 From cc4729826fd1a478f235fbcf58c0f97663f8d7e3 Mon Sep 17 00:00:00 2001 From: Martyn Welch Date: Thu, 3 May 2012 17:36:54 +0100 Subject: VME: Move API documentation to Documentation folder The documentation for the VME device driver API is currently in drivers/vme/vme_api.txt, move this to Documentation/vme_api.txt Signed-of-by: Martyn Welch Acked-by: Rob Landley Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/vme_api.txt b/Documentation/vme_api.txt new file mode 100644 index 0000000..856efa3 --- /dev/null +++ b/Documentation/vme_api.txt @@ -0,0 +1,396 @@ + VME Device Driver API + ===================== + +Driver registration +=================== + +As with other subsystems within the Linux kernel, VME device drivers register +with the VME subsystem, typically called from the devices init routine. This is +achieved via a call to the following function: + + int vme_register_driver (struct vme_driver *driver); + +If driver registration is successful this function returns zero, if an error +occurred a negative error code will be returned. + +A pointer to a structure of type 'vme_driver' must be provided to the +registration function. The structure is as follows: + + struct vme_driver { + struct list_head node; + const char *name; + int (*match)(struct vme_dev *); + int (*probe)(struct vme_dev *); + int (*remove)(struct vme_dev *); + void (*shutdown)(void); + struct device_driver driver; + struct list_head devices; + unsigned int ndev; + }; + +At the minimum, the '.name', '.match' and '.probe' elements of this structure +should be correctly set. The '.name' element is a pointer to a string holding +the device driver's name. + +The '.match' function allows controlling the number of devices that need to +be registered. The match function should return 1 if a device should be +probed and 0 otherwise. This example match function (from vme_user.c) limits +the number of devices probed to one: + + #define USER_BUS_MAX 1 + ... + static int vme_user_match(struct vme_dev *vdev) + { + if (vdev->id.num >= USER_BUS_MAX) + return 0; + return 1; + } + +The '.probe' element should contain a pointer to the probe routine. The +probe routine is passed a 'struct vme_dev' pointer as an argument. The +'struct vme_dev' structure looks like the following: + + struct vme_dev { + int num; + struct vme_bridge *bridge; + struct device dev; + struct list_head drv_list; + struct list_head bridge_list; + }; + +Here, the 'num' field refers to the sequential device ID for this specific +driver. The bridge number (or bus number) can be accessed using +dev->bridge->num. + +A function is also provided to unregister the driver from the VME core and is +usually called from the device driver's exit routine: + + void vme_unregister_driver (struct vme_driver *driver); + + +Resource management +=================== + +Once a driver has registered with the VME core the provided match routine will +be called the number of times specified during the registration. If a match +succeeds, a non-zero value should be returned. A zero return value indicates +failure. For all successful matches, the probe routine of the corresponding +driver is called. The probe routine is passed a pointer to the devices +device structure. This pointer should be saved, it will be required for +requesting VME resources. + +The driver can request ownership of one or more master windows, slave windows +and/or dma channels. Rather than allowing the device driver to request a +specific window or DMA channel (which may be used by a different driver) this +driver allows a resource to be assigned based on the required attributes of the +driver in question: + + struct vme_resource * vme_master_request(struct vme_dev *dev, + u32 aspace, u32 cycle, u32 width); + + struct vme_resource * vme_slave_request(struct vme_dev *dev, u32 aspace, + u32 cycle); + + struct vme_resource *vme_dma_request(struct vme_dev *dev, u32 route); + +For slave windows these attributes are split into the VME address spaces that +need to be accessed in 'aspace' and VME bus cycle types required in 'cycle'. +Master windows add a further set of attributes in 'width' specifying the +required data transfer widths. These attributes are defined as bitmasks and as +such any combination of the attributes can be requested for a single window, +the core will assign a window that meets the requirements, returning a pointer +of type vme_resource that should be used to identify the allocated resource +when it is used. For DMA controllers, the request function requires the +potential direction of any transfers to be provided in the route attributes. +This is typically VME-to-MEM and/or MEM-to-VME, though some hardware can +support VME-to-VME and MEM-to-MEM transfers as well as test pattern generation. +If an unallocated window fitting the requirements can not be found a NULL +pointer will be returned. + +Functions are also provided to free window allocations once they are no longer +required. These functions should be passed the pointer to the resource provided +during resource allocation: + + void vme_master_free(struct vme_resource *res); + + void vme_slave_free(struct vme_resource *res); + + void vme_dma_free(struct vme_resource *res); + + +Master windows +============== + +Master windows provide access from the local processor[s] out onto the VME bus. +The number of windows available and the available access modes is dependent on +the underlying chipset. A window must be configured before it can be used. + + +Master window configuration +--------------------------- + +Once a master window has been assigned the following functions can be used to +configure it and retrieve the current settings: + + int vme_master_set (struct vme_resource *res, int enabled, + unsigned long long base, unsigned long long size, u32 aspace, + u32 cycle, u32 width); + + int vme_master_get (struct vme_resource *res, int *enabled, + unsigned long long *base, unsigned long long *size, u32 *aspace, + u32 *cycle, u32 *width); + +The address spaces, transfer widths and cycle types are the same as described +under resource management, however some of the options are mutually exclusive. +For example, only one address space may be specified. + +These functions return 0 on success or an error code should the call fail. + + +Master window access +-------------------- + +The following functions can be used to read from and write to configured master +windows. These functions return the number of bytes copied: + + ssize_t vme_master_read(struct vme_resource *res, void *buf, + size_t count, loff_t offset); + + ssize_t vme_master_write(struct vme_resource *res, void *buf, + size_t count, loff_t offset); + +In addition to simple reads and writes, a function is provided to do a +read-modify-write transaction. This function returns the original value of the +VME bus location : + + unsigned int vme_master_rmw (struct vme_resource *res, + unsigned int mask, unsigned int compare, unsigned int swap, + loff_t offset); + +This functions by reading the offset, applying the mask. If the bits selected in +the mask match with the values of the corresponding bits in the compare field, +the value of swap is written the specified offset. + + +Slave windows +============= + +Slave windows provide devices on the VME bus access into mapped portions of the +local memory. The number of windows available and the access modes that can be +used is dependent on the underlying chipset. A window must be configured before +it can be used. + + +Slave window configuration +-------------------------- + +Once a slave window has been assigned the following functions can be used to +configure it and retrieve the current settings: + + int vme_slave_set (struct vme_resource *res, int enabled, + unsigned long long base, unsigned long long size, + dma_addr_t mem, u32 aspace, u32 cycle); + + int vme_slave_get (struct vme_resource *res, int *enabled, + unsigned long long *base, unsigned long long *size, + dma_addr_t *mem, u32 *aspace, u32 *cycle); + +The address spaces, transfer widths and cycle types are the same as described +under resource management, however some of the options are mutually exclusive. +For example, only one address space may be specified. + +These functions return 0 on success or an error code should the call fail. + + +Slave window buffer allocation +------------------------------ + +Functions are provided to allow the user to allocate and free a contiguous +buffers which will be accessible by the VME bridge. These functions do not have +to be used, other methods can be used to allocate a buffer, though care must be +taken to ensure that they are contiguous and accessible by the VME bridge: + + void * vme_alloc_consistent(struct vme_resource *res, size_t size, + dma_addr_t *mem); + + void vme_free_consistent(struct vme_resource *res, size_t size, + void *virt, dma_addr_t mem); + + +Slave window access +------------------- + +Slave windows map local memory onto the VME bus, the standard methods for +accessing memory should be used. + + +DMA channels +============ + +The VME DMA transfer provides the ability to run link-list DMA transfers. The +API introduces the concept of DMA lists. Each DMA list is a link-list which can +be passed to a DMA controller. Multiple lists can be created, extended, +executed, reused and destroyed. + + +List Management +--------------- + +The following functions are provided to create and destroy DMA lists. Execution +of a list will not automatically destroy the list, thus enabling a list to be +reused for repetitive tasks: + + struct vme_dma_list *vme_new_dma_list(struct vme_resource *res); + + int vme_dma_list_free(struct vme_dma_list *list); + + +List Population +--------------- + +An item can be added to a list using the following function ( the source and +destination attributes need to be created before calling this function, this is +covered under "Transfer Attributes"): + + int vme_dma_list_add(struct vme_dma_list *list, + struct vme_dma_attr *src, struct vme_dma_attr *dest, + size_t count); + +NOTE: The detailed attributes of the transfers source and destination + are not checked until an entry is added to a DMA list, the request + for a DMA channel purely checks the directions in which the + controller is expected to transfer data. As a result it is + possible for this call to return an error, for example if the + source or destination is in an unsupported VME address space. + +Transfer Attributes +------------------- + +The attributes for the source and destination are handled separately from adding +an item to a list. This is due to the diverse attributes required for each type +of source and destination. There are functions to create attributes for PCI, VME +and pattern sources and destinations (where appropriate): + +Pattern source: + + struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, u32 type); + +PCI source or destination: + + struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t mem); + +VME source or destination: + + struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long base, + u32 aspace, u32 cycle, u32 width); + +The following function should be used to free an attribute: + + void vme_dma_free_attribute(struct vme_dma_attr *attr); + + +List Execution +-------------- + +The following function queues a list for execution. The function will return +once the list has been executed: + + int vme_dma_list_exec(struct vme_dma_list *list); + + +Interrupts +========== + +The VME API provides functions to attach and detach callbacks to specific VME +level and status ID combinations and for the generation of VME interrupts with +specific VME level and status IDs. + + +Attaching Interrupt Handlers +---------------------------- + +The following functions can be used to attach and free a specific VME level and +status ID combination. Any given combination can only be assigned a single +callback function. A void pointer parameter is provided, the value of which is +passed to the callback function, the use of this pointer is user undefined: + + int vme_irq_request(struct vme_dev *dev, int level, int statid, + void (*callback)(int, int, void *), void *priv); + + void vme_irq_free(struct vme_dev *dev, int level, int statid); + +The callback parameters are as follows. Care must be taken in writing a callback +function, callback functions run in interrupt context: + + void callback(int level, int statid, void *priv); + + +Interrupt Generation +-------------------- + +The following function can be used to generate a VME interrupt at a given VME +level and VME status ID: + + int vme_irq_generate(struct vme_dev *dev, int level, int statid); + + +Location monitors +================= + +The VME API provides the following functionality to configure the location +monitor. + + +Location Monitor Management +--------------------------- + +The following functions are provided to request the use of a block of location +monitors and to free them after they are no longer required: + + struct vme_resource * vme_lm_request(struct vme_dev *dev); + + void vme_lm_free(struct vme_resource * res); + +Each block may provide a number of location monitors, monitoring adjacent +locations. The following function can be used to determine how many locations +are provided: + + int vme_lm_count(struct vme_resource * res); + + +Location Monitor Configuration +------------------------------ + +Once a bank of location monitors has been allocated, the following functions +are provided to configure the location and mode of the location monitor: + + int vme_lm_set(struct vme_resource *res, unsigned long long base, + u32 aspace, u32 cycle); + + int vme_lm_get(struct vme_resource *res, unsigned long long *base, + u32 *aspace, u32 *cycle); + + +Location Monitor Use +-------------------- + +The following functions allow a callback to be attached and detached from each +location monitor location. Each location monitor can monitor a number of +adjacent locations: + + int vme_lm_attach(struct vme_resource *res, int num, + void (*callback)(int)); + + int vme_lm_detach(struct vme_resource *res, int num); + +The callback function is declared as follows. + + void callback(int num); + + +Slot Detection +============== + +This function returns the slot ID of the provided bridge. + + int vme_slot_get(struct vme_dev *dev); diff --git a/drivers/vme/vme_api.txt b/drivers/vme/vme_api.txt deleted file mode 100644 index 856efa3..0000000 --- a/drivers/vme/vme_api.txt +++ /dev/null @@ -1,396 +0,0 @@ - VME Device Driver API - ===================== - -Driver registration -=================== - -As with other subsystems within the Linux kernel, VME device drivers register -with the VME subsystem, typically called from the devices init routine. This is -achieved via a call to the following function: - - int vme_register_driver (struct vme_driver *driver); - -If driver registration is successful this function returns zero, if an error -occurred a negative error code will be returned. - -A pointer to a structure of type 'vme_driver' must be provided to the -registration function. The structure is as follows: - - struct vme_driver { - struct list_head node; - const char *name; - int (*match)(struct vme_dev *); - int (*probe)(struct vme_dev *); - int (*remove)(struct vme_dev *); - void (*shutdown)(void); - struct device_driver driver; - struct list_head devices; - unsigned int ndev; - }; - -At the minimum, the '.name', '.match' and '.probe' elements of this structure -should be correctly set. The '.name' element is a pointer to a string holding -the device driver's name. - -The '.match' function allows controlling the number of devices that need to -be registered. The match function should return 1 if a device should be -probed and 0 otherwise. This example match function (from vme_user.c) limits -the number of devices probed to one: - - #define USER_BUS_MAX 1 - ... - static int vme_user_match(struct vme_dev *vdev) - { - if (vdev->id.num >= USER_BUS_MAX) - return 0; - return 1; - } - -The '.probe' element should contain a pointer to the probe routine. The -probe routine is passed a 'struct vme_dev' pointer as an argument. The -'struct vme_dev' structure looks like the following: - - struct vme_dev { - int num; - struct vme_bridge *bridge; - struct device dev; - struct list_head drv_list; - struct list_head bridge_list; - }; - -Here, the 'num' field refers to the sequential device ID for this specific -driver. The bridge number (or bus number) can be accessed using -dev->bridge->num. - -A function is also provided to unregister the driver from the VME core and is -usually called from the device driver's exit routine: - - void vme_unregister_driver (struct vme_driver *driver); - - -Resource management -=================== - -Once a driver has registered with the VME core the provided match routine will -be called the number of times specified during the registration. If a match -succeeds, a non-zero value should be returned. A zero return value indicates -failure. For all successful matches, the probe routine of the corresponding -driver is called. The probe routine is passed a pointer to the devices -device structure. This pointer should be saved, it will be required for -requesting VME resources. - -The driver can request ownership of one or more master windows, slave windows -and/or dma channels. Rather than allowing the device driver to request a -specific window or DMA channel (which may be used by a different driver) this -driver allows a resource to be assigned based on the required attributes of the -driver in question: - - struct vme_resource * vme_master_request(struct vme_dev *dev, - u32 aspace, u32 cycle, u32 width); - - struct vme_resource * vme_slave_request(struct vme_dev *dev, u32 aspace, - u32 cycle); - - struct vme_resource *vme_dma_request(struct vme_dev *dev, u32 route); - -For slave windows these attributes are split into the VME address spaces that -need to be accessed in 'aspace' and VME bus cycle types required in 'cycle'. -Master windows add a further set of attributes in 'width' specifying the -required data transfer widths. These attributes are defined as bitmasks and as -such any combination of the attributes can be requested for a single window, -the core will assign a window that meets the requirements, returning a pointer -of type vme_resource that should be used to identify the allocated resource -when it is used. For DMA controllers, the request function requires the -potential direction of any transfers to be provided in the route attributes. -This is typically VME-to-MEM and/or MEM-to-VME, though some hardware can -support VME-to-VME and MEM-to-MEM transfers as well as test pattern generation. -If an unallocated window fitting the requirements can not be found a NULL -pointer will be returned. - -Functions are also provided to free window allocations once they are no longer -required. These functions should be passed the pointer to the resource provided -during resource allocation: - - void vme_master_free(struct vme_resource *res); - - void vme_slave_free(struct vme_resource *res); - - void vme_dma_free(struct vme_resource *res); - - -Master windows -============== - -Master windows provide access from the local processor[s] out onto the VME bus. -The number of windows available and the available access modes is dependent on -the underlying chipset. A window must be configured before it can be used. - - -Master window configuration ---------------------------- - -Once a master window has been assigned the following functions can be used to -configure it and retrieve the current settings: - - int vme_master_set (struct vme_resource *res, int enabled, - unsigned long long base, unsigned long long size, u32 aspace, - u32 cycle, u32 width); - - int vme_master_get (struct vme_resource *res, int *enabled, - unsigned long long *base, unsigned long long *size, u32 *aspace, - u32 *cycle, u32 *width); - -The address spaces, transfer widths and cycle types are the same as described -under resource management, however some of the options are mutually exclusive. -For example, only one address space may be specified. - -These functions return 0 on success or an error code should the call fail. - - -Master window access --------------------- - -The following functions can be used to read from and write to configured master -windows. These functions return the number of bytes copied: - - ssize_t vme_master_read(struct vme_resource *res, void *buf, - size_t count, loff_t offset); - - ssize_t vme_master_write(struct vme_resource *res, void *buf, - size_t count, loff_t offset); - -In addition to simple reads and writes, a function is provided to do a -read-modify-write transaction. This function returns the original value of the -VME bus location : - - unsigned int vme_master_rmw (struct vme_resource *res, - unsigned int mask, unsigned int compare, unsigned int swap, - loff_t offset); - -This functions by reading the offset, applying the mask. If the bits selected in -the mask match with the values of the corresponding bits in the compare field, -the value of swap is written the specified offset. - - -Slave windows -============= - -Slave windows provide devices on the VME bus access into mapped portions of the -local memory. The number of windows available and the access modes that can be -used is dependent on the underlying chipset. A window must be configured before -it can be used. - - -Slave window configuration --------------------------- - -Once a slave window has been assigned the following functions can be used to -configure it and retrieve the current settings: - - int vme_slave_set (struct vme_resource *res, int enabled, - unsigned long long base, unsigned long long size, - dma_addr_t mem, u32 aspace, u32 cycle); - - int vme_slave_get (struct vme_resource *res, int *enabled, - unsigned long long *base, unsigned long long *size, - dma_addr_t *mem, u32 *aspace, u32 *cycle); - -The address spaces, transfer widths and cycle types are the same as described -under resource management, however some of the options are mutually exclusive. -For example, only one address space may be specified. - -These functions return 0 on success or an error code should the call fail. - - -Slave window buffer allocation ------------------------------- - -Functions are provided to allow the user to allocate and free a contiguous -buffers which will be accessible by the VME bridge. These functions do not have -to be used, other methods can be used to allocate a buffer, though care must be -taken to ensure that they are contiguous and accessible by the VME bridge: - - void * vme_alloc_consistent(struct vme_resource *res, size_t size, - dma_addr_t *mem); - - void vme_free_consistent(struct vme_resource *res, size_t size, - void *virt, dma_addr_t mem); - - -Slave window access -------------------- - -Slave windows map local memory onto the VME bus, the standard methods for -accessing memory should be used. - - -DMA channels -============ - -The VME DMA transfer provides the ability to run link-list DMA transfers. The -API introduces the concept of DMA lists. Each DMA list is a link-list which can -be passed to a DMA controller. Multiple lists can be created, extended, -executed, reused and destroyed. - - -List Management ---------------- - -The following functions are provided to create and destroy DMA lists. Execution -of a list will not automatically destroy the list, thus enabling a list to be -reused for repetitive tasks: - - struct vme_dma_list *vme_new_dma_list(struct vme_resource *res); - - int vme_dma_list_free(struct vme_dma_list *list); - - -List Population ---------------- - -An item can be added to a list using the following function ( the source and -destination attributes need to be created before calling this function, this is -covered under "Transfer Attributes"): - - int vme_dma_list_add(struct vme_dma_list *list, - struct vme_dma_attr *src, struct vme_dma_attr *dest, - size_t count); - -NOTE: The detailed attributes of the transfers source and destination - are not checked until an entry is added to a DMA list, the request - for a DMA channel purely checks the directions in which the - controller is expected to transfer data. As a result it is - possible for this call to return an error, for example if the - source or destination is in an unsupported VME address space. - -Transfer Attributes -------------------- - -The attributes for the source and destination are handled separately from adding -an item to a list. This is due to the diverse attributes required for each type -of source and destination. There are functions to create attributes for PCI, VME -and pattern sources and destinations (where appropriate): - -Pattern source: - - struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, u32 type); - -PCI source or destination: - - struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t mem); - -VME source or destination: - - struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long base, - u32 aspace, u32 cycle, u32 width); - -The following function should be used to free an attribute: - - void vme_dma_free_attribute(struct vme_dma_attr *attr); - - -List Execution --------------- - -The following function queues a list for execution. The function will return -once the list has been executed: - - int vme_dma_list_exec(struct vme_dma_list *list); - - -Interrupts -========== - -The VME API provides functions to attach and detach callbacks to specific VME -level and status ID combinations and for the generation of VME interrupts with -specific VME level and status IDs. - - -Attaching Interrupt Handlers ----------------------------- - -The following functions can be used to attach and free a specific VME level and -status ID combination. Any given combination can only be assigned a single -callback function. A void pointer parameter is provided, the value of which is -passed to the callback function, the use of this pointer is user undefined: - - int vme_irq_request(struct vme_dev *dev, int level, int statid, - void (*callback)(int, int, void *), void *priv); - - void vme_irq_free(struct vme_dev *dev, int level, int statid); - -The callback parameters are as follows. Care must be taken in writing a callback -function, callback functions run in interrupt context: - - void callback(int level, int statid, void *priv); - - -Interrupt Generation --------------------- - -The following function can be used to generate a VME interrupt at a given VME -level and VME status ID: - - int vme_irq_generate(struct vme_dev *dev, int level, int statid); - - -Location monitors -================= - -The VME API provides the following functionality to configure the location -monitor. - - -Location Monitor Management ---------------------------- - -The following functions are provided to request the use of a block of location -monitors and to free them after they are no longer required: - - struct vme_resource * vme_lm_request(struct vme_dev *dev); - - void vme_lm_free(struct vme_resource * res); - -Each block may provide a number of location monitors, monitoring adjacent -locations. The following function can be used to determine how many locations -are provided: - - int vme_lm_count(struct vme_resource * res); - - -Location Monitor Configuration ------------------------------- - -Once a bank of location monitors has been allocated, the following functions -are provided to configure the location and mode of the location monitor: - - int vme_lm_set(struct vme_resource *res, unsigned long long base, - u32 aspace, u32 cycle); - - int vme_lm_get(struct vme_resource *res, unsigned long long *base, - u32 *aspace, u32 *cycle); - - -Location Monitor Use --------------------- - -The following functions allow a callback to be attached and detached from each -location monitor location. Each location monitor can monitor a number of -adjacent locations: - - int vme_lm_attach(struct vme_resource *res, int num, - void (*callback)(int)); - - int vme_lm_detach(struct vme_resource *res, int num); - -The callback function is declared as follows. - - void callback(int num); - - -Slot Detection -============== - -This function returns the slot ID of the provided bridge. - - int vme_slot_get(struct vme_dev *dev); -- cgit v0.10.2 From 390beae4f843d4d2c4adfdedc1e3d633f9d3945f Mon Sep 17 00:00:00 2001 From: Martyn Welch Date: Thu, 3 May 2012 17:52:36 +0100 Subject: MAINTAINERS: Add maintainers for VME subsystem Add Martyn Welch, Manohar Vanga and Greg Kroah-Hartman as maintainers for the VME subsystem. Signed-off-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman diff --git a/MAINTAINERS b/MAINTAINERS index 216dbf3..4e8ace8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7313,6 +7313,18 @@ S: Maintained F: drivers/vlynq/vlynq.c F: include/linux/vlynq.h +VME SUBSYSTEM +M: Martyn Welch +M: Manohar Vanga +M: Greg Kroah-Hartman +L: devel@driverdev.osuosl.org +S: Maintained +T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git +F: Documentation/vme_api.txt +F: drivers/staging/vme/ +F: drivers/vme/ +F: include/linux/vme* + VMWARE VMXNET3 ETHERNET DRIVER M: Shreyas Bhatewara M: "VMware, Inc." -- cgit v0.10.2 From 5a28c87397655cb0d791d04e45bd7cd5691ba0f2 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 3 May 2012 09:50:51 +0800 Subject: IIO: industrialio-core: Use simple_open Use simple_open to replace iio_debugfs_open. Signed-off-by: Axel Lin Acked-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 72e33b8..52aa44a 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -152,14 +152,6 @@ static void __exit iio_exit(void) } #if defined(CONFIG_DEBUG_FS) -static int iio_debugfs_open(struct inode *inode, struct file *file) -{ - if (inode->i_private) - file->private_data = inode->i_private; - - return 0; -} - static ssize_t iio_debugfs_read_reg(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { @@ -218,7 +210,7 @@ static ssize_t iio_debugfs_write_reg(struct file *file, } static const struct file_operations iio_debugfs_reg_fops = { - .open = iio_debugfs_open, + .open = simple_open, .read = iio_debugfs_read_reg, .write = iio_debugfs_write_reg, }; -- cgit v0.10.2 From abd5a2fb3957b5a6eb8083044a61e1b95b770abf Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 3 May 2012 22:56:58 +0800 Subject: IIO: industrialio-core: Checking NULL instead of IS_ERR for debugfs_create_dir() If defined CONFIG_DEBUG_FS, debugfs_create_dir returns NULL on failure. Signed-off-by: Axel Lin Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 52aa44a..b39a587 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -227,15 +227,12 @@ static int iio_device_register_debugfs(struct iio_dev *indio_dev) if (indio_dev->info->debugfs_reg_access == NULL) return 0; - if (IS_ERR(iio_debugfs_dentry)) + if (!iio_debugfs_dentry) return 0; indio_dev->debugfs_dentry = debugfs_create_dir(dev_name(&indio_dev->dev), iio_debugfs_dentry); - if (IS_ERR(indio_dev->debugfs_dentry)) - return PTR_ERR(indio_dev->debugfs_dentry); - if (indio_dev->debugfs_dentry == NULL) { dev_warn(indio_dev->dev.parent, "Failed to create debugfs directory\n"); -- cgit v0.10.2 From 99de0c2b341fc2d0f41ca9eadaa752c651c06b83 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 9 May 2012 03:18:17 +0900 Subject: staging: iio: Fix typo in iio Correct spelling typo in staging/iio Signed-off-by: Masanari Iida Acked-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/iio/TODO b/drivers/staging/iio/TODO index d1ad35e..cf3f948 100644 --- a/drivers/staging/iio/TODO +++ b/drivers/staging/iio/TODO @@ -67,7 +67,7 @@ e-mailing the normal IIO list (see below). Documentation 1) Lots of cleanup and expansion. -2) Some device require indvidual docs. +2) Some device require individual docs. Contact: Jonathan Cameron . Mailing list: linux-iio@vger.kernel.org diff --git a/drivers/staging/iio/gyro/adxrs450.h b/drivers/staging/iio/gyro/adxrs450.h index af0c870..f8cf21f 100644 --- a/drivers/staging/iio/gyro/adxrs450.h +++ b/drivers/staging/iio/gyro/adxrs450.h @@ -49,7 +49,7 @@ enum { * @us: actual spi_device * @buf_lock: mutex to protect tx and rx * @tx: transmit buffer - * @rx: recieve buffer + * @rx: receive buffer **/ struct adxrs450_state { struct spi_device *us; diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c index 3726065..fdfc873 100644 --- a/drivers/staging/iio/iio_simple_dummy_buffer.c +++ b/drivers/staging/iio/iio_simple_dummy_buffer.c @@ -37,7 +37,7 @@ static const s16 fakedata[] = { * @irq: the interrupt number * @p: private data - always a pointer to the poll func. * - * This is the guts of buffered capture. On a trigger event occuring, + * This is the guts of buffered capture. On a trigger event occurring, * if the pollfunc is attached then this handler is called as a threaded * interrupt (and hence may sleep). It is responsible for grabbing data * from the device and pushing it into the associated buffer. @@ -61,7 +61,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) * up a fast read. The capture will consist of all of them. * Hence we just call the grab data function and fill the * buffer without processing. - * sofware scans: can be considered to be random access + * software scans: can be considered to be random access * so efficient reading is just a case of minimal bus * transactions. * software culled hardware scans: diff --git a/drivers/staging/iio/iio_simple_dummy_events.c b/drivers/staging/iio/iio_simple_dummy_events.c index f85bd19..317b774 100644 --- a/drivers/staging/iio/iio_simple_dummy_events.c +++ b/drivers/staging/iio/iio_simple_dummy_events.c @@ -122,7 +122,7 @@ int iio_simple_dummy_write_event_value(struct iio_dev *indio_dev, * @private: pointer to device instance state. * * This handler is responsible for querying the device to find out what - * event occured and for then pushing that event towards userspace. + * event occurred and for then pushing that event towards userspace. * Here only one event occurs so we push that directly on with locally * grabbed timestamp. */ -- cgit v0.10.2 From 01fdf901de6d1f0a6164c2cb6eb2f8eacffdf228 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Tue, 8 May 2012 00:26:07 +0900 Subject: staging: ramster: Fix typo in zcache-main.c Correct spelling typo in zcache-main.c Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ramster/zcache-main.c b/drivers/staging/ramster/zcache-main.c index c071111..4e7ef0e 100644 --- a/drivers/staging/ramster/zcache-main.c +++ b/drivers/staging/ramster/zcache-main.c @@ -1331,7 +1331,7 @@ static ssize_t zv_max_mean_zsize_store(struct kobject *kobj, * when that limit is reached, further puts will be rejected (until * some pages have been flushed). Note that, due to compression, * this number may exceed 100; it defaults to 75 and we set an - * arbitary limit of 150. A poor choice will almost certainly result + * arbitrary limit of 150. A poor choice will almost certainly result * in OOM's, so this value should only be changed prudently. */ static ssize_t zv_page_count_policy_percent_show(struct kobject *kobj, @@ -2004,7 +2004,7 @@ int zcache_pampd_replace_in_obj(void *new_pampd, struct tmem_obj *obj) * Called by the message handler after a (still compressed) page has been * fetched from the remote machine in response to an "is_remote" tmem_get * or persistent tmem_localify. For a tmem_get, "extra" is the address of - * the page that is to be filled to succesfully resolve the tmem_get; for + * the page that is to be filled to successfully resolve the tmem_get; for * a (persistent) tmem_localify, "extra" is NULL (as the data is placed only * in the local zcache). "data" points to "size" bytes of (compressed) data * passed in the message. In the case of a persistent remote get, if -- cgit v0.10.2 From 71a30f68c608084fd53a3de5fe5614e24fe6729e Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Mon, 7 May 2012 13:02:22 +0200 Subject: staging: ramster: depend on NET for sock_* functions Building ramster without NET would cause linkage issue due to missing sock_*() functions in cluster/tcp.c Signed-off-by: Sasha Levin Acked-by: Dan Magenheimer Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ramster/Kconfig b/drivers/staging/ramster/Kconfig index 4af1f8d..8349887 100644 --- a/drivers/staging/ramster/Kconfig +++ b/drivers/staging/ramster/Kconfig @@ -1,6 +1,6 @@ config RAMSTER bool "Cross-machine RAM capacity sharing, aka peer-to-peer tmem" - depends on (CLEANCACHE || FRONTSWAP) && CONFIGFS_FS=y && !ZCACHE && !XVMALLOC && !HIGHMEM + depends on (CLEANCACHE || FRONTSWAP) && CONFIGFS_FS=y && !ZCACHE && !XVMALLOC && !HIGHMEM && NET select LZO_COMPRESS select LZO_DECOMPRESS default n -- cgit v0.10.2 From 2e3b61547191a5934ff6c789aaa4d7e9a9e52f5a Mon Sep 17 00:00:00 2001 From: Minchan Kim Date: Thu, 3 May 2012 15:40:39 +0900 Subject: staging: zsmalloc: rename zspage_order with zspage_pages zspage_order defines how many pages are needed to make a zspage. So _order_ is rather awkward naming. It already deceive Jonathan - http://lwn.net/Articles/477067/ " For each size, the code calculates an optimum number of pages (up to 16)" Let's change from _order_ to _pages_ and some function names. Signed-off-by: Minchan Kim Acked-by: Nitin Gupta Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c index 504b6c2..8642800 100644 --- a/drivers/staging/zsmalloc/zsmalloc-main.c +++ b/drivers/staging/zsmalloc/zsmalloc-main.c @@ -180,7 +180,7 @@ out: * link together 3 PAGE_SIZE sized pages to form a zspage * since then we can perfectly fit in 8 such objects. */ -static int get_zspage_order(int class_size) +static int get_pages_per_zspage(int class_size) { int i, max_usedpc = 0; /* zspage order which gives maximum used size per KB */ @@ -368,7 +368,7 @@ static struct page *alloc_zspage(struct size_class *class, gfp_t flags) * identify the last page. */ error = -ENOMEM; - for (i = 0; i < class->zspage_order; i++) { + for (i = 0; i < class->pages_per_zspage; i++) { struct page *page, *prev_page; page = alloc_page(flags); @@ -388,7 +388,7 @@ static struct page *alloc_zspage(struct size_class *class, gfp_t flags) page->first_page = first_page; if (i >= 2) list_add(&page->lru, &prev_page->lru); - if (i == class->zspage_order - 1) /* last page */ + if (i == class->pages_per_zspage - 1) /* last page */ SetPagePrivate2(page); prev_page = page; } @@ -397,7 +397,7 @@ static struct page *alloc_zspage(struct size_class *class, gfp_t flags) first_page->freelist = obj_location_to_handle(first_page, 0); /* Maximum number of objects we can store in this zspage */ - first_page->objects = class->zspage_order * PAGE_SIZE / class->size; + first_page->objects = class->pages_per_zspage * PAGE_SIZE / class->size; error = 0; /* Success */ @@ -512,7 +512,7 @@ struct zs_pool *zs_create_pool(const char *name, gfp_t flags) class->size = size; class->index = i; spin_lock_init(&class->lock); - class->zspage_order = get_zspage_order(size); + class->pages_per_zspage = get_pages_per_zspage(size); } @@ -603,7 +603,7 @@ void *zs_malloc(struct zs_pool *pool, size_t size) set_zspage_mapping(first_page, class->index, ZS_EMPTY); spin_lock(&class->lock); - class->pages_allocated += class->zspage_order; + class->pages_allocated += class->pages_per_zspage; } obj = first_page->freelist; @@ -658,7 +658,7 @@ void zs_free(struct zs_pool *pool, void *obj) fullness = fix_fullness_group(pool, first_page); if (fullness == ZS_EMPTY) - class->pages_allocated -= class->zspage_order; + class->pages_allocated -= class->pages_per_zspage; spin_unlock(&class->lock); diff --git a/drivers/staging/zsmalloc/zsmalloc_int.h b/drivers/staging/zsmalloc/zsmalloc_int.h index 92eefc6..6fd32a9 100644 --- a/drivers/staging/zsmalloc/zsmalloc_int.h +++ b/drivers/staging/zsmalloc/zsmalloc_int.h @@ -124,7 +124,7 @@ struct size_class { unsigned int index; /* Number of PAGE_SIZE sized pages to combine to form a 'zspage' */ - int zspage_order; + int pages_per_zspage; spinlock_t lock; -- cgit v0.10.2 From 00a61d8618bb7314113eb3ba27c12631cd85c298 Mon Sep 17 00:00:00 2001 From: Minchan Kim Date: Thu, 3 May 2012 15:40:40 +0900 Subject: staging: zsmalloc: add/fix function comment Add/fix the comment. Signed-off-by: Minchan Kim Acked-by: Nitin Gupta Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c index 8642800..4496737 100644 --- a/drivers/staging/zsmalloc/zsmalloc-main.c +++ b/drivers/staging/zsmalloc/zsmalloc-main.c @@ -566,13 +566,9 @@ EXPORT_SYMBOL_GPL(zs_destroy_pool); * zs_malloc - Allocate block of given size from pool. * @pool: pool to allocate from * @size: size of block to allocate - * @page: page no. that holds the object - * @offset: location of object within page - * - * On success, identifies block allocated - * and 0 is returned. On failure, is set to - * 0 and -ENOMEM is returned. * + * On success, handle to the allocated object is returned, + * otherwise NULL. * Allocation requests with size > ZS_MAX_ALLOC_SIZE will fail. */ void *zs_malloc(struct zs_pool *pool, size_t size) @@ -667,6 +663,15 @@ void zs_free(struct zs_pool *pool, void *obj) } EXPORT_SYMBOL_GPL(zs_free); +/** + * zs_map_object - get address of allocated object from handle. + * @pool: pool from which the object was allocated + * @handle: handle returned from zs_malloc + * + * Before using an object allocated from zs_malloc, it must be mapped using + * this function. When done with the object, it must be unmapped using + * zs_unmap_object +*/ void *zs_map_object(struct zs_pool *pool, void *handle) { struct page *page; -- cgit v0.10.2 From 41d8cc1ac2fd5c4695ef0c8239ac0f45e1cd72ca Mon Sep 17 00:00:00 2001 From: Tomas Melin Date: Mon, 7 May 2012 22:49:11 +0300 Subject: Staging: Comedi adv_pci1710: Move check forward Simplifies function logic by assuming that n_chan >1 if not <=1. Removes one level of indentation. Signed-off-by: Tomas Melin Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index f3f6a65..ff098c0 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1161,48 +1161,47 @@ static int check_channel_list(struct comedi_device *dev, return 0; } - if (n_chan > 1) { - chansegment[0] = chanlist[0]; /* first channel is every time ok */ - for (i = 1, seglen = 1; i < n_chan; i++, seglen++) { /* build part of chanlist */ - /* printk("%d. %d %d\n",i,CR_CHAN(chanlist[i]),CR_RANGE(chanlist[i])); */ - if (chanlist[0] == chanlist[i]) - break; /* we detect loop, this must by finish */ - if (CR_CHAN(chanlist[i]) & 1) /* odd channel cann't by differencial */ - if (CR_AREF(chanlist[i]) == AREF_DIFF) { - comedi_error(dev, - "Odd channel can't be differential input!\n"); - return 0; - } - nowmustbechan = - (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan; - if (CR_AREF(chansegment[i - 1]) == AREF_DIFF) - nowmustbechan = (nowmustbechan + 1) % s->n_chan; - if (nowmustbechan != CR_CHAN(chanlist[i])) { /* channel list isn't continuous :-( */ - printk - ("channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n", - i, CR_CHAN(chanlist[i]), nowmustbechan, - CR_CHAN(chanlist[0])); + if (n_chan == 1) + return 1; /* seglen=1 */ + + chansegment[0] = chanlist[0]; /* first channel is every time ok */ + for (i = 1, seglen = 1; i < n_chan; i++, seglen++) { /* build part of chanlist */ + /* printk("%d. %d %d\n",i,CR_CHAN(chanlist[i]),CR_RANGE(chanlist[i])); */ + if (chanlist[0] == chanlist[i]) + break; /* we detect loop, this must by finish */ + if (CR_CHAN(chanlist[i]) & 1) /* odd channel cann't by differencial */ + if (CR_AREF(chanlist[i]) == AREF_DIFF) { + comedi_error(dev, + "Odd channel can't be differential input!\n"); return 0; } - chansegment[i] = chanlist[i]; /* well, this is next correct channel in list */ + nowmustbechan = + (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan; + if (CR_AREF(chansegment[i - 1]) == AREF_DIFF) + nowmustbechan = (nowmustbechan + 1) % s->n_chan; + if (nowmustbechan != CR_CHAN(chanlist[i])) { /* channel list isn't continuous :-( */ + printk + ("channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n", + i, CR_CHAN(chanlist[i]), nowmustbechan, + CR_CHAN(chanlist[0])); + return 0; } + chansegment[i] = chanlist[i]; /* well, this is next correct channel in list */ + } - for (i = 0, segpos = 0; i < n_chan; i++) { /* check whole chanlist */ - /* printk("%d %d=%d %d\n",CR_CHAN(chansegment[i%seglen]),CR_RANGE(chansegment[i%seglen]),CR_CHAN(chanlist[i]),CR_RANGE(chanlist[i])); */ - if (chanlist[i] != chansegment[i % seglen]) { - printk - ("bad channel, reference or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n", - i, CR_CHAN(chansegment[i]), - CR_RANGE(chansegment[i]), - CR_AREF(chansegment[i]), - CR_CHAN(chanlist[i % seglen]), - CR_RANGE(chanlist[i % seglen]), - CR_AREF(chansegment[i % seglen])); - return 0; /* chan/gain list is strange */ - } + for (i = 0, segpos = 0; i < n_chan; i++) { /* check whole chanlist */ + /* printk("%d %d=%d %d\n",CR_CHAN(chansegment[i%seglen]),CR_RANGE(chansegment[i%seglen]),CR_CHAN(chanlist[i]),CR_RANGE(chanlist[i])); */ + if (chanlist[i] != chansegment[i % seglen]) { + printk + ("bad channel, reference or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n", + i, CR_CHAN(chansegment[i]), + CR_RANGE(chansegment[i]), + CR_AREF(chansegment[i]), + CR_CHAN(chanlist[i % seglen]), + CR_RANGE(chanlist[i % seglen]), + CR_AREF(chansegment[i % seglen])); + return 0; /* chan/gain list is strange */ } - } else { - seglen = 1; } return seglen; } -- cgit v0.10.2 From 2e0031dd9078ba980bb664b144355c5ff6d6a030 Mon Sep 17 00:00:00 2001 From: Tomas Melin Date: Mon, 7 May 2012 22:49:48 +0300 Subject: Staging: Comedi adv_pci1710: Cleaned up comments Removed useless comments and cleaned up text. Signed-off-by: Tomas Melin Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index ff098c0..6dd4f4a 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1164,33 +1164,31 @@ static int check_channel_list(struct comedi_device *dev, if (n_chan == 1) return 1; /* seglen=1 */ - chansegment[0] = chanlist[0]; /* first channel is every time ok */ - for (i = 1, seglen = 1; i < n_chan; i++, seglen++) { /* build part of chanlist */ - /* printk("%d. %d %d\n",i,CR_CHAN(chanlist[i]),CR_RANGE(chanlist[i])); */ + chansegment[0] = chanlist[0]; /* first channel is every time ok */ + for (i = 1, seglen = 1; i < n_chan; i++, seglen++) { if (chanlist[0] == chanlist[i]) - break; /* we detect loop, this must by finish */ - if (CR_CHAN(chanlist[i]) & 1) /* odd channel cann't by differencial */ + break; /* we detected a loop, stop */ + if (CR_CHAN(chanlist[i]) & 1) if (CR_AREF(chanlist[i]) == AREF_DIFF) { comedi_error(dev, - "Odd channel can't be differential input!\n"); + "Odd channel cannot be differential input!\n"); return 0; } nowmustbechan = (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan; if (CR_AREF(chansegment[i - 1]) == AREF_DIFF) nowmustbechan = (nowmustbechan + 1) % s->n_chan; - if (nowmustbechan != CR_CHAN(chanlist[i])) { /* channel list isn't continuous :-( */ + if (nowmustbechan != CR_CHAN(chanlist[i])) { printk ("channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n", i, CR_CHAN(chanlist[i]), nowmustbechan, CR_CHAN(chanlist[0])); return 0; } - chansegment[i] = chanlist[i]; /* well, this is next correct channel in list */ + chansegment[i] = chanlist[i]; /* next correct channel in list */ } - for (i = 0, segpos = 0; i < n_chan; i++) { /* check whole chanlist */ - /* printk("%d %d=%d %d\n",CR_CHAN(chansegment[i%seglen]),CR_RANGE(chansegment[i%seglen]),CR_CHAN(chanlist[i]),CR_RANGE(chanlist[i])); */ + for (i = 0, segpos = 0; i < n_chan; i++) { if (chanlist[i] != chansegment[i % seglen]) { printk ("bad channel, reference or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n", @@ -1200,7 +1198,7 @@ static int check_channel_list(struct comedi_device *dev, CR_CHAN(chanlist[i % seglen]), CR_RANGE(chanlist[i % seglen]), CR_AREF(chansegment[i % seglen])); - return 0; /* chan/gain list is strange */ + return 0; /* chan/gain list is strange */ } } return seglen; -- cgit v0.10.2 From 583d82316081429dce49dc5c76219fa527a2129c Mon Sep 17 00:00:00 2001 From: Tomas Melin Date: Mon, 7 May 2012 22:50:24 +0300 Subject: Staging: Comedi adv_pci1710: Combined two conditions Combined two if statements making the code cleaner, removing one level of indentation. Signed-off-by: Tomas Melin Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 6dd4f4a..3c754cd 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1168,12 +1168,11 @@ static int check_channel_list(struct comedi_device *dev, for (i = 1, seglen = 1; i < n_chan; i++, seglen++) { if (chanlist[0] == chanlist[i]) break; /* we detected a loop, stop */ - if (CR_CHAN(chanlist[i]) & 1) - if (CR_AREF(chanlist[i]) == AREF_DIFF) { - comedi_error(dev, - "Odd channel cannot be differential input!\n"); - return 0; - } + if ((CR_CHAN(chanlist[i]) & 1) && + (CR_AREF(chanlist[i]) == AREF_DIFF)) { + comedi_error(dev, "Odd channel cannot be differential input!\n"); + return 0; + } nowmustbechan = (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan; if (CR_AREF(chansegment[i - 1]) == AREF_DIFF) -- cgit v0.10.2 From 6f483279f71ea9e15e2f9c99fa9496acabf5ca9a Mon Sep 17 00:00:00 2001 From: Tomas Melin Date: Mon, 7 May 2012 22:50:55 +0300 Subject: Staging: Comedi adv_pci1710: Fixed indentation Fixed indentation for print messages and code. Signed-off-by: Tomas Melin Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 3c754cd..6279e88 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1173,15 +1173,13 @@ static int check_channel_list(struct comedi_device *dev, comedi_error(dev, "Odd channel cannot be differential input!\n"); return 0; } - nowmustbechan = - (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan; + nowmustbechan = (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan; if (CR_AREF(chansegment[i - 1]) == AREF_DIFF) nowmustbechan = (nowmustbechan + 1) % s->n_chan; if (nowmustbechan != CR_CHAN(chanlist[i])) { - printk - ("channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n", - i, CR_CHAN(chanlist[i]), nowmustbechan, - CR_CHAN(chanlist[0])); + printk("channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n", + i, CR_CHAN(chanlist[i]), nowmustbechan, + CR_CHAN(chanlist[0])); return 0; } chansegment[i] = chanlist[i]; /* next correct channel in list */ @@ -1189,15 +1187,14 @@ static int check_channel_list(struct comedi_device *dev, for (i = 0, segpos = 0; i < n_chan; i++) { if (chanlist[i] != chansegment[i % seglen]) { - printk - ("bad channel, reference or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n", - i, CR_CHAN(chansegment[i]), - CR_RANGE(chansegment[i]), - CR_AREF(chansegment[i]), - CR_CHAN(chanlist[i % seglen]), - CR_RANGE(chanlist[i % seglen]), - CR_AREF(chansegment[i % seglen])); - return 0; /* chan/gain list is strange */ + printk("bad channel, reference or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n", + i, CR_CHAN(chansegment[i]), + CR_RANGE(chansegment[i]), + CR_AREF(chansegment[i]), + CR_CHAN(chanlist[i % seglen]), + CR_RANGE(chanlist[i % seglen]), + CR_AREF(chansegment[i % seglen])); + return 0; } } return seglen; -- cgit v0.10.2 From bc5219bdebab65a75fd224634a355f4b14a39781 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 4 May 2012 17:14:24 +0200 Subject: staging: rts5139: remove useless functions in rts51x_card.c Signed-off-by: Oleksij Rempel Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_card.c b/drivers/staging/rts5139/rts51x_card.c index 424a845..b2f41ce 100644 --- a/drivers/staging/rts5139/rts51x_card.c +++ b/drivers/staging/rts5139/rts51x_card.c @@ -191,7 +191,6 @@ void card_cd_debounce(struct rts51x_chip *chip, u8 *need_reset, goto Exit_Debounce; if (chip->card_exist) { - rts51x_clear_start_time(chip); retval = rts51x_read_register(chip, CARD_INT_PEND, &value); if (retval != STATUS_SUCCESS) { rts51x_ep0_write_register(chip, MC_FIFO_CTL, FIFO_FLUSH, @@ -214,17 +213,11 @@ void card_cd_debounce(struct rts51x_chip *chip, u8 *need_reset, } } else { if (chip->card_status & XD_CD) { - rts51x_clear_start_time(chip); reset_map |= XD_CARD; } else if (chip->card_status & SD_CD) { - rts51x_clear_start_time(chip); reset_map |= SD_CARD; } else if (chip->card_status & MS_CD) { - rts51x_clear_start_time(chip); reset_map |= MS_CARD; - } else { - if (rts51x_check_start_time(chip)) - rts51x_set_start_time(chip); } } diff --git a/drivers/staging/rts5139/rts51x_chip.c b/drivers/staging/rts5139/rts51x_chip.c index b3e0bb2..196c176a 100644 --- a/drivers/staging/rts5139/rts51x_chip.c +++ b/drivers/staging/rts5139/rts51x_chip.c @@ -144,7 +144,6 @@ int rts51x_reset_chip(struct rts51x_chip *chip) card_power_on(chip, SD_CARD | MS_CARD | XD_CARD); wait_timeout(10); } - rts51x_clear_start_time(chip); return STATUS_SUCCESS; } @@ -253,19 +252,6 @@ static inline void rts51x_blink_led(struct rts51x_chip *chip) } #endif -int rts51x_check_start_time(struct rts51x_chip *chip) -{ - return 0; -} - -void rts51x_set_start_time(struct rts51x_chip *chip) -{ -} - -void rts51x_clear_start_time(struct rts51x_chip *chip) -{ -} - static void rts51x_auto_delink_cmd(struct rts51x_chip *chip) { rts51x_write_register(chip, AUTO_DELINK_EN, @@ -484,7 +470,6 @@ void rts51x_polling_func(struct rts51x_chip *chip) rts51x_auto_delink(chip); } else { chip->auto_delink_counter = 0; - rts51x_clear_start_time(chip); } } diff --git a/drivers/staging/rts5139/rts51x_sys.h b/drivers/staging/rts5139/rts51x_sys.h index b09cd34..5ba0d58 100644 --- a/drivers/staging/rts5139/rts51x_sys.h +++ b/drivers/staging/rts5139/rts51x_sys.h @@ -33,10 +33,6 @@ #define USING_POLLING_CYCLE_DELINK -extern int rts51x_check_start_time(struct rts51x_chip *chip); -extern void rts51x_set_start_time(struct rts51x_chip *chip); -extern void rts51x_clear_start_time(struct rts51x_chip *chip); - /* typedef dma_addr_t ULONG_PTR; */ static inline void rts51x_reset_detected_cards(struct rts51x_chip *chip) -- cgit v0.10.2 From 30572230e11017633cb267d09a80c26b682d8b21 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 4 May 2012 17:14:25 +0200 Subject: staging: rts5139: remove disabled code in rts51x_chip.c Signed-off-by: Oleksij Rempel Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_chip.c b/drivers/staging/rts5139/rts51x_chip.c index 196c176a..1f7593d 100644 --- a/drivers/staging/rts5139/rts51x_chip.c +++ b/drivers/staging/rts5139/rts51x_chip.c @@ -163,12 +163,6 @@ int rts51x_init_chip(struct rts51x_chip *chip) chip->card_ejected = 0; chip->lun2card[0] = XD_CARD | SD_CARD | MS_CARD; -#if 0 - chip->option.sdr50_tx_phase = 0x01; - chip->option.sdr50_rx_phase = 0x05; - chip->option.ddr50_tx_phase = 0x09; - chip->option.ddr50_rx_phase = 0x06; /* add for debug */ -#endif #ifdef CLOSE_SSC_POWER rts51x_write_register(chip, FPDCTL, SSC_POWER_MASK, SSC_POWER_ON); udelay(100); @@ -307,59 +301,8 @@ static void rts51x_auto_delink(struct rts51x_chip *chip) } #else /* some of called funcs are not implemented, so comment it out */ -#if 0 -/* using precise time as delink time */ -static void rts51x_auto_delink_precise_time(struct rts51x_chip *chip) -{ - int retvalue = 0; - - retvalue = rts51x_get_card_status(chip, &chip->card_status); - /* get card CD status success and card CD not exist, - * then check whether delink */ - if ((retvalue == STATUS_SUCCESS) - && (!(chip->card_status & (SD_CD | MS_CD | XD_CD)))) { - if (rts51x_count_delink_time(chip) >= - chip->option.delink_delay) { - clear_first_install_mark(chip); - RTS51X_DEBUGP("No card inserted, do delink\n"); - /* sangdy2010-05-17:disable because there is error - * after SSC clock closed and card power - * has been closed before */ - /* rts51x_write_register(chip, CARD_PWR_CTL, - DV3318_AUTO_PWR_OFF, 0); */ - rts51x_auto_delink_cmd(chip); - } - /* card CD exist and not ready, then do force delink */ - if ((retvalue == STATUS_SUCCESS) - && (chip->card_status & (SD_CD | MS_CD | XD_CD))) { - /* if card is not ejected or safely remove, - * then do force delink */ - if (!chip->card_ejected) { - /* sangdy2010-11-16:polling at least 2 cycles - * then do force delink for card may force delink - * if card is extracted and insert quickly - * after ready. */ - if (chip->auto_delink_counter > 1) { - if (rts51x_count_delink_time(chip) > - chip->option.delink_delay * 2) { - RTS51X_DEBUGP("Try to do force" - "delink\n"); - rts51x_auto_delink_force_cmd(chip); - } - } - } - } - chip->auto_delink_counter++; -} -#else -static void rts51x_auto_delink_precise_time(struct rts51x_chip *chip) -{ -} -#endif - static void rts51x_auto_delink(struct rts51x_chip *chip) { - rts51x_auto_delink_precise_time(chip); } #endif @@ -848,16 +791,6 @@ void rts51x_prepare_run(struct rts51x_chip *chip) rts51x_write_register(chip, CLK_DIV, CLK_CHANGE, 0x00); } #endif -#if 0 - if (chip->option.ss_en && RTS51X_CHK_STAT(chip, STAT_SS)) { - rts51x_try_to_exit_ss(chip); - wait_timeout(100); - rts51x_init_chip(chip); - rts51x_init_cards(chip); - } - - RTS51X_SET_STAT(chip, STAT_RUN); -#endif } #ifdef _MSG_TRACE -- cgit v0.10.2 From 7f00e6eac6473d933245c144542c615d83272458 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 4 May 2012 17:14:26 +0200 Subject: staging: rts5139: remove disable code in rts51x_transport.c Signed-off-by: Oleksij Rempel Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_transport.c b/drivers/staging/rts5139/rts51x_transport.c index da9c83b..e402a3c 100644 --- a/drivers/staging/rts5139/rts51x_transport.c +++ b/drivers/staging/rts5139/rts51x_transport.c @@ -391,218 +391,9 @@ static void rts51x_sg_clean(struct usb_sg_request *io) kfree(io->urbs); io->urbs = NULL; } -#if 0 /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) */ - if (io->dev->dev.dma_mask != NULL) - usb_buffer_unmap_sg(io->dev, usb_pipein(io->pipe), - io->sg, io->nents); -#endif io->dev = NULL; } -#if 0 -static void rts51x_sg_complete(struct urb *urb) -{ - struct usb_sg_request *io = urb->context; - int status = urb->status; - - spin_lock(&io->lock); - - /* In 2.5 we require hcds' endpoint queues not to progress after fault - * reports, until the completion callback (this!) returns. That lets - * device driver code (like this routine) unlink queued urbs first, - * if it needs to, since the HC won't work on them at all. So it's - * not possible for page N+1 to overwrite page N, and so on. - * - * That's only for "hard" faults; "soft" faults (unlinks) sometimes - * complete before the HCD can get requests away from hardware, - * though never during cleanup after a hard fault. - */ - if (io->status - && (io->status != -ECONNRESET - || status != -ECONNRESET) - && urb->actual_length) { - dev_err(io->dev->bus->controller, - "dev %s ep%d%s scatterlist error %d/%d\n", - io->dev->devpath, - usb_endpoint_num(&urb->ep->desc), - usb_urb_dir_in(urb) ? "in" : "out", - status, io->status); - /* BUG (); */ - } - - if (io->status == 0 && status && status != -ECONNRESET) { - int i, found, retval; - - io->status = status; - - /* the previous urbs, and this one, completed already. - * unlink pending urbs so they won't rx/tx bad data. - * careful: unlink can sometimes be synchronous... - */ - spin_unlock(&io->lock); - for (i = 0, found = 0; i < io->entries; i++) { - if (!io->urbs[i] || !io->urbs[i]->dev) - continue; - if (found) { - retval = usb_unlink_urb(io->urbs[i]); - if (retval != -EINPROGRESS && - retval != -ENODEV && - retval != -EBUSY) - dev_err(&io->dev->dev, - "%s, unlink --> %d\n", - __func__, retval); - } else if (urb == io->urbs[i]) - found = 1; - } - spin_lock(&io->lock); - } - urb->dev = NULL; - - /* on the last completion, signal usb_sg_wait() */ - io->bytes += urb->actual_length; - io->count--; - if (!io->count) - complete(&io->complete); - - spin_unlock(&io->lock); -} - -/* This function is ported from usb_sg_init, which can transfer - * sg list partially */ -int rts51x_sg_init_partial(struct usb_sg_request *io, struct usb_device *dev, - unsigned pipe, unsigned period, void *buf, struct scatterlist **sgptr, - unsigned int *offset, int nents, size_t length, gfp_t mem_flags) -{ - int i; - int urb_flags; - int dma; - struct scatterlist *sg = *sgptr, *first_sg; - - first_sg = (struct scatterlist *)buf; - if (!sg) - sg = first_sg; - - if (!io || !dev || !sg - || usb_pipecontrol(pipe) - || usb_pipeisoc(pipe) - || (nents <= 0)) - return -EINVAL; - - spin_lock_init(&io->lock); - io->dev = dev; - io->pipe = pipe; - io->sg = first_sg; /* used by unmap */ - io->nents = nents; - - RTS51X_DEBUGP("Before map, sg address: 0x%x\n", (unsigned int)sg); - RTS51X_DEBUGP("Before map, dev address: 0x%x\n", (unsigned int)dev); - - /* not all host controllers use DMA (like the mainstream pci ones); - * they can use PIO (sl811) or be software over another transport. - */ - dma = (dev->dev.dma_mask != NULL); - if (dma) { - /* map the whole sg list, because here we only know the - * total nents */ - io->entries = usb_buffer_map_sg(dev, usb_pipein(pipe), - first_sg, nents); - } else { - io->entries = nents; - } - - /* initialize all the urbs we'll use */ - if (io->entries <= 0) - return io->entries; - - io->urbs = kmalloc(io->entries * sizeof *io->urbs, mem_flags); - if (!io->urbs) - goto nomem; - - urb_flags = URB_NO_INTERRUPT; - if (dma) - urb_flags |= URB_NO_TRANSFER_DMA_MAP; - if (usb_pipein(pipe)) - urb_flags |= URB_SHORT_NOT_OK; - - RTS51X_DEBUGP("io->entries = %d\n", io->entries); - - for (i = 0; (sg != NULL) && (length > 0); i++) { - unsigned len; - - RTS51X_DEBUGP("sg address: 0x%x\n", (unsigned int)sg); - RTS51X_DEBUGP("length = %d, *offset = %d\n", length, *offset); - - io->urbs[i] = usb_alloc_urb(0, mem_flags); - if (!io->urbs[i]) { - io->entries = i; - goto nomem; - } - - io->urbs[i]->dev = NULL; - io->urbs[i]->pipe = pipe; - io->urbs[i]->interval = period; - io->urbs[i]->transfer_flags = urb_flags; - - io->urbs[i]->complete = rts51x_sg_complete; - io->urbs[i]->context = io; - - if (dma) { - io->urbs[i]->transfer_dma = - sg_dma_address(sg) + *offset; - len = sg_dma_len(sg) - *offset; - io->urbs[i]->transfer_buffer = NULL; - RTS51X_DEBUGP(" -- sg entry dma length = %d\n", - sg_dma_len(sg)); - } else { - /* hc may use _only_ transfer_buffer */ - io->urbs[i]->transfer_buffer = sg_virt(sg) + *offset; - len = sg->length - *offset; - RTS51X_DEBUGP(" -- sg entry length = %d\n", - sg->length); - } - - if (length >= len) { - *offset = 0; - io->urbs[i]->transfer_buffer_length = len; - length -= len; - sg = sg_next(sg); - } else { - *offset += length; - io->urbs[i]->transfer_buffer_length = length; - length = 0; - } - if (length == 0) - io->entries = i + 1; -#if 0 - if (length) { - len = min_t(unsigned, len, length); - length -= len; - if (length == 0) { - io->entries = i + 1; - *offset += len; - } else { - *offset = 0; - } - } -#endif - } - RTS51X_DEBUGP("In %s, urb count: %d\n", __func__, i); - io->urbs[--i]->transfer_flags &= ~URB_NO_INTERRUPT; - - RTS51X_DEBUGP("sg address stored in sgptr: 0x%x\n", (unsigned int)sg); - *sgptr = sg; - - /* transaction state */ - io->count = io->entries; - io->status = 0; - io->bytes = 0; - init_completion(&io->complete); - return 0; -nomem: - rts51x_sg_clean(io); - return -ENOMEM; -} -#endif int rts51x_sg_init(struct usb_sg_request *io, struct usb_device *dev, unsigned pipe, unsigned period, struct scatterlist *sg, int nents, size_t length, gfp_t mem_flags) @@ -740,55 +531,7 @@ static int rts51x_bulk_transfer_sglist(struct rts51x_chip *chip, return interpret_urb_result(chip, pipe, length, result, chip->usb->current_sg.bytes); } -#if 0 -static int rts51x_bulk_transfer_sglist_partial(struct rts51x_chip *chip, - unsigned int pipe, void *buf, struct scatterlist **sgptr, - unsigned int *offset, int num_sg, unsigned int length, - unsigned int *act_len, int timeout) -{ - int result; - /* don't submit s-g requests during abort processing */ - if (test_bit(FLIDX_ABORTING, &chip->usb->dflags)) - TRACE_RET(chip, STATUS_ERROR); - - /* initialize the scatter-gather request block */ - RTS51X_DEBUGP("%s: xfer %u bytes, %d entries\n", __func__, - length, num_sg); - result = rts51x_sg_init_partial(&chip->usb->current_sg, - chip->usb->pusb_dev, pipe, 0, buf, sgptr, offset, - num_sg, length, GFP_NOIO); - if (result) { - RTS51X_DEBUGP("rts51x_sg_init_partial returned %d\n", result); - TRACE_RET(chip, STATUS_ERROR); - } - - /* since the block has been initialized successfully, it's now - * okay to cancel it */ - set_bit(FLIDX_SG_ACTIVE, &chip->usb->dflags); - - /* did an abort occur during the submission? */ - if (test_bit(FLIDX_ABORTING, &chip->usb->dflags)) { - - /* cancel the request, if it hasn't been cancelled already */ - if (test_and_clear_bit(FLIDX_SG_ACTIVE, &chip->usb->dflags)) { - RTS51X_DEBUGP("-- cancelling sg request\n"); - usb_sg_cancel(&chip->usb->current_sg); - } - } - - /* wait for the completion of the transfer */ - result = rts51x_sg_wait(&chip->usb->current_sg, timeout); - - clear_bit(FLIDX_SG_ACTIVE, &chip->usb->dflags); - - /* result = us->current_sg.status; */ - if (act_len) - *act_len = chip->usb->current_sg.bytes; - return interpret_urb_result(chip, pipe, length, result, - chip->usb->current_sg.bytes); -} -#endif int rts51x_bulk_transfer_buf(struct rts51x_chip *chip, unsigned int pipe, void *buf, unsigned int length, unsigned int *act_len, int timeout) @@ -860,11 +603,6 @@ int rts51x_transfer_data_partial(struct rts51x_chip *chip, unsigned int pipe, } kfree(tmp_buf); -#if 0 - result = rts51x_bulk_transfer_sglist_partial(chip, pipe, buf, - (struct scatterlist **)ptr, offset, - use_sg, len, act_len, timeout); -#endif } else { unsigned int step = 0; if (offset) -- cgit v0.10.2 From d705b84c6e44d8d1fe0dafe34a20a12846ab07ed Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 4 May 2012 17:14:27 +0200 Subject: staging: rts5139: remove disabled code in rts51x_scsi.c Signed-off-by: Oleksij Rempel Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_scsi.c b/drivers/staging/rts5139/rts51x_scsi.c index 87c9cdc..9625adc 100644 --- a/drivers/staging/rts5139/rts51x_scsi.c +++ b/drivers/staging/rts5139/rts51x_scsi.c @@ -883,20 +883,12 @@ static int read_write(struct scsi_cmnd *srb, struct rts51x_chip *chip) retval = card_rw(srb, chip, start_sec, sec_cnt); if (retval != STATUS_SUCCESS) { -#if 0 - if (chip->need_release & chip->lun2card[lun]) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - } else { -#endif if (srb->sc_data_direction == DMA_FROM_DEVICE) { set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); } else { set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); } -#if 0 - } -#endif TRACE_RET(chip, TRANSPORT_FAILED); } @@ -2111,14 +2103,7 @@ int queuecommand_lck(struct scsi_cmnd *srb, void (*done) (struct scsi_cmnd *)) return 0; } -#if 0 /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37) */ -int queuecommand(struct scsi_cmnd *srb, void (*done) (struct scsi_cmnd *)) -{ - return queuecommand_lck(srb, done); -} -#else DEF_SCSI_QCMD(queuecommand) -#endif /*********************************************************************** * Error handling functions ***********************************************************************/ -- cgit v0.10.2 From d66af05301c7859b676d95db915ebee4c8c01092 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 4 May 2012 17:14:28 +0200 Subject: staging: rts5139: remove disabled code in rts51x_fop.* Signed-off-by: Oleksij Rempel Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_fop.c b/drivers/staging/rts5139/rts51x_fop.c index 6eaebb6..ef893c8 100644 --- a/drivers/staging/rts5139/rts51x_fop.c +++ b/drivers/staging/rts5139/rts51x_fop.c @@ -234,12 +234,7 @@ ssize_t rts51x_write(struct file *filp, const char __user *buf, size_t count, return 0; } -#if 0 /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) */ -int rts51x_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) -#else long rts51x_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -#endif { struct rts51x_chip *chip; struct sd_direct_cmnd cmnd; diff --git a/drivers/staging/rts5139/rts51x_fop.h b/drivers/staging/rts5139/rts51x_fop.h index 94d75f0..eb45acf 100644 --- a/drivers/staging/rts5139/rts51x_fop.h +++ b/drivers/staging/rts5139/rts51x_fop.h @@ -50,12 +50,7 @@ ssize_t rts51x_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos); ssize_t rts51x_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos); -#if 0 /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) */ -int rts51x_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg); -#else long rts51x_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -#endif #endif diff --git a/drivers/staging/rts5139/rts51x_scsi.h b/drivers/staging/rts5139/rts51x_scsi.h index 3a8ca06..6ba7273 100644 --- a/drivers/staging/rts5139/rts51x_scsi.h +++ b/drivers/staging/rts5139/rts51x_scsi.h @@ -150,11 +150,7 @@ int slave_alloc(struct scsi_device *sdev); int slave_configure(struct scsi_device *sdev); int proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int inout); -#if 0 /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37) */ -int queuecommand(struct scsi_cmnd *srb, void (*done) (struct scsi_cmnd *)); -#else int queuecommand(struct Scsi_Host *, struct scsi_cmnd *); -#endif int command_abort(struct scsi_cmnd *srb); int device_reset(struct scsi_cmnd *srb); int bus_reset(struct scsi_cmnd *srb); -- cgit v0.10.2 From 3d2b3aacac35c375e4678b0d0537f5da88647acd Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 4 May 2012 17:14:29 +0200 Subject: staging: rts5139: remove unused LED_AUTO_BLINK code Signed-off-by: Oleksij Rempel Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_chip.c b/drivers/staging/rts5139/rts51x_chip.c index 1f7593d..1be4d49 100644 --- a/drivers/staging/rts5139/rts51x_chip.c +++ b/drivers/staging/rts5139/rts51x_chip.c @@ -121,12 +121,6 @@ int rts51x_reset_chip(struct rts51x_chip *chip) /* GPIO OE */ rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO, GPIO_OE, GPIO_OE); -#ifdef LED_AUTO_BLINK - /* LED autoblink */ - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_AUTO_BLINK, - BLINK_ENABLE | BLINK_SPEED_MASK, - BLINK_ENABLE | chip->option.led_blink_speed); -#endif rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DMA1_CTL, EXTEND_DMA1_ASYNC_SIGNAL, EXTEND_DMA1_ASYNC_SIGNAL); @@ -230,7 +224,6 @@ int rts51x_release_chip(struct rts51x_chip *chip) return STATUS_SUCCESS; } -#ifndef LED_AUTO_BLINK static inline void rts51x_blink_led(struct rts51x_chip *chip) { /* Read/Write */ @@ -244,7 +237,6 @@ static inline void rts51x_blink_led(struct rts51x_chip *chip) } } } -#endif static void rts51x_auto_delink_cmd(struct rts51x_chip *chip) { @@ -360,9 +352,7 @@ void rts51x_polling_func(struct rts51x_chip *chip) if (!RTS51X_CHK_STAT(chip, STAT_IDLE)) { RTS51X_DEBUGP("Idle state!\n"); RTS51X_SET_STAT(chip, STAT_IDLE); -#ifndef LED_AUTO_BLINK chip->led_toggle_counter = 0; -#endif /* Idle state, turn off LED * to reduce power consumption */ if (chip->option.led_always_on @@ -396,9 +386,7 @@ void rts51x_polling_func(struct rts51x_chip *chip) switch (RTS51X_GET_STAT(chip)) { case STAT_RUN: -#ifndef LED_AUTO_BLINK rts51x_blink_led(chip); -#endif do_remaining_work(chip); break; diff --git a/drivers/staging/rts5139/rts51x_chip.h b/drivers/staging/rts5139/rts51x_chip.h index 13fc2a4..effed9f 100644 --- a/drivers/staging/rts5139/rts51x_chip.h +++ b/drivers/staging/rts5139/rts51x_chip.h @@ -39,8 +39,6 @@ #define SUPPORT_CPRM #define SUPPORT_MAGIC_GATE #define SUPPORT_MSXC -/* #define LED_AUTO_BLINK */ - /* { wwang, 2010-07-26 * Add support for SD lock/unlock */ /* #define SUPPORT_SD_LOCK */ @@ -720,9 +718,8 @@ struct rts51x_chip { struct scsi_cmnd *srb; struct sense_data_t sense_buffer[MAX_ALLOWED_LUN_CNT]; -#ifndef LED_AUTO_BLINK int led_toggle_counter; -#endif + int ss_counter; int idle_counter; int auto_delink_counter; -- cgit v0.10.2 From a7f625160fb9b65c85f344a734ae63a26b5d87f0 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 4 May 2012 17:14:30 +0200 Subject: staging: rts5139: remove disabled SUPPORT_SD_LOCK code. Signed-off-by: Oleksij Rempel Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_chip.c b/drivers/staging/rts5139/rts51x_chip.c index 1be4d49..9831917 100644 --- a/drivers/staging/rts5139/rts51x_chip.c +++ b/drivers/staging/rts5139/rts51x_chip.c @@ -300,33 +300,6 @@ static void rts51x_auto_delink(struct rts51x_chip *chip) void rts51x_polling_func(struct rts51x_chip *chip) { -#ifdef SUPPORT_SD_LOCK - struct sd_info *sd_card = &(chip->sd_card); - - if (sd_card->sd_erase_status) { - if (chip->card_exist & SD_CARD) { - u8 val; - rts51x_read_register(chip, SD_BUS_STAT, &val); - if (val & SD_DAT0_STATUS) { - /* Erase completed */ - sd_card->sd_erase_status = SD_NOT_ERASE; - sd_card->sd_lock_notify = 1; - - /* SD card should be reinited, - * so we release it here. */ - sd_cleanup_work(chip); - release_sd_card(chip); - chip->card_ready &= ~SD_CARD; - chip->card_exist &= ~SD_CARD; - chip->rw_card[chip->card2lun[SD_CARD]] = NULL; - clear_bit(chip->card2lun[SD_CARD], - &(chip->lun_mc)); - } - } else { - sd_card->sd_erase_status = SD_NOT_ERASE; - } - } -#endif rts51x_init_cards(chip); @@ -923,24 +896,6 @@ void rts51x_pp_status(struct rts51x_chip *chip, unsigned int lun, u8 *status, status[0x0F] = 0x00; } } -#ifdef SUPPORT_SD_LOCK - /* SD Lock/Unlock */ - if (card == SD_CARD) { - status[0x17] = 0x80; - if (sd_card->sd_erase_status) - status[0x17] |= 0x01; /* Under erasing */ - if (sd_card->sd_lock_status & SD_LOCKED) { - status[0x17] |= 0x02; /* Locked */ - status[0x07] |= 0x40; /* Read protected */ - } - if (sd_card->sd_lock_status & SD_PWD_EXIST) - status[0x17] |= 0x04; /* Contain PWD */ - } else { - status[0x17] = 0x00; - } - - RTS51X_DEBUGP("status[0x17] = 0x%x\n", status[0x17]); -#endif /* Function 0 * Support Magic Gate, CPRM and PhyRegister R/W */ @@ -950,12 +905,6 @@ void rts51x_pp_status(struct rts51x_chip *chip, unsigned int lun, u8 *status, * Support OC LUN status & WP LUN status */ status[0x1A] = 0x28; - /* Function 7 */ -#ifdef SUPPORT_SD_LOCK - /* Support SD Lock/Unlock */ - status[0x1F] = 0x01; -#endif - /* Function 2 * Support OC LUN status & WP LUN status */ status[0x1A] = 0x28; diff --git a/drivers/staging/rts5139/rts51x_chip.h b/drivers/staging/rts5139/rts51x_chip.h index effed9f..7541bb6 100644 --- a/drivers/staging/rts5139/rts51x_chip.h +++ b/drivers/staging/rts5139/rts51x_chip.h @@ -39,10 +39,6 @@ #define SUPPORT_CPRM #define SUPPORT_MAGIC_GATE #define SUPPORT_MSXC -/* { wwang, 2010-07-26 - * Add support for SD lock/unlock */ -/* #define SUPPORT_SD_LOCK */ -/* } wwang, 2010-07-26 */ #ifdef SUPPORT_MAGIC_GA /* Using NORMAL_WRITE instead of AUTO_WRITE to set ICVTE */ @@ -205,10 +201,6 @@ struct trace_msg_t { /* WRITE ERROR */ #define SENSE_TYPE_MG_WRITE_ERR 0x0e #endif -#ifdef SUPPORT_SD_LOCK -/* FOR Locked SD card */ -#define SENSE_TYPE_MEDIA_READ_FORBIDDEN 0x10 -#endif /*---- sense key ----*/ #define ILI 0x20 /* ILI bit is on */ @@ -612,11 +604,6 @@ struct sd_info { u8 sd_reset_fail; /* sangdy2010-07-01 */ u8 sd_send_status_en; -#ifdef SUPPORT_SD_LOCK - u8 sd_lock_status; - u8 sd_erase_status; - u8 sd_lock_notify; -#endif }; #define MODE_512_SEQ 0x01 diff --git a/drivers/staging/rts5139/rts51x_scsi.c b/drivers/staging/rts5139/rts51x_scsi.c index 9625adc..dcb8c18 100644 --- a/drivers/staging/rts5139/rts51x_scsi.c +++ b/drivers/staging/rts5139/rts51x_scsi.c @@ -396,12 +396,6 @@ void set_sense_type(struct rts51x_chip *chip, unsigned int lun, int sense_type) break; #endif -#ifdef SUPPORT_SD_LOCK - case SENSE_TYPE_MEDIA_READ_FORBIDDEN: - set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x11, 0x13, 0, 0); - break; -#endif - case SENSE_TYPE_NO_SENSE: default: set_sense_data(chip, lun, CUR_ERR, 0, 0, 0, 0, 0, 0); @@ -448,20 +442,6 @@ static int test_unit_ready(struct scsi_cmnd *srb, struct rts51x_chip *chip) set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); return TRANSPORT_FAILED; } -#ifdef SUPPORT_SD_LOCK - if (get_lun_card(chip, SCSI_LUN(srb)) == SD_CARD) { - struct sd_info *sd_card = &(chip->sd_card); - if (sd_card->sd_lock_notify) { - sd_card->sd_lock_notify = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } else if (sd_card->sd_lock_status & SD_LOCKED) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_READ_FORBIDDEN); - return TRANSPORT_FAILED; - } - } -#endif return TRANSPORT_GOOD; } @@ -797,9 +777,6 @@ static int request_sense(struct scsi_cmnd *srb, struct rts51x_chip *chip) static int read_write(struct scsi_cmnd *srb, struct rts51x_chip *chip) { -#ifdef SUPPORT_SD_LOCK - struct sd_info *sd_card = &(chip->sd_card); -#endif unsigned int lun = SCSI_LUN(srb); int retval; u32 start_sec; @@ -819,25 +796,6 @@ static int read_write(struct scsi_cmnd *srb, struct rts51x_chip *chip) rts51x_prepare_run(chip); RTS51X_SET_STAT(chip, STAT_RUN); -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_erase_status) { - /* Accessing to any card is forbidden - * until the erase procedure of SD is completed */ - RTS51X_DEBUGP("SD card being erased!\n"); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_READ_FORBIDDEN); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (get_lun_card(chip, lun) == SD_CARD) { - if (sd_card->sd_lock_status & SD_LOCKED) { - RTS51X_DEBUGP("SD card locked!\n"); - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_READ_FORBIDDEN); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } -#endif - if ((srb->cmnd[0] == READ_10) || (srb->cmnd[0] == WRITE_10)) { start_sec = ((u32) srb->cmnd[2] << 24) | @@ -1863,30 +1821,10 @@ int mg_send_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) int rts51x_scsi_handler(struct scsi_cmnd *srb, struct rts51x_chip *chip) { -#ifdef SUPPORT_SD_LOCK - struct sd_info *sd_card = &(chip->sd_card); -#endif struct ms_info *ms_card = &(chip->ms_card); unsigned int lun = SCSI_LUN(srb); int result = TRANSPORT_GOOD; -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_erase_status) { - /* Block all SCSI command except for REQUEST_SENSE - * and rs_ppstatus */ - if (! - ((srb->cmnd[0] == VENDOR_CMND) - && (srb->cmnd[1] == SCSI_APP_CMD) - && (srb->cmnd[2] == GET_DEV_STATUS)) - && (srb->cmnd[0] != REQUEST_SENSE)) { - /* Logical Unit Not Ready Format in Progress */ - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, - 0, 0); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } -#endif - if ((get_lun_card(chip, lun) == MS_CARD) && (ms_card->format_status == FORMAT_IN_PROGRESS)) { if ((srb->cmnd[0] != REQUEST_SENSE) diff --git a/drivers/staging/rts5139/sd.c b/drivers/staging/rts5139/sd.c index d5dd2f9..7031595 100644 --- a/drivers/staging/rts5139/sd.c +++ b/drivers/staging/rts5139/sd.c @@ -246,12 +246,7 @@ RTY_SEND_CMD: if (buf[1] & 0x80) TRACE_RET(chip, STATUS_FAIL); } -#ifdef SUPPORT_SD_LOCK - /* exclude bit25 CARD_IS_LOCKED */ - if (buf[1] & 0x7D) { -#else if (buf[1] & 0x7F) { -#endif RTS51X_DEBUGP("buf[1]: 0x%02x\n", buf[1]); TRACE_RET(chip, STATUS_FAIL); } @@ -709,36 +704,6 @@ int sd_select_card(struct rts51x_chip *chip, int select) return STATUS_SUCCESS; } -#ifdef SUPPORT_SD_LOCK -int sd_update_lock_status(struct rts51x_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - u8 rsp[5]; - - retval = - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, rsp, 5); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (rsp[1] & 0x02) - sd_card->sd_lock_status |= SD_LOCKED; - else - sd_card->sd_lock_status &= ~SD_LOCKED; - - RTS51X_DEBUGP("sd_card->sd_lock_status = 0x%x\n", - sd_card->sd_lock_status); - - if (rsp[1] & 0x01) { - /* LOCK_UNLOCK_FAILED */ - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} -#endif - int sd_wait_currentstate_dataready(struct rts51x_chip *chip, u8 statechk, u8 rdychk, u16 pollingcnt) { @@ -1197,15 +1162,6 @@ static int sd_switch_function(struct rts51x_chip *chip, u8 bus_width) RTS51X_DEBUGP("SD_FUNC_GROUP_1: func_to_switch = 0x%02x", func_to_switch); -#ifdef SUPPORT_SD_LOCK - if ((sd_card->sd_lock_status & SD_SDR_RST) - && (DDR50_SUPPORT == func_to_switch) - && (sd_card->func_group1_mask & SDR50_SUPPORT_MASK)) { - func_to_switch = SDR50_SUPPORT; - RTS51X_DEBUGP("Using SDR50 instead of DDR50 for SD Lock\n"); - } -#endif - if (func_to_switch) { retval = sd_check_switch(chip, SD_FUNC_GROUP_1, func_to_switch, @@ -2024,10 +1980,6 @@ Switch_Fail: k = 0; hi_cap_flow = 0; support_1v8 = 0; -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) - goto SD_UNLOCK_ENTRY; -#endif retval = sd_prepare_reset(chip); if (retval != STATUS_SUCCESS) @@ -2190,20 +2142,6 @@ RTY_CMD55: retval = sd_select_card(chip, 1); if (retval != STATUS_SUCCESS) TRACE_RET(chip, retval); -#ifdef SUPPORT_SD_LOCK -SD_UNLOCK_ENTRY: - /* Get SD lock status */ - retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (sd_card->sd_lock_status & SD_LOCKED) { - sd_card->sd_lock_status |= (SD_LOCK_1BIT_MODE | SD_PWD_EXIST); - return STATUS_SUCCESS; - } else if (!(sd_card->sd_lock_status & SD_UNLOCK_POW_ON)) { - sd_card->sd_lock_status &= ~SD_PWD_EXIST; - } -#endif /* ACMD42 */ retval = @@ -2294,10 +2232,6 @@ SD_UNLOCK_ENTRY: if (retval != STATUS_SUCCESS) TRACE_RET(chip, retval); } -#ifdef SUPPORT_SD_LOCK - /* clear 1 bit mode status */ - sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; -#endif if (CHK_SD30_SPEED(sd_card)) { rts51x_write_register(chip, SD30_DRIVE_SEL, SD30_DRIVE_MASK, @@ -2380,19 +2314,6 @@ SD_UNLOCK_ENTRY: chip->card_bus_width[chip->card2lun[SD_CARD]] = 4; -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) { - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0x02); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 0x00); - - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } -#endif - return STATUS_SUCCESS; } @@ -2587,17 +2508,10 @@ static int mmc_switch_timing_bus(struct rts51x_chip *chip) sd_card->capacity = ((u32) buf[5] << 24) | ((u32) buf[4] << 16) | ((u32) buf[3] << 8) | ((u32) buf[2]); -#ifdef SUPPORT_SD_LOCK - if (!(sd_card->sd_lock_status & SD_SDR_RST) && CHECK_UHS50(chip)) - card_type_mask = 0x07; - else - card_type_mask = 0x03; -#else if (CHECK_UHS50(chip)) card_type_mask = 0x07; else card_type_mask = 0x03; -#endif card_type = buf[1] & card_type_mask; if (card_type) { @@ -2626,15 +2540,9 @@ static int mmc_switch_timing_bus(struct rts51x_chip *chip) if (mmc_test_switch_bus(chip, MMC_8BIT_BUS) == STATUS_SUCCESS) { SET_MMC_8BIT(sd_card); chip->card_bus_width[chip->card2lun[SD_CARD]] = 8; -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; -#endif } else if (mmc_test_switch_bus(chip, MMC_4BIT_BUS) == STATUS_SUCCESS) { SET_MMC_4BIT(sd_card); chip->card_bus_width[chip->card2lun[SD_CARD]] = 4; -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; -#endif } else { CLR_MMC_8BIT(sd_card); CLR_MMC_4BIT(sd_card); @@ -2652,11 +2560,6 @@ static int reset_mmc(struct rts51x_chip *chip) u8 change_to_ddr52 = 1; u8 cmd[5]; -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) - goto MMC_UNLOCK_ENTRY; -#endif - MMC_DDR_FAIL: retval = sd_prepare_reset(chip); @@ -2763,13 +2666,6 @@ RTY_MMC_RST: 0); if (retval != STATUS_SUCCESS) TRACE_RET(chip, retval); -#ifdef SUPPORT_SD_LOCK -MMC_UNLOCK_ENTRY: - /* Get SD lock status */ - retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); -#endif RTS51X_WRITE_REG(chip, SD_CFG1, SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_0); @@ -2842,18 +2738,6 @@ MMC_UNLOCK_ENTRY: } } } -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) { - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0x02); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 0x00); - - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } -#endif retval = rts51x_get_card_status(chip, &(chip->card_status)); if (retval != STATUS_SUCCESS) @@ -2879,11 +2763,6 @@ int reset_sd_card(struct rts51x_chip *chip) sd_card->capacity = 0; sd_card->sd_switch_fail = 0; -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status = 0; - sd_card->sd_erase_status = 0; -#endif - sd_clear_reset_fail(chip); enable_card_clock(chip, SD_CARD); @@ -3352,11 +3231,6 @@ int release_sd_card(struct rts51x_chip *chip) chip->card_fail &= ~SD_CARD; chip->card_wp &= ~SD_CARD; -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status = 0; - sd_card->sd_erase_status = 0; -#endif - memset(sd_card->raw_csd, 0, 16); memset(sd_card->raw_scr, 0, 8); diff --git a/drivers/staging/rts5139/sd.h b/drivers/staging/rts5139/sd.h index 0805edc..44b6fc4 100644 --- a/drivers/staging/rts5139/sd.h +++ b/drivers/staging/rts5139/sd.h @@ -141,29 +141,6 @@ #define SWITCH_MODE_ERR 0x06 #define SWITCH_PASS 0x07 -#ifdef SUPPORT_SD_LOCK -/* CMD42 Parameter */ -#define SD_ERASE 0x08 -#define SD_LOCK 0x04 -#define SD_UNLOCK 0x00 -#define SD_CLR_PWD 0x02 -#define SD_SET_PWD 0x01 - -#define SD_PWD_LEN 0x10 - -/* SD lock unlock Status */ -#define SD_LOCKED 0x80 /* Global lock status */ -#define SD_LOCK_1BIT_MODE 0x40 /**/ -#define SD_PWD_EXIST 0x20 -#define SD_UNLOCK_POW_ON 0x01 /**/ -#define SD_SDR_RST 0x02 /* Reset SD30 card with current DDR mode to SDR mode. */ -/* g_bySDEraseStatus */ -#define SD_NOT_ERASE 0x00 -#define SD_UNDER_ERASING 0x01 -#define SD_COMPLETE_ERASE 0x02 -/* SD_RW FAIL status */ -#define SD_RW_FORBIDDEN 0x0F /* read/write is forbidden (SD card) */ -#endif /* Function Group Definition */ /* Function Group 1 */ #define HS_SUPPORT 0x01 @@ -289,10 +266,6 @@ void sd_cleanup_work(struct rts51x_chip *chip); int sd_power_off_card3v3(struct rts51x_chip *chip); int release_sd_card(struct rts51x_chip *chip); -#ifdef SUPPORT_SD_LOCK -int sd_update_lock_status(struct rts51x_chip *chip); -#endif - #ifdef SUPPORT_CPRM extern int reset_sd(struct rts51x_chip *chip); extern int sd_check_data0_status(struct rts51x_chip *chip); diff --git a/drivers/staging/rts5139/sd_cprm.c b/drivers/staging/rts5139/sd_cprm.c index d5969d9..ba4d189 100644 --- a/drivers/staging/rts5139/sd_cprm.c +++ b/drivers/staging/rts5139/sd_cprm.c @@ -206,11 +206,7 @@ RTY_SEND_CMD: if (buf[1] & 0x80) TRACE_RET(chip, STATUS_FAIL); } -#ifdef SUPPORT_SD_LOCK - if (buf[1] & 0x7D) { -#else if (buf[1] & 0x7F) { -#endif TRACE_RET(chip, STATUS_FAIL); } if (buf[2] & 0xF8) @@ -305,26 +301,8 @@ int ext_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun, retval = sd_switch_clock(chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); -#ifdef SUPPORT_SD_LOCK - if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { - if (CHK_MMC_8BIT(sd_card)) { - retval = - rts51x_write_register(chip, SD_CFG1, 0x03, - SD_BUS_WIDTH_8); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { - retval = - rts51x_write_register(chip, SD_CFG1, 0x03, - SD_BUS_WIDTH_4); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - } - } -#else /* Set H/W SD/MMC Bus Width */ rts51x_write_register(chip, SD_CFG1, 0x03, SD_BUS_WIDTH_4); -#endif if (standby) { retval = sd_select_card(chip, 0); @@ -350,12 +328,6 @@ int ext_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun, if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Cmd_Failed); } -#ifdef SUPPORT_SD_LOCK - /* Get SD lock status */ - retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Cmd_Failed); -#endif return TRANSPORT_GOOD; @@ -399,21 +371,7 @@ int ext_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun, retval = sd_switch_clock(chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); -#ifdef SUPPORT_SD_LOCK - if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { - if (CHK_MMC_8BIT(sd_card)) - bus_width = SD_BUS_WIDTH_8; - else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) - bus_width = SD_BUS_WIDTH_4; - else - bus_width = SD_BUS_WIDTH_1; - } else { - bus_width = SD_BUS_WIDTH_4; - } - RTS51X_DEBUGP("bus_width = %d\n", bus_width); -#else bus_width = SD_BUS_WIDTH_4; -#endif if (data_len < 512) { retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, @@ -599,11 +557,6 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, int cmd13_checkbit = 0, write_err = 0; u8 rsp_type; u32 i; -#ifdef SUPPORT_SD_LOCK - int lock_cmd_fail = 0; - u8 sd_lock_state = 0; - u8 lock_cmd_type = 0; -#endif if (sd_card->pre_cmd_err) { sd_card->pre_cmd_err = 0; @@ -614,12 +567,6 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, retval = sd_switch_clock(chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); -#ifdef SUPPORT_SD_LOCK - if (cmd_idx == LOCK_UNLOCK) { - sd_lock_state = sd_card->sd_lock_status; - sd_lock_state &= SD_LOCKED; - } -#endif retval = get_rsp_type(rsp_code, &rsp_type, &rsp_len); if (retval != STATUS_SUCCESS) { @@ -631,25 +578,7 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, retval = sd_switch_clock(chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); -#ifdef SUPPORT_SD_LOCK - if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { - if (CHK_MMC_8BIT(sd_card)) { - retval = - rts51x_write_register(chip, SD_CFG1, 0x03, - SD_BUS_WIDTH_8); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { - retval = - rts51x_write_register(chip, SD_CFG1, 0x03, - SD_BUS_WIDTH_4); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - } - } -#else rts51x_write_register(chip, SD_CFG1, 0x03, SD_BUS_WIDTH_4); -#endif if (data_len < 512) { retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, @@ -692,10 +621,6 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, else memcpy(buf, data_buf, data_len); -#ifdef SUPPORT_SD_LOCK - if (cmd_idx == LOCK_UNLOCK) - lock_cmd_type = buf[0] & 0x0F; -#endif if (data_len > 256) { rts51x_init_cmd(chip); @@ -802,29 +727,6 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, SD_STOP | SD_CLR_ERR); TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); } -#ifdef SUPPORT_SD_LOCK - if (cmd_idx == LOCK_UNLOCK) { - if (lock_cmd_type == SD_ERASE) { - sd_card->sd_erase_status = SD_UNDER_ERASING; - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; - } - - rts51x_init_cmd(chip); - rts51x_add_cmd(chip, CHECK_REG_CMD, SD_BUS_STAT, SD_DAT0_STATUS, - SD_DAT0_STATUS); - retval = rts51x_send_cmd(chip, MODE_CR, 250); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - rts51x_get_rsp(chip, 1, 200); /* Don't care return value */ - - retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) { - RTS51X_DEBUGP("Lock command fail!\n"); - lock_cmd_fail = 1; - } - } -#endif /* SUPPORT_SD_LOCK */ if (standby) { retval = sd_select_card(chip, 1); @@ -865,51 +767,6 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, } if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); -#ifdef SUPPORT_SD_LOCK - if (cmd_idx == LOCK_UNLOCK) { - if (!lock_cmd_fail) { - RTS51X_DEBUGP("lock_cmd_type = 0x%x\n", - lock_cmd_type); - if (lock_cmd_type & SD_CLR_PWD) - sd_card->sd_lock_status &= ~SD_PWD_EXIST; - if (lock_cmd_type & SD_SET_PWD) - sd_card->sd_lock_status |= SD_PWD_EXIST; - } - - RTS51X_DEBUGP("sd_lock_state = 0x%x," - "sd_card->sd_lock_status = 0x%x\n", - sd_lock_state, sd_card->sd_lock_status); - if (sd_lock_state ^ (sd_card->sd_lock_status & SD_LOCKED)) { - sd_card->sd_lock_notify = 1; - if (sd_lock_state) { - if (sd_card->sd_lock_status & - SD_LOCK_1BIT_MODE) { - sd_card->sd_lock_status |= - (SD_UNLOCK_POW_ON | SD_SDR_RST); - if (CHK_SD(sd_card)) { - retval = reset_sd(chip); - if (retval != STATUS_SUCCESS) { - sd_card->sd_lock_status - &= ~(SD_UNLOCK_POW_ON | - SD_SDR_RST); - TRACE_GOTO(chip, - SD_Execute_Write_Cmd_Failed); - } - } - - sd_card->sd_lock_status &= - ~(SD_UNLOCK_POW_ON | SD_SDR_RST); - } - } - } - } - - if (lock_cmd_fail) { - scsi_set_resid(srb, 0); - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - TRACE_RET(chip, TRANSPORT_FAILED); - } -#endif /* SUPPORT_SD_LOCK */ return TRANSPORT_GOOD; @@ -1173,24 +1030,12 @@ int sd_hw_rst(struct scsi_cmnd *srb, struct rts51x_chip *chip) switch (srb->cmnd[1] & 0x0F) { case 0: /* SD Card Power Off -> ON and Initialization */ -#ifdef SUPPORT_SD_LOCK - if (0x64 == srb->cmnd[9]) { - /* Command Mode */ - sd_card->sd_lock_status |= SD_SDR_RST; - } -#endif /* SUPPORT_SD_LOCK */ retval = reset_sd_card(chip); if (retval != STATUS_SUCCESS) { -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_SDR_RST; -#endif set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); sd_card->pre_cmd_err = 1; TRACE_RET(chip, TRANSPORT_FAILED); } -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_SDR_RST; -#endif break; case 1: -- cgit v0.10.2 From 174b8d9fa3066a98ac7bcc122d5b27efa1053051 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 4 May 2012 17:14:31 +0200 Subject: staging: rts5139: remove disabled XD_SPEEDUP code Signed-off-by: Oleksij Rempel Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_chip.h b/drivers/staging/rts5139/rts51x_chip.h index 7541bb6..9f71aca 100644 --- a/drivers/staging/rts5139/rts51x_chip.h +++ b/drivers/staging/rts5139/rts51x_chip.h @@ -57,7 +57,6 @@ #define SUPPORT_OCP #define MS_SPEEDUP -/* #define XD_SPEEDUP */ #define SD_XD_IO_FOLLOW_PWR diff --git a/drivers/staging/rts5139/xd.c b/drivers/staging/rts5139/xd.c index 5820605..7f2748c 100644 --- a/drivers/staging/rts5139/xd.c +++ b/drivers/staging/rts5139/xd.c @@ -1182,91 +1182,6 @@ static int xd_copy_page(struct rts51x_chip *chip, return STATUS_SUCCESS; } -#ifdef XD_SPEEDUP -static int xd_auto_copy_page(struct rts51x_chip *chip, - u32 old_blk, u32 new_blk, - u8 start_page, u8 end_page) -{ - struct xd_info *xd_card = &(chip->xd_card); - u32 old_page, new_page; - int retval; - u8 page_count; - - RTS51X_DEBUGP("Auto copy page from block 0x%x to block 0x%x\n", - old_blk, new_blk); - - if (start_page > end_page) - TRACE_RET(chip, STATUS_FAIL); - - page_count = end_page - start_page; - - if ((old_blk == BLK_NOT_FOUND) || (new_blk == BLK_NOT_FOUND)) - TRACE_RET(chip, STATUS_FAIL); - - old_page = (old_blk << xd_card->block_shift) + start_page; - new_page = (new_blk << xd_card->block_shift) + start_page; - - XD_CLR_BAD_NEWBLK(xd_card); - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_WAITTIME, 0x03, WAIT_FF); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_PAGELEN, 0xFF, page_count); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_READADDR0, 0xFF, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_READADDR1, 0xFF, - (u8) old_page); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_READADDR2, 0xFF, - (u8) (old_page >> 8)); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_READADDR3, 0xFF, - (u8) (old_page >> 16)); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_READADDR4, 0xFF, 0); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_WRITEADDR0, 0xFF, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_WRITEADDR1, 0xFF, - (u8) new_page); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_WRITEADDR2, 0xFF, - (u8) (new_page >> 8)); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_WRITEADDR3, 0xFF, - (u8) (new_page >> 16)); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_WRITEADDR4, 0xFF, 0); - - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CFG, - XD_BA_TRANSFORM | XD_ADDR_MASK, 0 | xd_card->addr_cycle); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, - XD_AUTO_CHK_DATA_STATUS, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_COPY_PAGES); - rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, - XD_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) { - rts51x_clear_xd_error(chip); - TRACE_GOTO(chip, Copy_Fail); - } - - retval = rts51x_get_rsp(chip, 1, 800); - if (retval != STATUS_SUCCESS) { - rts51x_clear_xd_error(chip); - TRACE_GOTO(chip, Copy_Fail); - } - - return STATUS_SUCCESS; - -Copy_Fail: - retval = xd_copy_page(chip, old_blk, new_blk, start_page, end_page); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} -#endif - static int xd_reset_cmd(struct rts51x_chip *chip) { int retval; @@ -1686,15 +1601,9 @@ Fail: XD_CLR_BAD_OLDBLK(xd_card); TRACE_RET(chip, STATUS_FAIL); } -#ifdef XD_SPEEDUP - retval = - xd_auto_copy_page(chip, phy_blk, new_blk, 0, - xd_card->page_off + 1); -#else retval = xd_copy_page(chip, phy_blk, new_blk, 0, xd_card->page_off + 1); -#endif if (retval != STATUS_SUCCESS) { if (!XD_CHK_BAD_NEWBLK(xd_card)) { retval = xd_erase_block(chip, new_blk); @@ -1741,13 +1650,8 @@ static int xd_finish_write(struct rts51x_chip *chip, TRACE_RET(chip, STATUS_FAIL); } } else { -#ifdef XD_SPEEDUP - retval = xd_auto_copy_page(chip, old_blk, new_blk, - page_off, xd_card->page_off + 1); -#else retval = xd_copy_page(chip, old_blk, new_blk, page_off, xd_card->page_off + 1); -#endif if (retval != STATUS_SUCCESS) { if (!XD_CHK_BAD_NEWBLK(xd_card)) { retval = xd_erase_block(chip, new_blk); @@ -1789,11 +1693,7 @@ static int xd_prepare_write(struct rts51x_chip *chip, old_blk, new_blk, log_blk, (int)page_off); if (page_off) { -#ifdef XD_SPEEDUP - retval = xd_auto_copy_page(chip, old_blk, new_blk, 0, page_off); -#else retval = xd_copy_page(chip, old_blk, new_blk, 0, page_off); -#endif if (retval != STATUS_SUCCESS) TRACE_RET(chip, retval); } @@ -1999,18 +1899,11 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, (start_page > delay_write->pageoff)) { delay_write->delay_write_flag = 0; if (delay_write->old_phyblock != BLK_NOT_FOUND) { -#ifdef XD_SPEEDUP - retval = xd_auto_copy_page(chip, - delay_write->old_phyblock, - delay_write->new_phyblock, - delay_write->pageoff, start_page); -#else retval = xd_copy_page(chip, delay_write->old_phyblock, delay_write->new_phyblock, delay_write->pageoff, start_page); -#endif if (retval != STATUS_SUCCESS) { set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); -- cgit v0.10.2 From c377c5006f2c69ac3a41a865fbb41578547fe33d Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 4 May 2012 17:14:32 +0200 Subject: staging: rts5139: remove disabled SCSI_SCAN_DELAY code Signed-off-by: Oleksij Rempel Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x.c b/drivers/staging/rts5139/rts51x.c index 2b9f785..48cb684 100644 --- a/drivers/staging/rts5139/rts51x.c +++ b/drivers/staging/rts5139/rts51x.c @@ -56,12 +56,6 @@ MODULE_DESCRIPTION(RTS51X_DESC); MODULE_LICENSE("GPL"); MODULE_VERSION(DRIVER_VERSION); -#ifdef SCSI_SCAN_DELAY -static unsigned int delay_use = 5; -module_param(delay_use, uint, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device"); -#endif - static int auto_delink_en; module_param(auto_delink_en, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(auto_delink_en, "enable auto delink"); @@ -364,11 +358,6 @@ static int rts51x_polling_thread(void *__chip) { struct rts51x_chip *chip = (struct rts51x_chip *)__chip; -#ifdef SCSI_SCAN_DELAY - /* Wait until SCSI scan finished */ - wait_timeout((delay_use + 5) * HZ); -#endif - for (;;) { wait_timeout(POLLING_INTERVAL); @@ -432,38 +421,6 @@ static int rts51x_polling_thread(void *__chip) return 0; } -#ifdef SCSI_SCAN_DELAY -/* Thread to carry out delayed SCSI-device scanning */ -static int rts51x_scan_thread(void *__chip) -{ - struct rts51x_chip *chip = (struct rts51x_chip *)__chip; - - printk(KERN_DEBUG - "rts51x: device found at %d\n", chip->usb->pusb_dev->devnum); - - set_freezable(); - /* Wait for the timeout to expire or for a disconnect */ - if (delay_use > 0) { - printk(KERN_DEBUG "rts51x: waiting for device " - "to settle before scanning\n"); - wait_event_freezable_timeout(chip->usb->delay_wait, - test_bit(FLIDX_DONT_SCAN, - &chip->usb->dflags), - delay_use * HZ); - } - - /* If the device is still connected, perform the scanning */ - if (!test_bit(FLIDX_DONT_SCAN, &chip->usb->dflags)) { - scsi_scan_host(rts51x_to_host(chip)); - printk(KERN_DEBUG "rts51x: device scan complete\n"); - - /* Should we unbind if no devices were detected? */ - } - - complete_and_exit(&chip->usb->scanning_done, 0); -} -#endif - /* Associate our private data with the USB device */ static int associate_dev(struct rts51x_chip *chip, struct usb_interface *intf) { @@ -737,15 +694,6 @@ static void quiesce_and_remove_host(struct rts51x_chip *chip) if (rts51x->pusb_dev->state == USB_STATE_NOTATTACHED) set_bit(FLIDX_DISCONNECTING, &rts51x->dflags); -#ifdef SCSI_SCAN_DELAY - /* Prevent SCSI-scanning (if it hasn't started yet) - * and wait for the SCSI-scanning thread to stop. - */ - set_bit(FLIDX_DONT_SCAN, &rts51x->dflags); - wake_up(&rts51x->delay_wait); - wait_for_completion(&rts51x->scanning_done); -#endif - /* Removing the host will perform an orderly shutdown: caches * synchronized, disks spun down, etc. */ @@ -757,9 +705,6 @@ static void quiesce_and_remove_host(struct rts51x_chip *chip) scsi_lock(host); set_bit(FLIDX_DISCONNECTING, &rts51x->dflags); scsi_unlock(host); -#ifdef SCSI_SCAN_DELAY - wake_up(&rts51x->delay_wait); -#endif } /* Second stage of disconnect processing: deallocate all resources */ @@ -818,10 +763,6 @@ static int rts51x_probe(struct usb_interface *intf, init_completion(&rts51x->control_exit); init_completion(&rts51x->polling_exit); init_completion(&(rts51x->notify)); -#ifdef SCSI_SCAN_DELAY - init_waitqueue_head(&rts51x->delay_wait); - init_completion(&rts51x->scanning_done); -#endif chip->usb = rts51x; @@ -855,22 +796,7 @@ static int rts51x_probe(struct usb_interface *intf, printk(KERN_WARNING RTS51X_TIP "Unable to add the scsi host\n"); goto BadDevice; } -#ifdef SCSI_SCAN_DELAY - /* Start up the thread for delayed SCSI-device scanning */ - th = kthread_create(rts51x_scan_thread, chip, RTS51X_SCAN_THREAD); - if (IS_ERR(th)) { - printk(KERN_WARNING RTS51X_TIP - "Unable to start the device-scanning thread\n"); - complete(&rts51x->scanning_done); - quiesce_and_remove_host(chip); - result = PTR_ERR(th); - goto BadDevice; - } - - wake_up_process(th); -#else scsi_scan_host(rts51x_to_host(chip)); -#endif /* Start up our polling thread */ th = kthread_run(rts51x_polling_thread, chip, RTS51X_POLLING_THREAD); diff --git a/drivers/staging/rts5139/rts51x.h b/drivers/staging/rts5139/rts51x.h index b2c5839..40ca432 100644 --- a/drivers/staging/rts5139/rts51x.h +++ b/drivers/staging/rts5139/rts51x.h @@ -51,7 +51,6 @@ #define RTS51X_POLLING_THREAD "rts5139-polling" #define POLLING_IN_THREAD -/* #define SCSI_SCAN_DELAY */ #define SUPPORT_FILE_OP #define wait_timeout_x(task_state, msecs) \ @@ -116,10 +115,6 @@ struct rts51x_usb { struct completion control_exit; /* control thread exit */ struct completion polling_exit; /* polling thread exit */ struct completion notify; /* thread begin/end */ -#ifdef SCSI_SCAN_DELAY - wait_queue_head_t delay_wait; /* wait during scan, reset */ - struct completion scanning_done; /* wait for scan thread */ -#endif }; extern struct usb_driver rts51x_driver; -- cgit v0.10.2 From ec5bd9b3cf288798c0ca2ee573d18594255d72ec Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 4 May 2012 17:14:33 +0200 Subject: staging: rts5139: remove unused clear_first_install_mark it also removes rts51x_reset_detected_cards. Signed-off-by: Oleksij Rempel Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_chip.c b/drivers/staging/rts5139/rts51x_chip.c index 9831917..ff23d5a 100644 --- a/drivers/staging/rts5139/rts51x_chip.c +++ b/drivers/staging/rts5139/rts51x_chip.c @@ -259,7 +259,6 @@ static void rts51x_auto_delink_polling_cycle(struct rts51x_chip *chip) chip->option.delink_delay * 2) { if (chip->auto_delink_counter == chip->option.delink_delay) { - clear_first_install_mark(chip); if (chip->card_exist) { /* False card */ if (!chip->card_ejected) { diff --git a/drivers/staging/rts5139/rts51x_sys.h b/drivers/staging/rts5139/rts51x_sys.h index 5ba0d58..10c51f7 100644 --- a/drivers/staging/rts5139/rts51x_sys.h +++ b/drivers/staging/rts5139/rts51x_sys.h @@ -35,15 +35,6 @@ /* typedef dma_addr_t ULONG_PTR; */ -static inline void rts51x_reset_detected_cards(struct rts51x_chip *chip) -{ -/* rts51x_reset_cards(chip); */ -} - -static inline void clear_first_install_mark(struct rts51x_chip *chip) -{ -} - void rts51x_enter_ss(struct rts51x_chip *chip); void rts51x_exit_ss(struct rts51x_chip *chip); -- cgit v0.10.2 From 63bb174d9c8acdc077dcb99b51c3f8f89bf7de6d Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 4 May 2012 17:14:34 +0200 Subject: staging: rts5139: remove useless rts51x_sys.h and move USING_POLLING_CYCLE_DELINK to rts51x_chip.h Signed-off-by: Oleksij Rempel Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_card.c b/drivers/staging/rts5139/rts51x_card.c index b2f41ce..bb86c5b5 100644 --- a/drivers/staging/rts5139/rts51x_card.c +++ b/drivers/staging/rts5139/rts51x_card.c @@ -37,7 +37,6 @@ #include "rts51x_chip.h" #include "rts51x_card.h" #include "rts51x_transport.h" -#include "rts51x_sys.h" #include "xd.h" #include "sd.h" #include "ms.h" diff --git a/drivers/staging/rts5139/rts51x_chip.c b/drivers/staging/rts5139/rts51x_chip.c index ff23d5a..3a10310 100644 --- a/drivers/staging/rts5139/rts51x_chip.c +++ b/drivers/staging/rts5139/rts51x_chip.c @@ -34,7 +34,6 @@ #include "rts51x_chip.h" #include "rts51x_card.h" #include "rts51x_transport.h" -#include "rts51x_sys.h" #include "xd.h" #include "ms.h" #include "sd.h" diff --git a/drivers/staging/rts5139/rts51x_chip.h b/drivers/staging/rts5139/rts51x_chip.h index 9f71aca..cab8ab0 100644 --- a/drivers/staging/rts5139/rts51x_chip.h +++ b/drivers/staging/rts5139/rts51x_chip.h @@ -39,6 +39,7 @@ #define SUPPORT_CPRM #define SUPPORT_MAGIC_GATE #define SUPPORT_MSXC +#define USING_POLLING_CYCLE_DELINK #ifdef SUPPORT_MAGIC_GA /* Using NORMAL_WRITE instead of AUTO_WRITE to set ICVTE */ diff --git a/drivers/staging/rts5139/rts51x_scsi.c b/drivers/staging/rts5139/rts51x_scsi.c index dcb8c18..1591ad7 100644 --- a/drivers/staging/rts5139/rts51x_scsi.c +++ b/drivers/staging/rts5139/rts51x_scsi.c @@ -40,7 +40,6 @@ #include "rts51x_scsi.h" #include "rts51x_card.h" #include "rts51x_transport.h" -#include "rts51x_sys.h" #include "sd_cprm.h" #include "ms_mg.h" #include "trace.h" diff --git a/drivers/staging/rts5139/rts51x_sys.h b/drivers/staging/rts5139/rts51x_sys.h deleted file mode 100644 index 10c51f7..0000000 --- a/drivers/staging/rts5139/rts51x_sys.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Driver for Realtek USB RTS51xx card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, 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, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __RTS51X_SYS_H -#define __RTS51X_SYS_H - -#include "rts51x.h" -#include "rts51x_chip.h" -#include "rts51x_card.h" - -#define USING_POLLING_CYCLE_DELINK - -/* typedef dma_addr_t ULONG_PTR; */ - -void rts51x_enter_ss(struct rts51x_chip *chip); -void rts51x_exit_ss(struct rts51x_chip *chip); - -#endif /* __RTS51X_SYS_H */ -- cgit v0.10.2 From 60c1530170008393901f03d018a2f89ad3022a0d Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 4 May 2012 20:02:46 +0200 Subject: staging: rts5139: make some functions static in rts51x_card.c and rts51x.c Signed-off-by: Oleksij Rempel Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x.c b/drivers/staging/rts5139/rts51x.c index 48cb684..7726a1a 100644 --- a/drivers/staging/rts5139/rts51x.c +++ b/drivers/staging/rts5139/rts51x.c @@ -108,7 +108,7 @@ static inline void usb_autopm_disable(struct usb_interface *intf) usb_autopm_get_interface(intf); } -void rts51x_try_to_enter_ss(struct rts51x_chip *chip) +static void rts51x_try_to_enter_ss(struct rts51x_chip *chip) { RTS51X_DEBUGP("Ready to enter SS state\n"); usb_autopm_enable(chip->usb->pusb_intf); @@ -201,7 +201,7 @@ int rts51x_reset_resume(struct usb_interface *iface) #else /* CONFIG_PM */ -void rts51x_try_to_enter_ss(struct rts51x_chip *chip) +static void rts51x_try_to_enter_ss(struct rts51x_chip *chip) { } diff --git a/drivers/staging/rts5139/rts51x.h b/drivers/staging/rts5139/rts51x.h index 40ca432..2d2b315 100644 --- a/drivers/staging/rts5139/rts51x.h +++ b/drivers/staging/rts5139/rts51x.h @@ -183,7 +183,6 @@ enum xfer_buf_dir { TO_XFER_BUF, FROM_XFER_BUF }; /* General routines provided by the usb-storage standard core */ #ifdef CONFIG_PM -void rts51x_try_to_enter_ss(struct rts51x_chip *chip); void rts51x_try_to_exit_ss(struct rts51x_chip *chip); int rts51x_suspend(struct usb_interface *iface, pm_message_t message); int rts51x_resume(struct usb_interface *iface); diff --git a/drivers/staging/rts5139/rts51x_card.c b/drivers/staging/rts5139/rts51x_card.c index bb86c5b5..3c12dfb 100644 --- a/drivers/staging/rts5139/rts51x_card.c +++ b/drivers/staging/rts5139/rts51x_card.c @@ -93,7 +93,7 @@ void do_remaining_work(struct rts51x_chip *chip) ms_cleanup_work(chip); } -void do_reset_xd_card(struct rts51x_chip *chip) +static void do_reset_xd_card(struct rts51x_chip *chip) { int retval; @@ -147,7 +147,7 @@ void do_reset_sd_card(struct rts51x_chip *chip) } } -void do_reset_ms_card(struct rts51x_chip *chip) +static void do_reset_ms_card(struct rts51x_chip *chip) { int retval; @@ -174,7 +174,7 @@ void do_reset_ms_card(struct rts51x_chip *chip) } } -void card_cd_debounce(struct rts51x_chip *chip, u8 *need_reset, +static void card_cd_debounce(struct rts51x_chip *chip, u8 *need_reset, u8 *need_release) { int retval; @@ -701,7 +701,7 @@ u8 get_lun_card(struct rts51x_chip *chip, unsigned int lun) return 0; } -int card_share_mode(struct rts51x_chip *chip, int card) +static int card_share_mode(struct rts51x_chip *chip, int card) { u8 value; diff --git a/drivers/staging/rts5139/rts51x_card.h b/drivers/staging/rts5139/rts51x_card.h index ac3c1e7..7a2c4ab 100644 --- a/drivers/staging/rts5139/rts51x_card.h +++ b/drivers/staging/rts5139/rts51x_card.h @@ -744,9 +744,7 @@ int monitor_card_cd(struct rts51x_chip *chip, u8 card); void do_remaining_work(struct rts51x_chip *chip); -void do_reset_xd_card(struct rts51x_chip *chip); void do_reset_sd_card(struct rts51x_chip *chip); -void do_reset_ms_card(struct rts51x_chip *chip); void rts51x_init_cards(struct rts51x_chip *chip); void rts51x_release_cards(struct rts51x_chip *chip); int switch_ssc_clock(struct rts51x_chip *chip, int clk); @@ -754,7 +752,6 @@ int switch_normal_clock(struct rts51x_chip *chip, int clk); int card_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 sec_addr, u16 sec_cnt); u8 get_lun_card(struct rts51x_chip *chip, unsigned int lun); -int card_share_mode(struct rts51x_chip *chip, int card); int rts51x_select_card(struct rts51x_chip *chip, int card); void eject_card(struct rts51x_chip *chip, unsigned int lun); void trans_dma_enable(enum dma_data_direction dir, struct rts51x_chip *chip, -- cgit v0.10.2 From 6741f6c719f88e2cea8843f1934e308dd7939380 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 4 May 2012 17:14:36 +0200 Subject: staging: rts5139: remove unused disable_card_clock Signed-off-by: Oleksij Rempel Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_card.c b/drivers/staging/rts5139/rts51x_card.c index 3c12dfb..4406bf9 100644 --- a/drivers/staging/rts5139/rts51x_card.c +++ b/drivers/staging/rts5139/rts51x_card.c @@ -815,22 +815,6 @@ int enable_card_clock(struct rts51x_chip *chip, u8 card) return STATUS_SUCCESS; } -int disable_card_clock(struct rts51x_chip *chip, u8 card) -{ - u8 clk_en = 0; - - if (card & XD_CARD) - clk_en |= XD_CLK_EN; - if (card & SD_CARD) - clk_en |= SD_CLK_EN; - if (card & MS_CARD) - clk_en |= MS_CLK_EN; - - RTS51X_WRITE_REG(chip, CARD_CLK_EN, clk_en, 0); - - return STATUS_SUCCESS; -} - int card_power_on(struct rts51x_chip *chip, u8 card) { u8 mask, val1, val2; diff --git a/drivers/staging/rts5139/rts51x_card.h b/drivers/staging/rts5139/rts51x_card.h index 7a2c4ab..104a4a9 100644 --- a/drivers/staging/rts5139/rts51x_card.h +++ b/drivers/staging/rts5139/rts51x_card.h @@ -757,7 +757,6 @@ void eject_card(struct rts51x_chip *chip, unsigned int lun); void trans_dma_enable(enum dma_data_direction dir, struct rts51x_chip *chip, u32 byte_cnt, u8 pack_size); int enable_card_clock(struct rts51x_chip *chip, u8 card); -int disable_card_clock(struct rts51x_chip *chip, u8 card); int card_power_on(struct rts51x_chip *chip, u8 card); int card_power_off(struct rts51x_chip *chip, u8 card); int toggle_gpio(struct rts51x_chip *chip, u8 gpio); -- cgit v0.10.2 From 25c59c553828145860d983bdd8ee445c1209dd0a Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 4 May 2012 17:14:37 +0200 Subject: staging: rts5139: remove unused card_power_off Signed-off-by: Oleksij Rempel Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_card.c b/drivers/staging/rts5139/rts51x_card.c index 4406bf9..73032ef 100644 --- a/drivers/staging/rts5139/rts51x_card.c +++ b/drivers/staging/rts5139/rts51x_card.c @@ -855,17 +855,6 @@ int card_power_on(struct rts51x_chip *chip, u8 card) return STATUS_SUCCESS; } -int card_power_off(struct rts51x_chip *chip, u8 card) -{ - u8 mask, val; - - mask = POWER_MASK; - val = POWER_OFF; - RTS51X_WRITE_REG(chip, CARD_PWR_CTL, mask, val); - - return STATUS_SUCCESS; -} - int monitor_card_cd(struct rts51x_chip *chip, u8 card) { int retval; diff --git a/drivers/staging/rts5139/rts51x_card.h b/drivers/staging/rts5139/rts51x_card.h index 104a4a9..ef9cc89 100644 --- a/drivers/staging/rts5139/rts51x_card.h +++ b/drivers/staging/rts5139/rts51x_card.h @@ -758,7 +758,6 @@ void trans_dma_enable(enum dma_data_direction dir, struct rts51x_chip *chip, u32 byte_cnt, u8 pack_size); int enable_card_clock(struct rts51x_chip *chip, u8 card); int card_power_on(struct rts51x_chip *chip, u8 card); -int card_power_off(struct rts51x_chip *chip, u8 card); int toggle_gpio(struct rts51x_chip *chip, u8 gpio); int turn_on_led(struct rts51x_chip *chip, u8 gpio); int turn_off_led(struct rts51x_chip *chip, u8 gpio); -- cgit v0.10.2 From feb5680e063fd39873e9e638937f1197d38a81ca Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 9 May 2012 03:06:46 +0900 Subject: staging: rts5139: Fix typo in rts5139 Correct spelling typo in rts5139 Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_chip.h b/drivers/staging/rts5139/rts51x_chip.h index cab8ab0..65c3ee9 100644 --- a/drivers/staging/rts5139/rts51x_chip.h +++ b/drivers/staging/rts5139/rts51x_chip.h @@ -232,8 +232,8 @@ struct trace_msg_t { #define CUR_ERR 0x70 /* current error */ #define DEF_ERR 0x71 /* specific command error */ -/*---- sense key Infomation ----*/ -#define SNSKEYINFO_LEN 3 /* length of sense key infomation */ +/*---- sense key Information ----*/ +#define SNSKEYINFO_LEN 3 /* length of sense key information */ #define SKSV 0x80 #define CDB_ILLEGAL 0x40 @@ -286,13 +286,13 @@ struct sense_data_t { unsigned char seg_no; /* segment No. */ unsigned char sense_key; /* byte5 : ILI */ /* bit3-0 : sense key */ - unsigned char info[4]; /* infomation */ + unsigned char info[4]; /* information */ unsigned char ad_sense_len; /* additional sense data length */ - unsigned char cmd_info[4]; /* command specific infomation */ + unsigned char cmd_info[4]; /* command specific information */ unsigned char asc; /* ASC */ unsigned char ascq; /* ASCQ */ unsigned char rfu; /* FRU */ - unsigned char sns_key_info[3]; /* sense key specific infomation */ + unsigned char sns_key_info[3]; /* sense key specific information */ }; /* sd_ctl bit map */ diff --git a/drivers/staging/rts5139/sd.c b/drivers/staging/rts5139/sd.c index 7031595..0395bc3 100644 --- a/drivers/staging/rts5139/sd.c +++ b/drivers/staging/rts5139/sd.c @@ -1518,7 +1518,7 @@ static u8 sd_search_final_phase(struct rts51x_chip *chip, u32 phase_map, } Search_Finish: - RTS51X_DEBUGP("Final choosen phase: %d\n", final_phase); + RTS51X_DEBUGP("Final chosen phase: %d\n", final_phase); return final_phase; } -- cgit v0.10.2 From 294f930d98be86fb4f34302c718a49719650857f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 3 May 2012 15:09:40 -0700 Subject: staging: comedi: use module_comedi_driver Convert the refactored comedi drivers to use the module_comedi_driver() macro which makes the code smaller and a bit simpler. In the process, rename the driver variables from driver_* to *_driver, as is more typical with other subsystems, and make sure they are all static. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index ed80397..f709107 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -437,24 +437,13 @@ static int dev_8255_detach(struct comedi_device *dev) return 0; } -static struct comedi_driver driver_8255 = { +static struct comedi_driver dev_8255_driver = { .driver_name = "8255", .module = THIS_MODULE, .attach = dev_8255_attach, .detach = dev_8255_detach, }; - -static int __init driver_8255_init_module(void) -{ - return comedi_driver_register(&driver_8255); -} -module_init(driver_8255_init_module); - -static void __exit driver_8255_cleanup_module(void) -{ - comedi_driver_unregister(&driver_8255); -} -module_exit(driver_8255_cleanup_module); +module_comedi_driver(dev_8255_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/acl7225b.c b/drivers/staging/comedi/drivers/acl7225b.c index ef685fc..e5f8729 100644 --- a/drivers/staging/comedi/drivers/acl7225b.c +++ b/drivers/staging/comedi/drivers/acl7225b.c @@ -134,7 +134,7 @@ static const struct boardtype boardtypes[] = { { "p16r16dio", P16R16DIO_SIZE, }, }; -static struct comedi_driver driver_acl7225b = { +static struct comedi_driver acl7225b_driver = { .driver_name = "acl7225b", .module = THIS_MODULE, .attach = acl7225b_attach, @@ -143,18 +143,7 @@ static struct comedi_driver driver_acl7225b = { .num_names = ARRAY_SIZE(boardtypes), .offset = sizeof(struct boardtype), }; - -static int __init driver_acl7225b_init_module(void) -{ - return comedi_driver_register(&driver_acl7225b); -} -module_init(driver_acl7225b_init_module); - -static void __exit driver_acl7225b_cleanup_module(void) -{ - comedi_driver_unregister(&driver_acl7225b); -} -module_exit(driver_acl7225b_cleanup_module); +module_comedi_driver(acl7225b_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c index 275cb77..6a68d53 100644 --- a/drivers/staging/comedi/drivers/adq12b.c +++ b/drivers/staging/comedi/drivers/adq12b.c @@ -347,7 +347,7 @@ static const struct adq12b_board adq12b_boards[] = { }, }; -static struct comedi_driver driver_adq12b = { +static struct comedi_driver adq12b_driver = { .driver_name = "adq12b", .module = THIS_MODULE, .attach = adq12b_attach, @@ -356,18 +356,7 @@ static struct comedi_driver driver_adq12b = { .offset = sizeof(struct adq12b_board), .num_names = ARRAY_SIZE(adq12b_boards), }; - -static int __init driver_adq12b_init_module(void) -{ - return comedi_driver_register(&driver_adq12b); -} -module_init(driver_adq12b_init_module); - -static void __exit driver_adq12b_cleanup_module(void) -{ - comedi_driver_unregister(&driver_adq12b); -} -module_exit(driver_adq12b_cleanup_module); +module_comedi_driver(adq12b_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c index b0f98e5..1a28e67 100644 --- a/drivers/staging/comedi/drivers/aio_aio12_8.c +++ b/drivers/staging/comedi/drivers/aio_aio12_8.c @@ -217,28 +217,16 @@ static int aio_aio12_8_detach(struct comedi_device *dev) return 0; } -static struct comedi_driver driver_aio_aio12_8 = { - .driver_name = "aio_aio12_8", - .module = THIS_MODULE, - .attach = aio_aio12_8_attach, - .detach = aio_aio12_8_detach, - .board_name = &board_types[0].name, - .num_names = 1, - .offset = sizeof(struct aio12_8_boardtype), +static struct comedi_driver aio_aio12_8_driver = { + .driver_name = "aio_aio12_8", + .module = THIS_MODULE, + .attach = aio_aio12_8_attach, + .detach = aio_aio12_8_detach, + .board_name = &board_types[0].name, + .num_names = ARRAY_SIZE(board_types), + .offset = sizeof(struct aio12_8_boardtype), }; - -static int __init driver_aio_aio12_8_init_module(void) -{ - return comedi_driver_register(&driver_aio_aio12_8); -} - -static void __exit driver_aio_aio12_8_cleanup_module(void) -{ - comedi_driver_unregister(&driver_aio_aio12_8); -} - -module_init(driver_aio_aio12_8_init_module); -module_exit(driver_aio_aio12_8_cleanup_module); +module_comedi_driver(aio_aio12_8_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c index 763461a..242255c 100644 --- a/drivers/staging/comedi/drivers/aio_iiro_16.c +++ b/drivers/staging/comedi/drivers/aio_iiro_16.c @@ -159,7 +159,7 @@ static int aio_iiro_16_detach(struct comedi_device *dev) return 0; } -static struct comedi_driver driver_aio_iiro_16 = { +static struct comedi_driver aio_iiro_16_driver = { .driver_name = "aio_iiro_16", .module = THIS_MODULE, .attach = aio_iiro_16_attach, @@ -168,18 +168,7 @@ static struct comedi_driver driver_aio_iiro_16 = { .offset = sizeof(struct aio_iiro_16_board), .num_names = ARRAY_SIZE(aio_iiro_16_boards), }; - -static int __init driver_aio_iiro_16_init_module(void) -{ - return comedi_driver_register(&driver_aio_iiro_16); -} -module_init(driver_aio_iiro_16_init_module); - -static void __exit driver_aio_iiro_16_cleanup_module(void) -{ - comedi_driver_unregister(&driver_aio_iiro_16); -} -module_exit(driver_aio_iiro_16_cleanup_module); +module_comedi_driver(aio_iiro_16_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c index 5f75351..56dd33a 100644 --- a/drivers/staging/comedi/drivers/c6xdigio.c +++ b/drivers/staging/comedi/drivers/c6xdigio.c @@ -508,24 +508,13 @@ static int c6xdigio_detach(struct comedi_device *dev) return 0; } -struct comedi_driver driver_c6xdigio = { +static struct comedi_driver c6xdigio_driver = { .driver_name = "c6xdigio", .module = THIS_MODULE, .attach = c6xdigio_attach, .detach = c6xdigio_detach, }; - -static int __init driver_c6xdigio_init_module(void) -{ - return comedi_driver_register(&driver_c6xdigio); -} -module_init(driver_c6xdigio_init_module); - -static void __exit driver_c6xdigio_cleanup_module(void) -{ - comedi_driver_unregister(&driver_c6xdigio); -} -module_exit(driver_c6xdigio_cleanup_module); +module_comedi_driver(c6xdigio_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c index f5a0dc5..152959c 100644 --- a/drivers/staging/comedi/drivers/dt2815.c +++ b/drivers/staging/comedi/drivers/dt2815.c @@ -242,24 +242,13 @@ static int dt2815_detach(struct comedi_device *dev) return 0; } -static struct comedi_driver driver_dt2815 = { +static struct comedi_driver dt2815_driver = { .driver_name = "dt2815", .module = THIS_MODULE, .attach = dt2815_attach, .detach = dt2815_detach, }; - -static int __init driver_dt2815_init_module(void) -{ - return comedi_driver_register(&driver_dt2815); -} -module_init(driver_dt2815_init_module); - -static void __exit driver_dt2815_cleanup_module(void) -{ - comedi_driver_unregister(&driver_dt2815); -} -module_exit(driver_dt2815_cleanup_module); +module_comedi_driver(dt2815_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/dt2817.c b/drivers/staging/comedi/drivers/dt2817.c index 45d9a82..d8149f4 100644 --- a/drivers/staging/comedi/drivers/dt2817.c +++ b/drivers/staging/comedi/drivers/dt2817.c @@ -169,24 +169,13 @@ static int dt2817_detach(struct comedi_device *dev) return 0; } -static struct comedi_driver driver_dt2817 = { +static struct comedi_driver dt2817_driver = { .driver_name = "dt2817", .module = THIS_MODULE, .attach = dt2817_attach, .detach = dt2817_detach, }; - -static int __init driver_dt2817_init_module(void) -{ - return comedi_driver_register(&driver_dt2817); -} -module_init(driver_dt2817_init_module); - -static void __exit driver_dt2817_cleanup_module(void) -{ - comedi_driver_unregister(&driver_dt2817); -} -module_exit(driver_dt2817_cleanup_module); +module_comedi_driver(dt2817_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c index 88c18ea..25fed75 100644 --- a/drivers/staging/comedi/drivers/fl512.c +++ b/drivers/staging/comedi/drivers/fl512.c @@ -182,24 +182,13 @@ static int fl512_detach(struct comedi_device *dev) return 0; } -static struct comedi_driver driver_fl512 = { +static struct comedi_driver fl512_driver = { .driver_name = "fl512", .module = THIS_MODULE, .attach = fl512_attach, .detach = fl512_detach, }; - -static int __init driver_fl512_init_module(void) -{ - return comedi_driver_register(&driver_fl512); -} -module_init(driver_fl512_init_module); - -static void __exit driver_fl512_cleanup_module(void) -{ - comedi_driver_unregister(&driver_fl512); -} -module_exit(driver_fl512_cleanup_module); +module_comedi_driver(fl512_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c index fcb7cea..6a12dca 100644 --- a/drivers/staging/comedi/drivers/pcl711.c +++ b/drivers/staging/comedi/drivers/pcl711.c @@ -611,7 +611,7 @@ static const struct pcl711_board boardtypes[] = { { "acl8112dg", 0, 1, 1, 9, 16, 2, 15, &range_acl8112dg_ai }, }; -static struct comedi_driver driver_pcl711 = { +static struct comedi_driver pcl711_driver = { .driver_name = "pcl711", .module = THIS_MODULE, .attach = pcl711_attach, @@ -620,18 +620,7 @@ static struct comedi_driver driver_pcl711 = { .num_names = ARRAY_SIZE(boardtypes), .offset = sizeof(struct pcl711_board), }; - -static int __init driver_pcl711_init_module(void) -{ - return comedi_driver_register(&driver_pcl711); -} -module_init(driver_pcl711_init_module); - -static void __exit driver_pcl711_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl711); -} -module_exit(driver_pcl711_cleanup_module); +module_comedi_driver(pcl711_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c index 7d0a306..7562858 100644 --- a/drivers/staging/comedi/drivers/pcl724.c +++ b/drivers/staging/comedi/drivers/pcl724.c @@ -205,7 +205,7 @@ static const struct pcl724_board boardtypes[] = { { "pet48dio", 48, 2, 0x9eb8, PET48_SIZE, 0, 1, }, }; -static struct comedi_driver driver_pcl724 = { +static struct comedi_driver pcl724_driver = { .driver_name = "pcl724", .module = THIS_MODULE, .attach = pcl724_attach, @@ -214,18 +214,7 @@ static struct comedi_driver driver_pcl724 = { .num_names = ARRAY_SIZE(boardtypes), .offset = sizeof(struct pcl724_board), }; - -static int __init driver_pcl724_init_module(void) -{ - return comedi_driver_register(&driver_pcl724); -} -module_init(driver_pcl724_init_module); - -static void __exit driver_pcl724_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl724); -} -module_exit(driver_pcl724_cleanup_module); +module_comedi_driver(pcl724_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/pcl725.c b/drivers/staging/comedi/drivers/pcl725.c index 4b761a6..eeac943 100644 --- a/drivers/staging/comedi/drivers/pcl725.c +++ b/drivers/staging/comedi/drivers/pcl725.c @@ -99,24 +99,13 @@ static int pcl725_detach(struct comedi_device *dev) return 0; } -static struct comedi_driver driver_pcl725 = { +static struct comedi_driver pcl725_driver = { .driver_name = "pcl725", .module = THIS_MODULE, .attach = pcl725_attach, .detach = pcl725_detach, }; - -static int __init driver_pcl725_init_module(void) -{ - return comedi_driver_register(&driver_pcl725); -} -module_init(driver_pcl725_init_module); - -static void __exit driver_pcl725_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl725); -} -module_exit(driver_pcl725_cleanup_module); +module_comedi_driver(pcl725_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c index c63e91c..8e2fb36 100644 --- a/drivers/staging/comedi/drivers/pcl726.c +++ b/drivers/staging/comedi/drivers/pcl726.c @@ -365,7 +365,7 @@ static int pcl726_detach(struct comedi_device *dev) return 0; } -static struct comedi_driver driver_pcl726 = { +static struct comedi_driver pcl726_driver = { .driver_name = "pcl726", .module = THIS_MODULE, .attach = pcl726_attach, @@ -374,18 +374,7 @@ static struct comedi_driver driver_pcl726 = { .num_names = ARRAY_SIZE(boardtypes), .offset = sizeof(struct pcl726_board), }; - -static int __init driver_pcl726_init_module(void) -{ - return comedi_driver_register(&driver_pcl726); -} -module_init(driver_pcl726_init_module); - -static void __exit driver_pcl726_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl726); -} -module_exit(driver_pcl726_cleanup_module); +module_comedi_driver(pcl726_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c index f6fa8ae..73b4394 100644 --- a/drivers/staging/comedi/drivers/pcl730.c +++ b/drivers/staging/comedi/drivers/pcl730.c @@ -150,7 +150,7 @@ static const struct pcl730_board boardtypes[] = { { "acl7130", ACL7130_SIZE, }, }; -static struct comedi_driver driver_pcl730 = { +static struct comedi_driver pcl730_driver = { .driver_name = "pcl730", .module = THIS_MODULE, .attach = pcl730_attach, @@ -159,18 +159,7 @@ static struct comedi_driver driver_pcl730 = { .num_names = ARRAY_SIZE(boardtypes), .offset = sizeof(struct pcl730_board), }; - -static int __init driver_pcl730_init_module(void) -{ - return comedi_driver_register(&driver_pcl730); -} -module_init(driver_pcl730_init_module); - -static void __exit driver_pcl730_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl730); -} -module_exit(driver_pcl730_cleanup_module); +module_comedi_driver(pcl730_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 85463e2..613b397 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -1681,7 +1681,7 @@ static const struct pcl812_board boardtypes[] = { 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, }; -static struct comedi_driver driver_pcl812 = { +static struct comedi_driver pcl812_driver = { .driver_name = "pcl812", .module = THIS_MODULE, .attach = pcl812_attach, @@ -1690,18 +1690,7 @@ static struct comedi_driver driver_pcl812 = { .num_names = ARRAY_SIZE(boardtypes), .offset = sizeof(struct pcl812_board), }; - -static int __init driver_pcl812_init_module(void) -{ - return comedi_driver_register(&driver_pcl812); -} -module_init(driver_pcl812_init_module); - -static void __exit driver_pcl812_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl812); -} -module_exit(driver_pcl812_cleanup_module); +module_comedi_driver(pcl812_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index bccbb23..1559c05 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -1317,7 +1317,7 @@ static const struct pcl816_board boardtypes[] = { 100}, }; -static struct comedi_driver driver_pcl816 = { +static struct comedi_driver pcl816_driver = { .driver_name = "pcl816", .module = THIS_MODULE, .attach = pcl816_attach, @@ -1326,18 +1326,7 @@ static struct comedi_driver driver_pcl816 = { .num_names = ARRAY_SIZE(boardtypes), .offset = sizeof(struct pcl816_board), }; - -static int __init driver_pcl816_init_module(void) -{ - return comedi_driver_register(&driver_pcl816); -} -module_init(driver_pcl816_init_module); - -static void __exit driver_pcl816_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl816); -} -module_exit(driver_pcl816_cleanup_module); +module_comedi_driver(pcl816_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index 8dbefc5..9b8a1ff 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -1992,7 +1992,7 @@ static const struct pcl818_board boardtypes[] = { 0x0a, 0xfff, 0xfff, 0, 1 /* XXX ? */ }, }; -static struct comedi_driver driver_pcl818 = { +static struct comedi_driver pcl818_driver = { .driver_name = "pcl818", .module = THIS_MODULE, .attach = pcl818_attach, @@ -2001,18 +2001,7 @@ static struct comedi_driver driver_pcl818 = { .num_names = ARRAY_SIZE(boardtypes), .offset = sizeof(struct pcl818_board), }; - -static int __init driver_pcl818_init_module(void) -{ - return comedi_driver_register(&driver_pcl818); -} -module_init(driver_pcl818_init_module); - -static void __exit driver_pcl818_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl818); -} -module_exit(driver_pcl818_cleanup_module); +module_comedi_driver(pcl818_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c index 88a354b..36c0459 100644 --- a/drivers/staging/comedi/drivers/pcm3724.c +++ b/drivers/staging/comedi/drivers/pcm3724.c @@ -291,7 +291,7 @@ static const struct pcm3724_board boardtypes[] = { { "pcm3724", 48, 2, 0x00fc, PCM3724_SIZE, }, }; -static struct comedi_driver driver_pcm3724 = { +static struct comedi_driver pcm3724_driver = { .driver_name = "pcm3724", .module = THIS_MODULE, .attach = pcm3724_attach, @@ -300,18 +300,7 @@ static struct comedi_driver driver_pcm3724 = { .num_names = ARRAY_SIZE(boardtypes), .offset = sizeof(struct pcm3724_board), }; - -static int __init driver_pcm3724_init_module(void) -{ - return comedi_driver_register(&driver_pcm3724); -} -module_init(driver_pcm3724_init_module); - -static void __exit driver_pcm3724_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcm3724); -} -module_exit(driver_pcm3724_cleanup_module); +module_comedi_driver(pcm3724_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/pcm3730.c b/drivers/staging/comedi/drivers/pcm3730.c index 3428993..1571b83 100644 --- a/drivers/staging/comedi/drivers/pcm3730.c +++ b/drivers/staging/comedi/drivers/pcm3730.c @@ -143,24 +143,13 @@ static int pcm3730_detach(struct comedi_device *dev) return 0; } -static struct comedi_driver driver_pcm3730 = { +static struct comedi_driver pcm3730_driver = { .driver_name = "pcm3730", .module = THIS_MODULE, .attach = pcm3730_attach, .detach = pcm3730_detach, }; - -static int __init driver_pcm3730_init_module(void) -{ - return comedi_driver_register(&driver_pcm3730); -} -module_init(driver_pcm3730_init_module); - -static void __exit driver_pcm3730_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcm3730); -} -module_exit(driver_pcm3730_cleanup_module); +module_comedi_driver(pcm3730_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c index fe8ef66..05a2363 100644 --- a/drivers/staging/comedi/drivers/pcmad.c +++ b/drivers/staging/comedi/drivers/pcmad.c @@ -161,7 +161,7 @@ static const struct pcmad_board_struct pcmad_boards[] = { .n_ai_bits = 16, }, }; -static struct comedi_driver driver_pcmad = { +static struct comedi_driver pcmad_driver = { .driver_name = "pcmad", .module = THIS_MODULE, .attach = pcmad_attach, @@ -170,18 +170,7 @@ static struct comedi_driver driver_pcmad = { .num_names = ARRAY_SIZE(pcmad_boards), .offset = sizeof(pcmad_boards[0]), }; - -static int __init driver_pcmad_init_module(void) -{ - return comedi_driver_register(&driver_pcmad); -} -module_init(driver_pcmad_init_module); - -static void __exit driver_pcmad_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcmad); -} -module_exit(driver_pcmad_cleanup_module); +module_comedi_driver(pcmad_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c index a82b343..aaea0e6 100644 --- a/drivers/staging/comedi/drivers/pcmda12.c +++ b/drivers/staging/comedi/drivers/pcmda12.c @@ -242,7 +242,7 @@ static const struct pcmda12_board pcmda12_boards[] = { }, }; -static struct comedi_driver driver = { +static struct comedi_driver pcmda12_driver = { .driver_name = "pcmda12", .module = THIS_MODULE, .attach = pcmda12_attach, @@ -251,18 +251,7 @@ static struct comedi_driver driver = { .offset = sizeof(struct pcmda12_board), .num_names = ARRAY_SIZE(pcmda12_boards), }; - -static int __init driver_init_module(void) -{ - return comedi_driver_register(&driver); -} -module_init(driver_init_module); - -static void __exit driver_cleanup_module(void) -{ - comedi_driver_unregister(&driver); -} -module_exit(driver_cleanup_module); +module_comedi_driver(pcmda12_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index 9ee1da5..a977acb 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -1261,7 +1261,7 @@ static const struct pcmmio_board pcmmio_boards[] = { }, }; -static struct comedi_driver driver = { +static struct comedi_driver pcmmio_driver = { .driver_name = "pcmmio", .module = THIS_MODULE, .attach = pcmmio_attach, @@ -1270,18 +1270,7 @@ static struct comedi_driver driver = { .offset = sizeof(struct pcmmio_board), .num_names = ARRAY_SIZE(pcmmio_boards), }; - -static int __init driver_init_module(void) -{ - return comedi_driver_register(&driver); -} -module_init(driver_init_module); - -static void __exit driver_cleanup_module(void) -{ - comedi_driver_unregister(&driver); -} -module_exit(driver_cleanup_module); +module_comedi_driver(pcmmio_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 47a3ee6..b18912ac8 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -940,7 +940,7 @@ static const struct pcmuio_board pcmuio_boards[] = { }, }; -static struct comedi_driver driver = { +static struct comedi_driver pcmuio_driver = { .driver_name = "pcmuio", .module = THIS_MODULE, .attach = pcmuio_attach, @@ -949,18 +949,7 @@ static struct comedi_driver driver = { .offset = sizeof(struct pcmuio_board), .num_names = ARRAY_SIZE(pcmuio_boards), }; - -static int __init driver_init_module(void) -{ - return comedi_driver_register(&driver); -} -module_init(driver_init_module); - -static void __exit driver_cleanup_module(void) -{ - comedi_driver_unregister(&driver); -} -module_exit(driver_cleanup_module); +module_comedi_driver(pcmuio_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/poc.c b/drivers/staging/comedi/drivers/poc.c index e3690bb..2e50c7fd 100644 --- a/drivers/staging/comedi/drivers/poc.c +++ b/drivers/staging/comedi/drivers/poc.c @@ -222,7 +222,7 @@ static const struct boarddef_struct boards[] = { }, }; -static struct comedi_driver driver_poc = { +static struct comedi_driver poc_driver = { .driver_name = "poc", .module = THIS_MODULE, .attach = poc_attach, @@ -231,18 +231,7 @@ static struct comedi_driver driver_poc = { .num_names = ARRAY_SIZE(boards), .offset = sizeof(boards[0]), }; - -static int __init driver_poc_init_module(void) -{ - return comedi_driver_register(&driver_poc); -} -module_init(driver_poc_init_module); - -static void __exit driver_poc_cleanup_module(void) -{ - comedi_driver_unregister(&driver_poc); -} -module_exit(driver_poc_cleanup_module); +module_comedi_driver(poc_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c index 9e082b3..c073bf4 100644 --- a/drivers/staging/comedi/drivers/rti800.c +++ b/drivers/staging/comedi/drivers/rti800.c @@ -461,7 +461,7 @@ static const struct rti800_board boardtypes[] = { { "rti815", 1 }, }; -static struct comedi_driver driver_rti800 = { +static struct comedi_driver rti800_driver = { .driver_name = "rti800", .module = THIS_MODULE, .attach = rti800_attach, @@ -470,18 +470,7 @@ static struct comedi_driver driver_rti800 = { .board_name = &boardtypes[0].name, .offset = sizeof(struct rti800_board), }; - -static int __init driver_rti800_init_module(void) -{ - return comedi_driver_register(&driver_rti800); -} -module_init(driver_rti800_init_module); - -static void __exit driver_rti800_cleanup_module(void) -{ - comedi_driver_unregister(&driver_rti800); -} -module_exit(driver_rti800_cleanup_module); +module_comedi_driver(rti800_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c index 21baf1a..b4980b4 100644 --- a/drivers/staging/comedi/drivers/rti802.c +++ b/drivers/staging/comedi/drivers/rti802.c @@ -139,24 +139,13 @@ static int rti802_detach(struct comedi_device *dev) return 0; } -static struct comedi_driver driver_rti802 = { +static struct comedi_driver rti802_driver = { .driver_name = "rti802", .module = THIS_MODULE, .attach = rti802_attach, .detach = rti802_detach, }; - -static int __init driver_rti802_init_module(void) -{ - return comedi_driver_register(&driver_rti802); -} -module_init(driver_rti802_init_module); - -static void __exit driver_rti802_cleanup_module(void) -{ - comedi_driver_unregister(&driver_rti802); -} -module_exit(driver_rti802_cleanup_module); +module_comedi_driver(rti802_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index ffe4362..3f86ed7 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -948,7 +948,7 @@ static int s526_detach(struct comedi_device *dev) return 0; } -static struct comedi_driver driver_s526 = { +static struct comedi_driver s526_driver = { .driver_name = "s526", .module = THIS_MODULE, .attach = s526_attach, @@ -957,18 +957,7 @@ static struct comedi_driver driver_s526 = { .offset = sizeof(struct s526_board), .num_names = ARRAY_SIZE(s526_boards), }; - -static int __init driver_s526_init_module(void) -{ - return comedi_driver_register(&driver_s526); -} -module_init(driver_s526_init_module); - -static void __exit driver_s526_cleanup_module(void) -{ - comedi_driver_unregister(&driver_s526); -} -module_exit(driver_s526_cleanup_module); +module_comedi_driver(s526_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index a034b10..0fbd9f9 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -868,7 +868,7 @@ static const struct serial2002_board serial2002_boards[] = { }, }; -struct comedi_driver driver_serial2002 = { +static struct comedi_driver serial2002_driver = { .driver_name = "serial2002", .module = THIS_MODULE, .attach = serial2002_attach, @@ -877,18 +877,7 @@ struct comedi_driver driver_serial2002 = { .offset = sizeof(struct serial2002_board), .num_names = ARRAY_SIZE(serial2002_boards), }; - -static int __init driver_serial2002_init_module(void) -{ - return comedi_driver_register(&driver_serial2002); -} -module_init(driver_serial2002_init_module); - -static void __exit driver_serial2002_cleanup_module(void) -{ - comedi_driver_unregister(&driver_serial2002); -} -module_exit(driver_serial2002_cleanup_module); +module_comedi_driver(serial2002_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); -- cgit v0.10.2 From 98b08941b20e41fcbd3aaa577381e656e1c41291 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 4 May 2012 11:23:54 -0700 Subject: staging: comedi: remove debug tracing in vmk80xx driver The vmk80xx driver uses a non-existant Kconfig symbol to enable function call debug tracing. This output is really just noise and doesn't serve any useful purpose. Remove all it's uses in the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index a7db686..d0e1065 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -151,27 +151,12 @@ MODULE_DEVICE_TABLE(usb, vmk80xx_id_table); #define URB_RCV_FLAG (1 << 0) #define URB_SND_FLAG (1 << 1) -#define CONFIG_VMK80XX_DEBUG -#undef CONFIG_VMK80XX_DEBUG - -#ifdef CONFIG_VMK80XX_DEBUG -static int dbgvm = 1; -#else -static int dbgvm; -#endif - #ifdef CONFIG_COMEDI_DEBUG static int dbgcm = 1; #else static int dbgcm; #endif -#define dbgvm(fmt, arg...) \ -do { \ - if (dbgvm) \ - printk(KERN_DEBUG fmt, ##arg); \ -} while (0) - #define dbgcm(fmt, arg...) \ do { \ if (dbgcm) \ @@ -254,8 +239,6 @@ static void vmk80xx_tx_callback(struct urb *urb) struct vmk80xx_usb *dev = urb->context; int stat = urb->status; - dbgvm("vmk80xx: %s\n", __func__); - if (stat && !(stat == -ENOENT || stat == -ECONNRESET || stat == -ESHUTDOWN)) dbgcm("comedi#: vmk80xx: %s - nonzero urb status (%d)\n", @@ -274,8 +257,6 @@ static void vmk80xx_rx_callback(struct urb *urb) struct vmk80xx_usb *dev = urb->context; int stat = urb->status; - dbgvm("vmk80xx: %s\n", __func__); - switch (stat) { case 0: break; @@ -316,8 +297,6 @@ static int vmk80xx_check_data_link(struct vmk80xx_usb *dev) unsigned char tx[1]; unsigned char rx[2]; - dbgvm("vmk80xx: %s\n", __func__); - tx_pipe = usb_sndbulkpipe(dev->udev, 0x01); rx_pipe = usb_rcvbulkpipe(dev->udev, 0x81); @@ -342,8 +321,6 @@ static void vmk80xx_read_eeprom(struct vmk80xx_usb *dev, int flag) unsigned char rx[64]; int cnt; - dbgvm("vmk80xx: %s\n", __func__); - tx_pipe = usb_sndbulkpipe(dev->udev, 0x01); rx_pipe = usb_rcvbulkpipe(dev->udev, 0x81); @@ -371,8 +348,6 @@ static int vmk80xx_reset_device(struct vmk80xx_usb *dev) int ival; size_t size; - dbgvm("vmk80xx: %s\n", __func__); - urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) return -ENOMEM; @@ -410,8 +385,6 @@ static void vmk80xx_build_int_urb(struct urb *urb, int flag) void (*callback) (struct urb *); int ival; - dbgvm("vmk80xx: %s\n", __func__); - if (flag & URB_RCV_FLAG) { rx_addr = dev->ep_rx->bEndpointAddress; pipe = usb_rcvintpipe(dev->udev, rx_addr); @@ -439,8 +412,6 @@ static void vmk80xx_do_bulk_msg(struct vmk80xx_usb *dev) unsigned int rx_pipe; size_t size; - dbgvm("vmk80xx: %s\n", __func__); - set_bit(TRANS_IN_BUSY, &dev->flags); set_bit(TRANS_OUT_BUSY, &dev->flags); @@ -468,8 +439,6 @@ static int vmk80xx_read_packet(struct vmk80xx_usb *dev) struct urb *urb; int retval; - dbgvm("vmk80xx: %s\n", __func__); - if (!dev->intf) return -ENODEV; @@ -516,8 +485,6 @@ static int vmk80xx_write_packet(struct vmk80xx_usb *dev, int cmd) struct urb *urb; int retval; - dbgvm("vmk80xx: %s\n", __func__); - if (!dev->intf) return -ENODEV; @@ -592,8 +559,6 @@ static int vmk80xx_ai_rinsn(struct comedi_device *cdev, int reg[2]; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_IN); if (n) return n; @@ -645,8 +610,6 @@ static int vmk80xx_ao_winsn(struct comedi_device *cdev, int reg; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_OUT); if (n) return n; @@ -690,8 +653,6 @@ static int vmk80xx_ao_rinsn(struct comedi_device *cdev, int reg; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_IN); if (n) return n; @@ -724,8 +685,6 @@ static int vmk80xx_di_bits(struct comedi_device *cdev, int reg; int retval; - dbgvm("vmk80xx: %s\n", __func__); - retval = rudimentary_check(dev, DIR_IN); if (retval) return retval; @@ -770,8 +729,6 @@ static int vmk80xx_di_rinsn(struct comedi_device *cdev, int inp; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_IN); if (n) return n; @@ -817,8 +774,6 @@ static int vmk80xx_do_winsn(struct comedi_device *cdev, int cmd; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_OUT); if (n) return n; @@ -865,8 +820,6 @@ static int vmk80xx_do_rinsn(struct comedi_device *cdev, int reg; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_IN); if (n) return n; @@ -899,8 +852,6 @@ static int vmk80xx_do_bits(struct comedi_device *cdev, int dir, reg, cmd; int retval; - dbgvm("vmk80xx: %s\n", __func__); - dir = 0; if (data[0]) @@ -966,8 +917,6 @@ static int vmk80xx_cnt_rinsn(struct comedi_device *cdev, int reg[2]; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_IN); if (n) return n; @@ -1016,8 +965,6 @@ static int vmk80xx_cnt_cinsn(struct comedi_device *cdev, int reg; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_OUT); if (n) return n; @@ -1064,8 +1011,6 @@ static int vmk80xx_cnt_winsn(struct comedi_device *cdev, int cmd; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_OUT); if (n) return n; @@ -1110,8 +1055,6 @@ static int vmk80xx_pwm_rinsn(struct comedi_device *cdev, int reg[2]; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_IN); if (n) return n; @@ -1145,8 +1088,6 @@ static int vmk80xx_pwm_winsn(struct comedi_device *cdev, int cmd; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_OUT); if (n) return n; @@ -1195,8 +1136,6 @@ static int vmk80xx_attach(struct comedi_device *cdev, struct comedi_subdevice *s; int minor; - dbgvm("vmk80xx: %s\n", __func__); - mutex_lock(&glb_mutex); for (i = 0; i < VMK80XX_MAX_BOARDS; i++) @@ -1316,8 +1255,6 @@ static int vmk80xx_detach(struct comedi_device *cdev) struct vmk80xx_usb *dev; int minor; - dbgvm("vmk80xx: %s\n", __func__); - if (!cdev) return -EFAULT; @@ -1350,8 +1287,6 @@ static int vmk80xx_probe(struct usb_interface *intf, struct usb_endpoint_descriptor *ep_desc; size_t size; - dbgvm("vmk80xx: %s\n", __func__); - mutex_lock(&glb_mutex); for (i = 0; i < VMK80XX_MAX_BOARDS; i++) @@ -1499,8 +1434,6 @@ static void vmk80xx_disconnect(struct usb_interface *intf) { struct vmk80xx_usb *dev = usb_get_intfdata(intf); - dbgvm("vmk80xx: %s\n", __func__); - if (!dev) return; -- cgit v0.10.2 From 40e7f510ef24e8455c15201b07d0b691caac5254 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 4 May 2012 11:50:57 -0700 Subject: staging: comedi: refactor unioxx5 driver and use module_comedi_driver Move the module_init/module_exit routines and the associated struct comedi_drive to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Convert the driver to use the module_comedi_driver() macro which makes the code smaller and a bit simpler. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c index f45824f..0eaca68 100644 --- a/drivers/staging/comedi/drivers/unioxx5.c +++ b/drivers/staging/comedi/drivers/unioxx5.c @@ -83,8 +83,6 @@ struct unioxx5_subd_priv { unsigned char usp_prev_cn_val[3]; /* previous channel value */ }; -static int unioxx5_attach(struct comedi_device *dev, - struct comedi_devconfig *it); static int unioxx5_subdev_write(struct comedi_device *dev, struct comedi_subdevice *subdev, struct comedi_insn *insn, unsigned int *data); @@ -94,9 +92,6 @@ static int unioxx5_subdev_read(struct comedi_device *dev, static int unioxx5_insn_config(struct comedi_device *dev, struct comedi_subdevice *subdev, struct comedi_insn *insn, unsigned int *data); -static int unioxx5_detach(struct comedi_device *dev); -static int __unioxx5_subdev_init(struct comedi_subdevice *subdev, - int subdev_iobase, int minor); static int __unioxx5_digital_write(struct unioxx5_subd_priv *usp, unsigned int *data, int channel, int minor); static int __unioxx5_digital_read(struct unioxx5_subd_priv *usp, @@ -109,72 +104,6 @@ static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp, static int __unioxx5_define_chan_offset(int chan_num); static void __unioxx5_analog_config(struct unioxx5_subd_priv *usp, int channel); -static struct comedi_driver unioxx5_driver = { - .driver_name = DRIVER_NAME, - .module = THIS_MODULE, - .attach = unioxx5_attach, - .detach = unioxx5_detach -}; - -static int __init unioxx5_driver_init_module(void) -{ - return comedi_driver_register(&unioxx5_driver); -} - -static void __exit unioxx5_driver_cleanup_module(void) -{ - comedi_driver_unregister(&unioxx5_driver); -} - -module_init(unioxx5_driver_init_module); -module_exit(unioxx5_driver_cleanup_module); - -static int unioxx5_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - int iobase, i, n_subd; - int id, num, ba; - - iobase = it->options[0]; - - dev->board_name = DRIVER_NAME; - dev->iobase = iobase; - iobase += UNIOXX5_SUBDEV_BASE; - - /* defining number of subdevices and getting they types (it must be 'g01') */ - for (i = n_subd = 0, ba = iobase; i < 4; i++, ba += UNIOXX5_SUBDEV_ODDS) { - id = inb(ba + 0xE); - num = inb(ba + 0xF); - - if (id != 'g' || num != 1) - continue; - - n_subd++; - } - - /* unioxx5 can has from two to four subdevices */ - if (n_subd < 2) { - printk(KERN_ERR - "your card must has at least 2 'g01' subdevices\n"); - return -1; - } - - if (alloc_subdevices(dev, n_subd) < 0) { - printk(KERN_ERR "out of memory\n"); - return -ENOMEM; - } - - /* initializing each of for same subdevices */ - for (i = 0; i < n_subd; i++, iobase += UNIOXX5_SUBDEV_ODDS) { - if (__unioxx5_subdev_init(&dev->subdevices[i], iobase, - dev->minor) < 0) - return -1; - } - - printk(KERN_INFO "attached\n"); - return 0; -} - static int unioxx5_subdev_read(struct comedi_device *dev, struct comedi_subdevice *subdev, struct comedi_insn *insn, unsigned int *data) @@ -275,22 +204,6 @@ static int unioxx5_insn_config(struct comedi_device *dev, return 0; } -static int unioxx5_detach(struct comedi_device *dev) -{ - int i; - struct comedi_subdevice *subdev; - struct unioxx5_subd_priv *usp; - - for (i = 0; i < dev->n_subdevices; i++) { - subdev = &dev->subdevices[i]; - usp = subdev->private; - release_region(usp->usp_iobase, UNIOXX5_SIZE); - kfree(subdev->private); - } - - return 0; -} - /* initializing subdevice with given address */ static int __unioxx5_subdev_init(struct comedi_subdevice *subdev, int subdev_iobase, int minor) @@ -553,6 +466,76 @@ static int __unioxx5_define_chan_offset(int chan_num) return (chan_num >> 3) + 1; } +static int unioxx5_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + int iobase, i, n_subd; + int id, num, ba; + + iobase = it->options[0]; + + dev->board_name = DRIVER_NAME; + dev->iobase = iobase; + iobase += UNIOXX5_SUBDEV_BASE; + + /* defining number of subdevices and getting they types (it must be 'g01') */ + for (i = n_subd = 0, ba = iobase; i < 4; i++, ba += UNIOXX5_SUBDEV_ODDS) { + id = inb(ba + 0xE); + num = inb(ba + 0xF); + + if (id != 'g' || num != 1) + continue; + + n_subd++; + } + + /* unioxx5 can has from two to four subdevices */ + if (n_subd < 2) { + printk(KERN_ERR + "your card must has at least 2 'g01' subdevices\n"); + return -1; + } + + if (alloc_subdevices(dev, n_subd) < 0) { + printk(KERN_ERR "out of memory\n"); + return -ENOMEM; + } + + /* initializing each of for same subdevices */ + for (i = 0; i < n_subd; i++, iobase += UNIOXX5_SUBDEV_ODDS) { + if (__unioxx5_subdev_init(&dev->subdevices[i], iobase, + dev->minor) < 0) + return -1; + } + + printk(KERN_INFO "attached\n"); + return 0; +} + +static int unioxx5_detach(struct comedi_device *dev) +{ + int i; + struct comedi_subdevice *subdev; + struct unioxx5_subd_priv *usp; + + for (i = 0; i < dev->n_subdevices; i++) { + subdev = &dev->subdevices[i]; + usp = subdev->private; + release_region(usp->usp_iobase, UNIOXX5_SIZE); + kfree(subdev->private); + } + + return 0; +} + +static struct comedi_driver unioxx5_driver = { + .driver_name = DRIVER_NAME, + .module = THIS_MODULE, + .attach = unioxx5_attach, + .detach = unioxx5_detach, +}; +module_comedi_driver(unioxx5_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From f1decb9b83865161df3bde9bbe9292aa7f8ab6fa Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 4 May 2012 14:26:56 -0700 Subject: staging: comedi: refactor ssv_dnp driver and use module_comedi_driver Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Convert the driver to use the module_comedi_driver() macro which makes the code smaller and a bit simpler. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c index 526de2e..25cb659 100644 --- a/drivers/staging/comedi/drivers/ssv_dnp.c +++ b/drivers/staging/comedi/drivers/ssv_dnp.c @@ -59,16 +59,6 @@ struct dnp_board { int have_dio; }; -/* We only support one DNP 'board' variant at the moment */ -static const struct dnp_board dnp_boards[] = { -{ - .name = "dnp-1486", - .ai_chans = 16, - .ai_bits = 12, - .have_dio = 1, - }, -}; - /* Useful for shorthand access to the particular board structure ----------- */ #define thisboard ((const struct dnp_board *)dev->board_ptr) @@ -81,136 +71,6 @@ struct dnp_private_data { #define devpriv ((dnp_private *)dev->private) /* ------------------------------------------------------------------------- */ -/* The struct comedi_driver structure tells the Comedi core module which */ -/* functions to call to configure/deconfigure (attach/detach) the board, and */ -/* also about the kernel module that contains the device code. */ -/* */ -/* In the following section we define the API of this driver. */ -/* ------------------------------------------------------------------------- */ - -static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int dnp_detach(struct comedi_device *dev); - -static struct comedi_driver driver_dnp = { - .driver_name = "ssv_dnp", - .module = THIS_MODULE, - .attach = dnp_attach, - .detach = dnp_detach, - .board_name = &dnp_boards[0].name, - /* only necessary for non-PnP devs */ - .offset = sizeof(struct dnp_board), /* like ISA-PnP, PCI or PCMCIA */ - .num_names = ARRAY_SIZE(dnp_boards), -}; - -static int __init driver_dnp_init_module(void) -{ - return comedi_driver_register(&driver_dnp); -} - -static void __exit driver_dnp_cleanup_module(void) -{ - comedi_driver_unregister(&driver_dnp); -} - -module_init(driver_dnp_init_module); -module_exit(driver_dnp_cleanup_module); - -static int dnp_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int dnp_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* ------------------------------------------------------------------------- */ -/* Attach is called by comedi core to configure the driver for a particular */ -/* board. If you specified a board_name array in the driver structure, */ -/* dev->board_ptr contains that address. */ -/* ------------------------------------------------------------------------- */ - -static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - - struct comedi_subdevice *s; - - printk(KERN_INFO "comedi%d: dnp: ", dev->minor); - - /* Autoprobing: this should find out which board we have. Currently */ - /* only the 1486 board is supported and autoprobing is not */ - /* implemented :-) */ - /* dev->board_ptr = dnp_probe(dev); */ - - /* Initialize the name of the board. */ - /* We can use the "thisboard" macro now. */ - dev->board_name = thisboard->name; - - /* Allocate the private structure area. alloc_private() is a */ - /* convenient macro defined in comedidev.h. */ - if (alloc_private(dev, sizeof(struct dnp_private_data)) < 0) - return -ENOMEM; - - /* Allocate the subdevice structures. alloc_subdevice() is a */ - /* convenient macro defined in comedidev.h. */ - - if (alloc_subdevices(dev, 1) < 0) - return -ENOMEM; - - s = dev->subdevices + 0; - /* digital i/o subdevice */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 20; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = dnp_dio_insn_bits; - s->insn_config = dnp_dio_insn_config; - - printk("attached\n"); - - /* We use the I/O ports 0x22,0x23 and 0xa3-0xa9, which are always - * allocated for the primary 8259, so we don't need to allocate them - * ourselves. */ - - /* configure all ports as input (default) */ - outb(PAMR, CSCIR); - outb(0x00, CSCDR); - outb(PBMR, CSCIR); - outb(0x00, CSCDR); - outb(PCMR, CSCIR); - outb((inb(CSCDR) & 0xAA), CSCDR); - - return 1; - -} - -/* ------------------------------------------------------------------------- */ -/* detach is called to deconfigure a device. It should deallocate the */ -/* resources. This function is also called when _attach() fails, so it */ -/* should be careful not to release resources that were not necessarily */ -/* allocated by _attach(). dev->private and dev->subdevices are */ -/* deallocated automatically by the core. */ -/* ------------------------------------------------------------------------- */ - -static int dnp_detach(struct comedi_device *dev) -{ - - /* configure all ports as input (default) */ - outb(PAMR, CSCIR); - outb(0x00, CSCDR); - outb(PBMR, CSCIR); - outb(0x00, CSCDR); - outb(PCMR, CSCIR); - outb((inb(CSCDR) & 0xAA), CSCDR); - - /* announce that we are finished */ - printk(KERN_INFO "comedi%d: dnp: remove\n", dev->minor); - - return 0; - -} - -/* ------------------------------------------------------------------------- */ /* The insn_bits interface allows packed reading/writing of DIO channels. */ /* The comedi core can convert between insn_bits and insn_read/write, so you */ /* are able to use these instructions as well. */ @@ -326,6 +186,95 @@ static int dnp_dio_insn_config(struct comedi_device *dev, } +static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + + printk(KERN_INFO "comedi%d: dnp: ", dev->minor); + + /* Autoprobing: this should find out which board we have. Currently */ + /* only the 1486 board is supported and autoprobing is not */ + /* implemented :-) */ + /* dev->board_ptr = dnp_probe(dev); */ + + /* Initialize the name of the board. */ + /* We can use the "thisboard" macro now. */ + dev->board_name = thisboard->name; + + /* Allocate the private structure area. alloc_private() is a */ + /* convenient macro defined in comedidev.h. */ + if (alloc_private(dev, sizeof(struct dnp_private_data)) < 0) + return -ENOMEM; + + /* Allocate the subdevice structures. alloc_subdevice() is a */ + /* convenient macro defined in comedidev.h. */ + + if (alloc_subdevices(dev, 1) < 0) + return -ENOMEM; + + s = dev->subdevices + 0; + /* digital i/o subdevice */ + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 20; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = dnp_dio_insn_bits; + s->insn_config = dnp_dio_insn_config; + + printk("attached\n"); + + /* We use the I/O ports 0x22,0x23 and 0xa3-0xa9, which are always + * allocated for the primary 8259, so we don't need to allocate them + * ourselves. */ + + /* configure all ports as input (default) */ + outb(PAMR, CSCIR); + outb(0x00, CSCDR); + outb(PBMR, CSCIR); + outb(0x00, CSCDR); + outb(PCMR, CSCIR); + outb((inb(CSCDR) & 0xAA), CSCDR); + + return 1; +} + +static int dnp_detach(struct comedi_device *dev) +{ + /* configure all ports as input (default) */ + outb(PAMR, CSCIR); + outb(0x00, CSCDR); + outb(PBMR, CSCIR); + outb(0x00, CSCDR); + outb(PCMR, CSCIR); + outb((inb(CSCDR) & 0xAA), CSCDR); + + /* announce that we are finished */ + printk(KERN_INFO "comedi%d: dnp: remove\n", dev->minor); + + return 0; +} + +static const struct dnp_board dnp_boards[] = { + { + .name = "dnp-1486", + .ai_chans = 16, + .ai_bits = 12, + .have_dio = 1, + }, +}; + +static struct comedi_driver dnp_driver = { + .driver_name = "ssv_dnp", + .module = THIS_MODULE, + .attach = dnp_attach, + .detach = dnp_detach, + .board_name = &dnp_boards[0].name, + .offset = sizeof(struct dnp_board), + .num_names = ARRAY_SIZE(dnp_boards), +}; +module_comedi_driver(dnp_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 7122b76de9ac87be45e8de1041d81d9ea0bf9e48 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 4 May 2012 14:37:36 -0700 Subject: staging: comedi: partial refactor of s626 driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index a0b7c71..ad4d2f6 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -79,10 +79,6 @@ INSN_CONFIG instructions: #include "comedi_fc.h" #include "s626.h" -MODULE_AUTHOR("Gianluca Palli "); -MODULE_DESCRIPTION("Sensoray 626 Comedi driver module"); -MODULE_LICENSE("GPL"); - #define PCI_VENDOR_ID_S626 0x1131 #define PCI_DEVICE_ID_S626 0x7146 #define PCI_SUBVENDOR_ID_S626 0x6000 @@ -122,28 +118,6 @@ static const struct s626_board s626_boards[] = { #define thisboard ((const struct s626_board *)dev->board_ptr) -/* - * For devices with vendor:device id == 0x1131:0x7146 you must specify - * also subvendor:subdevice ids, because otherwise it will conflict with - * Philips SAA7146 media/dvb based cards. - */ -static DEFINE_PCI_DEVICE_TABLE(s626_pci_table) = { - {PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626, PCI_SUBVENDOR_ID_S626, PCI_SUBDEVICE_ID_S626, 0, 0, 0}, - {0} -}; - -MODULE_DEVICE_TABLE(pci, s626_pci_table); - -static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int s626_detach(struct comedi_device *dev); - -static struct comedi_driver driver_s626 = { - .driver_name = "s626", - .module = THIS_MODULE, - .attach = s626_attach, - .detach = s626_detach, -}; - struct s626_private { struct pci_dev *pdev; void *base_addr; @@ -235,44 +209,6 @@ static struct dio_private *dio_private_word[]={ #define devpriv ((struct s626_private *)dev->private) #define diopriv ((struct dio_private *)s->private) -static int __devinit driver_s626_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, &driver_s626); -} - -static void __devexit driver_s626_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver driver_s626_pci_driver = { - .id_table = s626_pci_table, - .probe = &driver_s626_pci_probe, - .remove = __devexit_p(&driver_s626_pci_remove) -}; - -static int __init driver_s626_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_s626); - if (retval < 0) - return retval; - - driver_s626_pci_driver.name = (char *)driver_s626.driver_name; - return pci_register_driver(&driver_s626_pci_driver); -} - -static void __exit driver_s626_cleanup_module(void) -{ - pci_unregister_driver(&driver_s626_pci_driver); - comedi_driver_unregister(&driver_s626); -} - -module_init(driver_s626_init_module); -module_exit(driver_s626_cleanup_module); - /* ioctl routines */ static int s626_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, @@ -3378,3 +3314,63 @@ static void CountersInit(struct comedi_device *dev) DEBUG("CountersInit: counters initialized\n"); } + +static struct comedi_driver driver_s626 = { + .driver_name = "s626", + .module = THIS_MODULE, + .attach = s626_attach, + .detach = s626_detach, +}; + +static int __devinit driver_s626_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &driver_s626); +} + +static void __devexit driver_s626_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +/* + * For devices with vendor:device id == 0x1131:0x7146 you must specify + * also subvendor:subdevice ids, because otherwise it will conflict with + * Philips SAA7146 media/dvb based cards. + */ +static DEFINE_PCI_DEVICE_TABLE(s626_pci_table) = { + { PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626, + PCI_SUBVENDOR_ID_S626, PCI_SUBDEVICE_ID_S626, 0, 0, 0 }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, s626_pci_table); + +static struct pci_driver driver_s626_pci_driver = { + .id_table = s626_pci_table, + .probe = driver_s626_pci_probe, + .remove = __devexit_p(driver_s626_pci_remove), +}; + +static int __init driver_s626_init_module(void) +{ + int retval; + + retval = comedi_driver_register(&driver_s626); + if (retval < 0) + return retval; + + driver_s626_pci_driver.name = (char *)driver_s626.driver_name; + return pci_register_driver(&driver_s626_pci_driver); +} +module_init(driver_s626_init_module); + +static void __exit driver_s626_cleanup_module(void) +{ + pci_unregister_driver(&driver_s626_pci_driver); + comedi_driver_unregister(&driver_s626); +} +module_exit(driver_s626_cleanup_module); + +MODULE_AUTHOR("Gianluca Palli "); +MODULE_DESCRIPTION("Sensoray 626 Comedi driver module"); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From d573d6bd303d455fe7268c89ceba9288535b59ed Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 4 May 2012 15:19:49 -0700 Subject: staging: comedi: refactor multiq3 driver and use module_comedi_driver Move the struct comedi_driver to the end of the source. Convert the driver to use the module_comedi_driver() macro which makes the code smaller and a bit simpler. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c index dace902..206296c 100644 --- a/drivers/staging/comedi/drivers/multiq3.c +++ b/drivers/staging/comedi/drivers/multiq3.c @@ -83,29 +83,6 @@ Devices: [Quanser Consulting] MultiQ-3 (multiq3) #define MULTIQ3_TIMEOUT 30 -static int multiq3_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int multiq3_detach(struct comedi_device *dev); -static struct comedi_driver driver_multiq3 = { - .driver_name = "multiq3", - .module = THIS_MODULE, - .attach = multiq3_attach, - .detach = multiq3_detach, -}; - -static int __init driver_multiq3_init_module(void) -{ - return comedi_driver_register(&driver_multiq3); -} - -static void __exit driver_multiq3_cleanup_module(void) -{ - comedi_driver_unregister(&driver_multiq3); -} - -module_init(driver_multiq3_init_module); -module_exit(driver_multiq3_cleanup_module); - struct multiq3_private { unsigned int ao_readback[2]; }; @@ -350,6 +327,14 @@ static int multiq3_detach(struct comedi_device *dev) return 0; } +static struct comedi_driver multiq3_driver = { + .driver_name = "multiq3", + .module = THIS_MODULE, + .attach = multiq3_attach, + .detach = multiq3_detach, +}; +module_comedi_driver(multiq3_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 45d63679d82557f0fbac767c7dab0e4bedb72d35 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 4 May 2012 15:26:44 -0700 Subject: staging: comedi: refactor mpc8260cpm driver and use module_comedi_driver Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Convert the driver to use the module_comedi_driver() macro which makes the code smaller and a bit simpler. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/mpc8260cpm.c b/drivers/staging/comedi/drivers/mpc8260cpm.c index 5f6816a..f468775 100644 --- a/drivers/staging/comedi/drivers/mpc8260cpm.c +++ b/drivers/staging/comedi/drivers/mpc8260cpm.c @@ -46,75 +46,6 @@ struct mpc8260cpm_private { #define devpriv ((struct mpc8260cpm_private *)dev->private) -static int mpc8260cpm_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int mpc8260cpm_detach(struct comedi_device *dev); -static struct comedi_driver driver_mpc8260cpm = { - .driver_name = "mpc8260cpm", - .module = THIS_MODULE, - .attach = mpc8260cpm_attach, - .detach = mpc8260cpm_detach, -}; - -static int __init driver_mpc8260cpm_init_module(void) -{ - return comedi_driver_register(&driver_mpc8260cpm); -} - -static void __exit driver_mpc8260cpm_cleanup_module(void) -{ - comedi_driver_unregister(&driver_mpc8260cpm); -} - -module_init(driver_mpc8260cpm_init_module); -module_exit(driver_mpc8260cpm_cleanup_module); - -static int mpc8260cpm_dio_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int mpc8260cpm_dio_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int mpc8260cpm_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - int i; - - printk("comedi%d: mpc8260cpm: ", dev->minor); - - dev->board_ptr = mpc8260cpm_boards + dev->board; - - dev->board_name = thisboard->name; - - if (alloc_private(dev, sizeof(struct mpc8260cpm_private)) < 0) - return -ENOMEM; - - if (alloc_subdevices(dev, 4) < 0) - return -ENOMEM; - - for (i = 0; i < 4; i++) { - s = dev->subdevices + i; - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 32; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_config = mpc8260cpm_dio_config; - s->insn_bits = mpc8260cpm_dio_bits; - } - - return 1; -} - -static int mpc8260cpm_detach(struct comedi_device *dev) -{ - printk("comedi%d: mpc8260cpm: remove\n", dev->minor); - - return 0; -} - static unsigned long *cpm_pdat(int port) { switch (port) { @@ -184,3 +115,50 @@ static int mpc8260cpm_dio_bits(struct comedi_device *dev, return 2; } + +static int mpc8260cpm_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + int i; + + printk("comedi%d: mpc8260cpm: ", dev->minor); + + dev->board_ptr = mpc8260cpm_boards + dev->board; + + dev->board_name = thisboard->name; + + if (alloc_private(dev, sizeof(struct mpc8260cpm_private)) < 0) + return -ENOMEM; + + if (alloc_subdevices(dev, 4) < 0) + return -ENOMEM; + + for (i = 0; i < 4; i++) { + s = dev->subdevices + i; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 32; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_config = mpc8260cpm_dio_config; + s->insn_bits = mpc8260cpm_dio_bits; + } + + return 1; +} + +static int mpc8260cpm_detach(struct comedi_device *dev) +{ + printk("comedi%d: mpc8260cpm: remove\n", dev->minor); + + return 0; +} + +static struct comedi_driver mpc8260cpm_driver = { + .driver_name = "mpc8260cpm", + .module = THIS_MODULE, + .attach = mpc8260cpm_attach, + .detach = mpc8260cpm_detach, +}; +module_comedi_driver(mpc8260cpm_driver); -- cgit v0.10.2 From 9142e00efeeb8b06fe7f0c42fd2e9400223b9418 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 4 May 2012 15:33:17 -0700 Subject: staging: comedi: refactor mpc624 driver and use module_comedi_driver Move the struct comedi_driver and associated attach/detach routines to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Convert the driver to use the module_comedi_driver() macro which makes the code smaller and a bit simpler. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c index dd09a6d..25d8553 100644 --- a/drivers/staging/comedi/drivers/mpc624.c +++ b/drivers/staging/comedi/drivers/mpc624.c @@ -148,131 +148,6 @@ static const struct comedi_lrange range_mpc624_bipolar10 = { } }; -/* -------------------------------------------------------------------------- */ -static int mpc624_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int mpc624_detach(struct comedi_device *dev); -/* -------------------------------------------------------------------------- */ -static struct comedi_driver driver_mpc624 = { - .driver_name = "mpc624", - .module = THIS_MODULE, - .attach = mpc624_attach, - .detach = mpc624_detach -}; - -/* -------------------------------------------------------------------------- */ -static int mpc624_ai_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); -/* -------------------------------------------------------------------------- */ -static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - unsigned long iobase; - - iobase = it->options[0]; - printk(KERN_INFO "comedi%d: mpc624 [0x%04lx, ", dev->minor, iobase); - if (request_region(iobase, MPC624_SIZE, "mpc624") == NULL) { - printk(KERN_ERR "I/O port(s) in use\n"); - return -EIO; - } - - dev->iobase = iobase; - dev->board_name = "mpc624"; - - /* Private structure initialization */ - if (alloc_private(dev, sizeof(struct skel_private)) < 0) - return -ENOMEM; - - switch (it->options[1]) { - case 0: - devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz; - printk(KERN_INFO "3.52 kHz, "); - break; - case 1: - devpriv->ulConvertionRate = MPC624_SPEED_1_76_kHz; - printk(KERN_INFO "1.76 kHz, "); - break; - case 2: - devpriv->ulConvertionRate = MPC624_SPEED_880_Hz; - printk(KERN_INFO "880 Hz, "); - break; - case 3: - devpriv->ulConvertionRate = MPC624_SPEED_440_Hz; - printk(KERN_INFO "440 Hz, "); - break; - case 4: - devpriv->ulConvertionRate = MPC624_SPEED_220_Hz; - printk(KERN_INFO "220 Hz, "); - break; - case 5: - devpriv->ulConvertionRate = MPC624_SPEED_110_Hz; - printk(KERN_INFO "110 Hz, "); - break; - case 6: - devpriv->ulConvertionRate = MPC624_SPEED_55_Hz; - printk(KERN_INFO "55 Hz, "); - break; - case 7: - devpriv->ulConvertionRate = MPC624_SPEED_27_5_Hz; - printk(KERN_INFO "27.5 Hz, "); - break; - case 8: - devpriv->ulConvertionRate = MPC624_SPEED_13_75_Hz; - printk(KERN_INFO "13.75 Hz, "); - break; - case 9: - devpriv->ulConvertionRate = MPC624_SPEED_6_875_Hz; - printk(KERN_INFO "6.875 Hz, "); - break; - default: - printk - (KERN_ERR "illegal conversion rate setting!" - " Valid numbers are 0..9. Using 9 => 6.875 Hz, "); - devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz; - } - - /* Subdevices structures */ - if (alloc_subdevices(dev, 1) < 0) - return -ENOMEM; - - s = dev->subdevices + 0; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_DIFF; - s->n_chan = 8; - switch (it->options[1]) { - default: - s->maxdata = 0x3FFFFFFF; - printk(KERN_INFO "30 bit, "); - } - - switch (it->options[1]) { - case 0: - s->range_table = &range_mpc624_bipolar1; - printk(KERN_INFO "1.01V]: "); - break; - default: - s->range_table = &range_mpc624_bipolar10; - printk(KERN_INFO "10.1V]: "); - } - s->len_chanlist = 1; - s->insn_read = mpc624_ai_rinsn; - - printk(KERN_INFO "attached\n"); - - return 1; -} - -static int mpc624_detach(struct comedi_device *dev) -{ - printk(KERN_INFO "comedi%d: mpc624: remove\n", dev->minor); - - if (dev->iobase) - release_region(dev->iobase, MPC624_SIZE); - - return 0; -} - /* Timeout 200ms */ #define TIMEOUT 200 @@ -406,18 +281,121 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, return n; } -static int __init driver_mpc624_init_module(void) +static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - return comedi_driver_register(&driver_mpc624); + struct comedi_subdevice *s; + unsigned long iobase; + + iobase = it->options[0]; + printk(KERN_INFO "comedi%d: mpc624 [0x%04lx, ", dev->minor, iobase); + if (request_region(iobase, MPC624_SIZE, "mpc624") == NULL) { + printk(KERN_ERR "I/O port(s) in use\n"); + return -EIO; + } + + dev->iobase = iobase; + dev->board_name = "mpc624"; + + /* Private structure initialization */ + if (alloc_private(dev, sizeof(struct skel_private)) < 0) + return -ENOMEM; + + switch (it->options[1]) { + case 0: + devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz; + printk(KERN_INFO "3.52 kHz, "); + break; + case 1: + devpriv->ulConvertionRate = MPC624_SPEED_1_76_kHz; + printk(KERN_INFO "1.76 kHz, "); + break; + case 2: + devpriv->ulConvertionRate = MPC624_SPEED_880_Hz; + printk(KERN_INFO "880 Hz, "); + break; + case 3: + devpriv->ulConvertionRate = MPC624_SPEED_440_Hz; + printk(KERN_INFO "440 Hz, "); + break; + case 4: + devpriv->ulConvertionRate = MPC624_SPEED_220_Hz; + printk(KERN_INFO "220 Hz, "); + break; + case 5: + devpriv->ulConvertionRate = MPC624_SPEED_110_Hz; + printk(KERN_INFO "110 Hz, "); + break; + case 6: + devpriv->ulConvertionRate = MPC624_SPEED_55_Hz; + printk(KERN_INFO "55 Hz, "); + break; + case 7: + devpriv->ulConvertionRate = MPC624_SPEED_27_5_Hz; + printk(KERN_INFO "27.5 Hz, "); + break; + case 8: + devpriv->ulConvertionRate = MPC624_SPEED_13_75_Hz; + printk(KERN_INFO "13.75 Hz, "); + break; + case 9: + devpriv->ulConvertionRate = MPC624_SPEED_6_875_Hz; + printk(KERN_INFO "6.875 Hz, "); + break; + default: + printk + (KERN_ERR "illegal conversion rate setting!" + " Valid numbers are 0..9. Using 9 => 6.875 Hz, "); + devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz; + } + + /* Subdevices structures */ + if (alloc_subdevices(dev, 1) < 0) + return -ENOMEM; + + s = dev->subdevices + 0; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_DIFF; + s->n_chan = 8; + switch (it->options[1]) { + default: + s->maxdata = 0x3FFFFFFF; + printk(KERN_INFO "30 bit, "); + } + + switch (it->options[1]) { + case 0: + s->range_table = &range_mpc624_bipolar1; + printk(KERN_INFO "1.01V]: "); + break; + default: + s->range_table = &range_mpc624_bipolar10; + printk(KERN_INFO "10.1V]: "); + } + s->len_chanlist = 1; + s->insn_read = mpc624_ai_rinsn; + + printk(KERN_INFO "attached\n"); + + return 1; } -static void __exit driver_mpc624_cleanup_module(void) +static int mpc624_detach(struct comedi_device *dev) { - comedi_driver_unregister(&driver_mpc624); + printk(KERN_INFO "comedi%d: mpc624: remove\n", dev->minor); + + if (dev->iobase) + release_region(dev->iobase, MPC624_SIZE); + + return 0; } -module_init(driver_mpc624_init_module); -module_exit(driver_mpc624_cleanup_module); +static struct comedi_driver mpc624_driver = { + .driver_name = "mpc624", + .module = THIS_MODULE, + .attach = mpc624_attach, + .detach = mpc624_detach +}; +module_comedi_driver(mpc624_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); -- cgit v0.10.2 From 4d76714b03e6f69aee316a2fa467811796076607 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 4 May 2012 15:39:55 -0700 Subject: staging: comedi: refactor me_daq driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index e286dcb..4ce6339 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -146,10 +146,6 @@ from http://www.comedi.org #define ME_COUNTER_STARTDATA_B 0x0022 /* - | W */ #define ME_COUNTER_VALUE_B 0x0022 /* R | - */ -/* Function prototypes */ -static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int me_detach(struct comedi_device *dev); - static const struct comedi_lrange me2000_ai_range = { 8, { @@ -187,14 +183,6 @@ static const struct comedi_lrange me2600_ao_range = { } }; -static DEFINE_PCI_DEVICE_TABLE(me_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, ME2600_DEVICE_ID) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, ME2000_DEVICE_ID) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, me_pci_table); - /* Board specification structure */ struct me_board { const char *name; /* driver name */ @@ -247,51 +235,6 @@ static const struct me_board me_boards[] = { #define me_board_nbr (sizeof(me_boards)/sizeof(struct me_board)) -static struct comedi_driver me_driver = { - .driver_name = ME_DRIVER_NAME, - .module = THIS_MODULE, - .attach = me_attach, - .detach = me_detach, -}; - -static int __devinit me_driver_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, &me_driver); -} - -static void __devexit me_driver_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver me_driver_pci_driver = { - .id_table = me_pci_table, - .probe = &me_driver_pci_probe, - .remove = __devexit_p(&me_driver_pci_remove) -}; - -static int __init me_driver_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&me_driver); - if (retval < 0) - return retval; - - me_driver_pci_driver.name = (char *)me_driver.driver_name; - return pci_register_driver(&me_driver_pci_driver); -} - -static void __exit me_driver_cleanup_module(void) -{ - pci_unregister_driver(&me_driver_pci_driver); - comedi_driver_unregister(&me_driver); -} - -module_init(me_driver_init_module); -module_exit(me_driver_cleanup_module); - /* Private data structure */ struct me_private_data { struct pci_dev *pci_device; @@ -669,12 +612,6 @@ static int me_reset(struct comedi_device *dev) return 0; } -/* - * Attach - * - * - Register PCI device - * - Declare device driver capability - */ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct pci_dev *pci_device = NULL; @@ -869,7 +806,6 @@ found: return 0; } -/* Detach */ static int me_detach(struct comedi_device *dev) { if (dev_private) { @@ -889,6 +825,57 @@ static int me_detach(struct comedi_device *dev) return 0; } +static struct comedi_driver me_driver = { + .driver_name = ME_DRIVER_NAME, + .module = THIS_MODULE, + .attach = me_attach, + .detach = me_detach, +}; + +static int __devinit me_driver_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &me_driver); +} + +static void __devexit me_driver_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(me_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, ME2600_DEVICE_ID) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, ME2000_DEVICE_ID) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, me_pci_table); + +static struct pci_driver me_driver_pci_driver = { + .id_table = me_pci_table, + .probe = me_driver_pci_probe, + .remove = __devexit_p(me_driver_pci_remove), +}; + +static int __init me_driver_init_module(void) +{ + int retval; + + retval = comedi_driver_register(&me_driver); + if (retval < 0) + return retval; + + me_driver_pci_driver.name = (char *)me_driver.driver_name; + return pci_register_driver(&me_driver_pci_driver); +} +module_init(me_driver_init_module); + +static void __exit me_driver_cleanup_module(void) +{ + pci_unregister_driver(&me_driver_pci_driver); + comedi_driver_unregister(&me_driver); +} +module_exit(me_driver_cleanup_module); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 3af09830558dde82602366637dec84d63ff724d7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 4 May 2012 15:51:25 -0700 Subject: staging: comedi: refactor me4000 driver to remove forward declarations Move the struct comedi_driver, attach/detach functions, and associated variables to the end of the source. This is more typical of how other drivers are written and removes the need for most of the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 54bcacc..c54c071 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -65,30 +65,6 @@ broken. #include "me4000_fw.h" #endif -/*============================================================================= - PCI device table. - This is used by modprobe to translate PCI IDs to drivers. - ===========================================================================*/ - -static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4650) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4660) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4661) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4662) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4663) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4670) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4671) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4672) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4673) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4680) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4681) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4682) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4683) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, me4000_pci_table); - static const struct me4000_board me4000_boards[] = { {"ME-4650", 0x4650, {0, 0}, {16, 0, 0, 0}, {4}, {0} }, @@ -113,22 +89,8 @@ static const struct me4000_board me4000_boards[] = { #define ME4000_BOARD_VERSIONS (ARRAY_SIZE(me4000_boards) - 1) /*----------------------------------------------------------------------------- - Comedi function prototypes - ---------------------------------------------------------------------------*/ -static int me4000_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int me4000_detach(struct comedi_device *dev); -static struct comedi_driver driver_me4000 = { - .driver_name = "me4000", - .module = THIS_MODULE, - .attach = me4000_attach, - .detach = me4000_detach, -}; - -/*----------------------------------------------------------------------------- Meilhaus function prototypes ---------------------------------------------------------------------------*/ -static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it); static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p); static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p); @@ -139,76 +101,10 @@ static int init_cnt_context(struct comedi_device *dev); static int xilinx_download(struct comedi_device *dev); static int reset_board(struct comedi_device *dev); -static int me4000_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int me4000_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int cnt_reset(struct comedi_device *dev, unsigned int channel); - -static int cnt_config(struct comedi_device *dev, - unsigned int channel, unsigned int mode); - -static int me4000_cnt_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int me4000_cnt_insn_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int me4000_cnt_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int me4000_ai_insn_read(struct comedi_device *dev, - struct comedi_subdevice *subdevice, - struct comedi_insn *insn, unsigned int *data); - -static int me4000_ai_cancel(struct comedi_device *dev, - struct comedi_subdevice *s); - -static int ai_check_chanlist(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd); - -static int ai_round_cmd_args(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd, - unsigned int *init_ticks, - unsigned int *scan_ticks, - unsigned int *chan_ticks); - -static int ai_prepare(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd, - unsigned int init_ticks, - unsigned int scan_ticks, unsigned int chan_ticks); - static int ai_write_chanlist(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd); -static irqreturn_t me4000_ai_isr(int irq, void *dev_id); - -static int me4000_ai_do_cmd_test(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd); - -static int me4000_ai_do_cmd(struct comedi_device *dev, - struct comedi_subdevice *s); - -static int me4000_ao_insn_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int me4000_ao_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - /*----------------------------------------------------------------------------- Meilhaus inline functions ---------------------------------------------------------------------------*/ @@ -262,130 +158,6 @@ static const struct comedi_lrange me4000_ao_range = { } }; -static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - int result; - - CALL_PDEBUG("In me4000_attach()\n"); - - result = me4000_probe(dev, it); - if (result) - return result; - - /* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. It relies on - * n_subdevices being set correctly. - */ - if (alloc_subdevices(dev, 4) < 0) - return -ENOMEM; - - /*========================================================================= - Analog input subdevice - ========================================================================*/ - - s = dev->subdevices + 0; - - if (thisboard->ai.count) { - s->type = COMEDI_SUBD_AI; - s->subdev_flags = - SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; - s->n_chan = thisboard->ai.count; - s->maxdata = 0xFFFF; /* 16 bit ADC */ - s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT; - s->range_table = &me4000_ai_range; - s->insn_read = me4000_ai_insn_read; - - if (info->irq > 0) { - if (request_irq(info->irq, me4000_ai_isr, - IRQF_SHARED, "ME-4000", dev)) { - printk - ("comedi%d: me4000: me4000_attach(): " - "Unable to allocate irq\n", dev->minor); - } else { - dev->read_subdev = s; - s->subdev_flags |= SDF_CMD_READ; - s->cancel = me4000_ai_cancel; - s->do_cmdtest = me4000_ai_do_cmd_test; - s->do_cmd = me4000_ai_do_cmd; - } - } else { - printk(KERN_WARNING - "comedi%d: me4000: me4000_attach(): " - "No interrupt available\n", dev->minor); - } - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - /*========================================================================= - Analog output subdevice - ========================================================================*/ - - s = dev->subdevices + 1; - - if (thisboard->ao.count) { - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND; - s->n_chan = thisboard->ao.count; - s->maxdata = 0xFFFF; /* 16 bit DAC */ - s->range_table = &me4000_ao_range; - s->insn_write = me4000_ao_insn_write; - s->insn_read = me4000_ao_insn_read; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - /*========================================================================= - Digital I/O subdevice - ========================================================================*/ - - s = dev->subdevices + 2; - - if (thisboard->dio.count) { - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = thisboard->dio.count * 8; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = me4000_dio_insn_bits; - s->insn_config = me4000_dio_insn_config; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - /* - * Check for optoisolated ME-4000 version. If one the first - * port is a fixed output port and the second is a fixed input port. - */ - if (!me4000_inl(dev, info->dio_context.dir_reg)) { - s->io_bits |= 0xFF; - me4000_outl(dev, ME4000_DIO_CTRL_BIT_MODE_0, - info->dio_context.dir_reg); - } - - /*========================================================================= - Counter subdevice - ========================================================================*/ - - s = dev->subdevices + 3; - - if (thisboard->cnt.count) { - s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = thisboard->cnt.count; - s->maxdata = 0xFFFF; /* 16 bit counters */ - s->insn_read = me4000_cnt_insn_read; - s->insn_write = me4000_cnt_insn_write; - s->insn_config = me4000_cnt_insn_config; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - return 0; -} - static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it) { struct pci_dev *pci_device = NULL; @@ -920,22 +692,6 @@ static int reset_board(struct comedi_device *dev) return 0; } -static int me4000_detach(struct comedi_device *dev) -{ - CALL_PDEBUG("In me4000_detach()\n"); - - if (info) { - if (info->pci_dev_p) { - reset_board(dev); - if (info->plx_regbase) - comedi_pci_disable(info->pci_dev_p); - pci_dev_put(info->pci_dev_p); - } - } - - return 0; -} - /*============================================================================= Analog input section ===========================================================================*/ @@ -2424,6 +2180,153 @@ static int me4000_cnt_insn_write(struct comedi_device *dev, return 1; } +static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + int result; + + CALL_PDEBUG("In me4000_attach()\n"); + + result = me4000_probe(dev, it); + if (result) + return result; + + /* + * Allocate the subdevice structures. alloc_subdevice() is a + * convenient macro defined in comedidev.h. It relies on + * n_subdevices being set correctly. + */ + if (alloc_subdevices(dev, 4) < 0) + return -ENOMEM; + + /*========================================================================= + Analog input subdevice + ========================================================================*/ + + s = dev->subdevices + 0; + + if (thisboard->ai.count) { + s->type = COMEDI_SUBD_AI; + s->subdev_flags = + SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; + s->n_chan = thisboard->ai.count; + s->maxdata = 0xFFFF; /* 16 bit ADC */ + s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT; + s->range_table = &me4000_ai_range; + s->insn_read = me4000_ai_insn_read; + + if (info->irq > 0) { + if (request_irq(info->irq, me4000_ai_isr, + IRQF_SHARED, "ME-4000", dev)) { + printk + ("comedi%d: me4000: me4000_attach(): " + "Unable to allocate irq\n", dev->minor); + } else { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->cancel = me4000_ai_cancel; + s->do_cmdtest = me4000_ai_do_cmd_test; + s->do_cmd = me4000_ai_do_cmd; + } + } else { + printk(KERN_WARNING + "comedi%d: me4000: me4000_attach(): " + "No interrupt available\n", dev->minor); + } + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /*========================================================================= + Analog output subdevice + ========================================================================*/ + + s = dev->subdevices + 1; + + if (thisboard->ao.count) { + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND; + s->n_chan = thisboard->ao.count; + s->maxdata = 0xFFFF; /* 16 bit DAC */ + s->range_table = &me4000_ao_range; + s->insn_write = me4000_ao_insn_write; + s->insn_read = me4000_ao_insn_read; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /*========================================================================= + Digital I/O subdevice + ========================================================================*/ + + s = dev->subdevices + 2; + + if (thisboard->dio.count) { + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = thisboard->dio.count * 8; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = me4000_dio_insn_bits; + s->insn_config = me4000_dio_insn_config; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* + * Check for optoisolated ME-4000 version. If one the first + * port is a fixed output port and the second is a fixed input port. + */ + if (!me4000_inl(dev, info->dio_context.dir_reg)) { + s->io_bits |= 0xFF; + me4000_outl(dev, ME4000_DIO_CTRL_BIT_MODE_0, + info->dio_context.dir_reg); + } + + /*========================================================================= + Counter subdevice + ========================================================================*/ + + s = dev->subdevices + 3; + + if (thisboard->cnt.count) { + s->type = COMEDI_SUBD_COUNTER; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = thisboard->cnt.count; + s->maxdata = 0xFFFF; /* 16 bit counters */ + s->insn_read = me4000_cnt_insn_read; + s->insn_write = me4000_cnt_insn_write; + s->insn_config = me4000_cnt_insn_config; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + return 0; +} + +static int me4000_detach(struct comedi_device *dev) +{ + CALL_PDEBUG("In me4000_detach()\n"); + + if (info) { + if (info->pci_dev_p) { + reset_board(dev); + if (info->plx_regbase) + comedi_pci_disable(info->pci_dev_p); + pci_dev_put(info->pci_dev_p); + } + } + + return 0; +} + +static struct comedi_driver driver_me4000 = { + .driver_name = "me4000", + .module = THIS_MODULE, + .attach = me4000_attach, + .detach = me4000_detach, +}; + static int __devinit driver_me4000_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { @@ -2435,10 +2338,28 @@ static void __devexit driver_me4000_pci_remove(struct pci_dev *dev) comedi_pci_auto_unconfig(dev); } +static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4650) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4660) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4661) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4662) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4663) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4670) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4671) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4672) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4673) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4680) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4681) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4682) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4683) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, me4000_pci_table); + static struct pci_driver driver_me4000_pci_driver = { - .id_table = me4000_pci_table, - .probe = &driver_me4000_pci_probe, - .remove = __devexit_p(&driver_me4000_pci_remove) + .id_table = me4000_pci_table, + .probe = driver_me4000_pci_probe, + .remove = __devexit_p(driver_me4000_pci_remove), }; static int __init driver_me4000_init_module(void) @@ -2452,14 +2373,13 @@ static int __init driver_me4000_init_module(void) driver_me4000_pci_driver.name = (char *)driver_me4000.driver_name; return pci_register_driver(&driver_me4000_pci_driver); } +module_init(driver_me4000_init_module); static void __exit driver_me4000_cleanup_module(void) { pci_unregister_driver(&driver_me4000_pci_driver); comedi_driver_unregister(&driver_me4000); } - -module_init(driver_me4000_init_module); module_exit(driver_me4000_cleanup_module); MODULE_AUTHOR("Comedi http://www.comedi.org"); -- cgit v0.10.2 From df61178c5159747be663a7a74116f1d68557fc5d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 4 May 2012 15:57:24 -0700 Subject: staging: comedi: refactor jr3_pci driver to remove forward declarations Move the struct comedi_driver and associated variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 114885d..9e21de0 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -59,28 +59,6 @@ Devices: [JR3] PCI force sensor board (jr3_pci) #define PCI_DEVICE_ID_JR3_3_CHANNEL 0x3113 #define PCI_DEVICE_ID_JR3_4_CHANNEL 0x3114 -static int jr3_pci_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int jr3_pci_detach(struct comedi_device *dev); - -static struct comedi_driver driver_jr3_pci = { - .driver_name = "jr3_pci", - .module = THIS_MODULE, - .attach = jr3_pci_attach, - .detach = jr3_pci_detach, -}; - -static DEFINE_PCI_DEVICE_TABLE(jr3_pci_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL) }, - { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL_NEW) }, - { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_2_CHANNEL) }, - { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_3_CHANNEL) }, - { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_4_CHANNEL) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, jr3_pci_pci_table); - struct jr3_pci_dev_private { struct pci_dev *pci_dev; @@ -948,8 +926,6 @@ out: return result; } -MODULE_FIRMWARE("comedi/jr3pci.idm"); - static int jr3_pci_detach(struct comedi_device *dev) { int i; @@ -974,6 +950,13 @@ static int jr3_pci_detach(struct comedi_device *dev) return 0; } +static struct comedi_driver driver_jr3_pci = { + .driver_name = "jr3_pci", + .module = THIS_MODULE, + .attach = jr3_pci_attach, + .detach = jr3_pci_detach, +}; + static int __devinit driver_jr3_pci_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { @@ -985,10 +968,20 @@ static void __devexit driver_jr3_pci_pci_remove(struct pci_dev *dev) comedi_pci_auto_unconfig(dev); } +static DEFINE_PCI_DEVICE_TABLE(jr3_pci_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL) }, + { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL_NEW) }, + { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_2_CHANNEL) }, + { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_3_CHANNEL) }, + { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_4_CHANNEL) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, jr3_pci_pci_table); + static struct pci_driver driver_jr3_pci_pci_driver = { - .id_table = jr3_pci_pci_table, - .probe = &driver_jr3_pci_pci_probe, - .remove = __devexit_p(&driver_jr3_pci_pci_remove) + .id_table = jr3_pci_pci_table, + .probe = driver_jr3_pci_pci_probe, + .remove = __devexit_p(driver_jr3_pci_pci_remove), }; static int __init driver_jr3_pci_init_module(void) @@ -1002,16 +995,16 @@ static int __init driver_jr3_pci_init_module(void) driver_jr3_pci_pci_driver.name = (char *)driver_jr3_pci.driver_name; return pci_register_driver(&driver_jr3_pci_pci_driver); } +module_init(driver_jr3_pci_init_module); static void __exit driver_jr3_pci_cleanup_module(void) { pci_unregister_driver(&driver_jr3_pci_pci_driver); comedi_driver_unregister(&driver_jr3_pci); } - -module_init(driver_jr3_pci_init_module); module_exit(driver_jr3_pci_cleanup_module); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("comedi/jr3pci.idm"); -- cgit v0.10.2 From d79fc8e161c56626b67226198871c16aa0fcad15 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 4 May 2012 16:19:26 -0700 Subject: staging: comedi: refactor the icp_multi driver to remove forward declarations Move the setup_channel_list function forward in the souce and the struct comedi_driver and associated variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Remove the unnecessary comments for the attach/detach functions. Change the initialization of struct boardtype to c99 syntax and remove the comments. Convert the driver to use the module_comedi_driver() macro which makes the code smaller and a bit simpler. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 67b6f5a..0f63fc0 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -121,15 +121,6 @@ static const char range_codes_analog[] = { 0x00, 0x20, 0x10, 0x30 }; /* ============================================================================== - Forward declarations -============================================================================== -*/ -static int icp_multi_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int icp_multi_detach(struct comedi_device *dev); - -/* -============================================================================== Data & Structure declarations ============================================================================== */ @@ -154,48 +145,6 @@ struct boardtype { const struct comedi_lrange *rangelist_ao; /* rangelist for D/A */ }; -static const struct boardtype boardtypes[] = { - {"icp_multi", /* Driver name */ - DEVICE_ID, /* PCI device ID */ - IORANGE_ICP_MULTI, /* I/O range length */ - 1, /* 1=Card supports interrupts */ - TYPE_ICP_MULTI, /* Card type = ICP MULTI */ - 16, /* Num of A/D channels */ - 8, /* Num of A/D channels in diff mode */ - 4, /* Num of D/A channels */ - 16, /* Num of digital inputs */ - 8, /* Num of digital outputs */ - 4, /* Num of counters */ - 0x0fff, /* Resolution of A/D */ - 0x0fff, /* Resolution of D/A */ - &range_analog, /* Rangelist for A/D */ - range_codes_analog, /* Range codes for programming */ - &range_analog}, /* Rangelist for D/A */ -}; - -static struct comedi_driver driver_icp_multi = { - .driver_name = "icp_multi", - .module = THIS_MODULE, - .attach = icp_multi_attach, - .detach = icp_multi_detach, - .num_names = ARRAY_SIZE(boardtypes), - .board_name = &boardtypes[0].name, - .offset = sizeof(struct boardtype), -}; - -static int __init driver_icp_multi_init_module(void) -{ - return comedi_driver_register(&driver_icp_multi); -} - -static void __exit driver_icp_multi_cleanup_module(void) -{ - comedi_driver_unregister(&driver_icp_multi); -} - -module_init(driver_icp_multi_init_module); -module_exit(driver_icp_multi_cleanup_module); - struct icp_multi_private { struct pcilst_struct *card; /* pointer to card */ char valid; /* card is usable */ @@ -220,25 +169,81 @@ struct icp_multi_private { /* ============================================================================== - More forward declarations + +Name: setup_channel_list + +Description: + This function sets the appropriate channel selection, + differential input mode and range bits in the ADC Command/ + Status register. + +Parameters: + struct comedi_device *dev Pointer to current service structure + struct comedi_subdevice *s Pointer to current subdevice structure + unsigned int *chanlist Pointer to packed channel list + unsigned int n_chan Number of channels to scan + +Returns:Void + ============================================================================== */ - -#if 0 -static int check_channel_list(struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned int *chanlist, unsigned int n_chan); -#endif static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s, - unsigned int *chanlist, unsigned int n_chan); -static int icp_multi_reset(struct comedi_device *dev); + unsigned int *chanlist, unsigned int n_chan) +{ + unsigned int i, range, chanprog; + unsigned int diff; -/* -============================================================================== - Functions -============================================================================== -*/ +#ifdef ICP_MULTI_EXTDEBUG + printk(KERN_DEBUG + "icp multi EDBG: setup_channel_list(...,%d)\n", n_chan); +#endif + devpriv->act_chanlist_len = n_chan; + devpriv->act_chanlist_pos = 0; + + for (i = 0; i < n_chan; i++) { + /* Get channel */ + chanprog = CR_CHAN(chanlist[i]); + + /* Determine if it is a differential channel (Bit 15 = 1) */ + if (CR_AREF(chanlist[i]) == AREF_DIFF) { + diff = 1; + chanprog &= 0x0007; + } else { + diff = 0; + chanprog &= 0x000f; + } + + /* Clear channel, range and input mode bits + * in A/D command/status register */ + devpriv->AdcCmdStatus &= 0xf00f; + + /* Set channel number and differential mode status bit */ + if (diff) { + /* Set channel number, bits 9-11 & mode, bit 6 */ + devpriv->AdcCmdStatus |= (chanprog << 9); + devpriv->AdcCmdStatus |= ADC_DI; + } else + /* Set channel number, bits 8-11 */ + devpriv->AdcCmdStatus |= (chanprog << 8); + + /* Get range for current channel */ + range = this_board->rangecode[CR_RANGE(chanlist[i])]; + /* Set range. bits 4-5 */ + devpriv->AdcCmdStatus |= range; + + /* Output channel, range, mode to ICP Multi */ + writew(devpriv->AdcCmdStatus, + devpriv->io_addr + ICP_MULTI_ADC_CSR); + +#ifdef ICP_MULTI_EXTDEBUG + printk(KERN_DEBUG + "GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range, + devpriv->act_chanlist[i]); +#endif + } + +} /* ============================================================================== @@ -762,84 +767,6 @@ static int check_channel_list(struct comedi_device *dev, /* ============================================================================== -Name: setup_channel_list - -Description: - This function sets the appropriate channel selection, - differential input mode and range bits in the ADC Command/ - Status register. - -Parameters: - struct comedi_device *dev Pointer to current service structure - struct comedi_subdevice *s Pointer to current subdevice structure - unsigned int *chanlist Pointer to packed channel list - unsigned int n_chan Number of channels to scan - -Returns:Void - -============================================================================== -*/ -static void setup_channel_list(struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned int *chanlist, unsigned int n_chan) -{ - unsigned int i, range, chanprog; - unsigned int diff; - -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG - "icp multi EDBG: setup_channel_list(...,%d)\n", n_chan); -#endif - devpriv->act_chanlist_len = n_chan; - devpriv->act_chanlist_pos = 0; - - for (i = 0; i < n_chan; i++) { - /* Get channel */ - chanprog = CR_CHAN(chanlist[i]); - - /* Determine if it is a differential channel (Bit 15 = 1) */ - if (CR_AREF(chanlist[i]) == AREF_DIFF) { - diff = 1; - chanprog &= 0x0007; - } else { - diff = 0; - chanprog &= 0x000f; - } - - /* Clear channel, range and input mode bits - * in A/D command/status register */ - devpriv->AdcCmdStatus &= 0xf00f; - - /* Set channel number and differential mode status bit */ - if (diff) { - /* Set channel number, bits 9-11 & mode, bit 6 */ - devpriv->AdcCmdStatus |= (chanprog << 9); - devpriv->AdcCmdStatus |= ADC_DI; - } else - /* Set channel number, bits 8-11 */ - devpriv->AdcCmdStatus |= (chanprog << 8); - - /* Get range for current channel */ - range = this_board->rangecode[CR_RANGE(chanlist[i])]; - /* Set range. bits 4-5 */ - devpriv->AdcCmdStatus |= range; - - /* Output channel, range, mode to ICP Multi */ - writew(devpriv->AdcCmdStatus, - devpriv->io_addr + ICP_MULTI_ADC_CSR); - -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG - "GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range, - devpriv->act_chanlist[i]); -#endif - } - -} - -/* -============================================================================== - Name: icp_multi_reset Description: @@ -895,23 +822,6 @@ static int icp_multi_reset(struct comedi_device *dev) return 0; } -/* -============================================================================== - -Name: icp_multi_attach - -Description: - This function sets up all the appropriate data for the current - device. - -Parameters: - struct comedi_device *dev Pointer to current device structure - struct comedi_devconfig *it Pointer to current device configuration - -Returns:int 0 = success - -============================================================================== -*/ static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -1097,25 +1007,8 @@ static int icp_multi_attach(struct comedi_device *dev, return 0; } -/* -============================================================================== - -Name: icp_multi_detach - -Description: - This function releases all the resources used by the current - device. - -Parameters: - struct comedi_device *dev Pointer to current device structure - -Returns:int 0 = success - -============================================================================== -*/ static int icp_multi_detach(struct comedi_device *dev) { - if (dev->private) if (devpriv->valid) icp_multi_reset(dev); @@ -1135,6 +1028,38 @@ static int icp_multi_detach(struct comedi_device *dev) return 0; } +static const struct boardtype boardtypes[] = { + { + .name = "icp_multi", + .device_id = DEVICE_ID, + .iorange = IORANGE_ICP_MULTI, + .have_irq = 1, + .cardtype = TYPE_ICP_MULTI, + .n_aichan = 16, + .n_aichand = 8, + .n_aochan = 4, + .n_dichan = 16, + .n_dochan = 8, + .n_ctrs = 4, + .ai_maxdata = 0x0fff, + .ao_maxdata = 0x0fff, + .rangelist_ai = &range_analog, + .rangecode = range_codes_analog, + .rangelist_ao = &range_analog, + }, +}; + +static struct comedi_driver icp_multi_driver = { + .driver_name = "icp_multi", + .module = THIS_MODULE, + .attach = icp_multi_attach, + .detach = icp_multi_detach, + .num_names = ARRAY_SIZE(boardtypes), + .board_name = &boardtypes[0].name, + .offset = sizeof(struct boardtype), +}; +module_comedi_driver(icp_multi_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From de9f2db41e6037fc4b9944edc62025327e4b9589 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 4 May 2012 16:31:58 -0700 Subject: staging: comedi: refactor dyna_pci10xx driver to remove forward declarations Move the struct comedi_driver and associated variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index f54e7ff..bb86c85 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -48,17 +48,6 @@ static DEFINE_MUTEX(start_stop_sem); -static DEFINE_PCI_DEVICE_TABLE(dyna_pci10xx_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_DYNALOG, 0x1050) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, dyna_pci10xx_pci_table); - -static int dyna_pci10xx_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int dyna_pci10xx_detach(struct comedi_device *dev); - static const struct comedi_lrange range_pci1050_ai = { 3, { BIP_RANGE(10), BIP_RANGE(5), @@ -113,16 +102,6 @@ static const struct boardtype boardtypes[] = { {.name = DRV_NAME}, }; -static struct comedi_driver driver_dyna_pci10xx = { - .driver_name = DRV_NAME, - .module = THIS_MODULE, - .attach = dyna_pci10xx_attach, - .detach = dyna_pci10xx_detach, - .board_name = &boardtypes[0].name, - .offset = sizeof(struct boardtype), - .num_names = ARRAY_SIZE(boardtypes), -}; - struct dyna_pci10xx_private { struct pci_dev *pci_dev; /* ptr to PCI device */ char valid; /* card is usable */ @@ -418,6 +397,16 @@ static int dyna_pci10xx_detach(struct comedi_device *dev) return 0; } +static struct comedi_driver driver_dyna_pci10xx = { + .driver_name = DRV_NAME, + .module = THIS_MODULE, + .attach = dyna_pci10xx_attach, + .detach = dyna_pci10xx_detach, + .board_name = &boardtypes[0].name, + .offset = sizeof(struct boardtype), + .num_names = ARRAY_SIZE(boardtypes), +}; + static int __devinit driver_dyna_pci10xx_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { @@ -429,10 +418,16 @@ static void __devexit driver_dyna_pci10xx_pci_remove(struct pci_dev *dev) comedi_pci_auto_unconfig(dev); } +static DEFINE_PCI_DEVICE_TABLE(dyna_pci10xx_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_DYNALOG, 0x1050) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, dyna_pci10xx_pci_table); + static struct pci_driver driver_dyna_pci10xx_pci_driver = { - .id_table = dyna_pci10xx_pci_table, - .probe = &driver_dyna_pci10xx_pci_probe, - .remove = __devexit_p(&driver_dyna_pci10xx_pci_remove) + .id_table = dyna_pci10xx_pci_table, + .probe = driver_dyna_pci10xx_pci_probe, + .remove = __devexit_p(driver_dyna_pci10xx_pci_remove), }; static int __init driver_dyna_pci10xx_init_module(void) @@ -447,14 +442,13 @@ static int __init driver_dyna_pci10xx_init_module(void) (char *)driver_dyna_pci10xx.driver_name; return pci_register_driver(&driver_dyna_pci10xx_pci_driver); } +module_init(driver_dyna_pci10xx_init_module); static void __exit driver_dyna_pci10xx_cleanup_module(void) { pci_unregister_driver(&driver_dyna_pci10xx_pci_driver); comedi_driver_unregister(&driver_dyna_pci10xx); } - -module_init(driver_dyna_pci10xx_init_module); module_exit(driver_dyna_pci10xx_cleanup_module); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 15362c5ec49bbb5d7b244d2db2e1779f3220c04a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 4 May 2012 16:49:45 -0700 Subject: staging: comedi: refactor dt3000 driver to remove forward declarations Move the module_init/module_exit routines and the associated struct comedi_driver and other variables to the end of the source. This is more typical of how other drivers are written. Also, refactor a couple of the pci helper functions used during the attach. The removes the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index d44c89d..932eac9 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -164,19 +164,6 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = { #define n_dt3k_boards sizeof(dt3k_boardtypes)/sizeof(struct dt3k_boardtype) #define this_board ((const struct dt3k_boardtype *)dev->board_ptr) -static DEFINE_PCI_DEVICE_TABLE(dt3k_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0022) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0027) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0023) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0024) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0028) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0025) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0026) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, dt3k_pci_table); - #define DT3000_SIZE (4*0x1000) /* dual-ported RAM location definitions */ @@ -276,54 +263,6 @@ struct dt3k_private { #define devpriv ((struct dt3k_private *)dev->private) -static int dt3000_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int dt3000_detach(struct comedi_device *dev); -static struct comedi_driver driver_dt3000 = { - .driver_name = "dt3000", - .module = THIS_MODULE, - .attach = dt3000_attach, - .detach = dt3000_detach, -}; - -static int __devinit driver_dt3000_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, &driver_dt3000); -} - -static void __devexit driver_dt3000_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver driver_dt3000_pci_driver = { - .id_table = dt3k_pci_table, - .probe = &driver_dt3000_pci_probe, - .remove = __devexit_p(&driver_dt3000_pci_remove) -}; - -static int __init driver_dt3000_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_dt3000); - if (retval < 0) - return retval; - - driver_dt3000_pci_driver.name = (char *)driver_dt3000.driver_name; - return pci_register_driver(&driver_dt3000_pci_driver); -} - -static void __exit driver_dt3000_cleanup_module(void) -{ - pci_unregister_driver(&driver_dt3000_pci_driver); - comedi_driver_unregister(&driver_dt3000); -} - -module_init(driver_dt3000_init_module); -module_exit(driver_dt3000_cleanup_module); - static void dt3k_ai_empty_fifo(struct comedi_device *dev, struct comedi_subdevice *s); static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *arg, @@ -841,7 +780,77 @@ static int dt3k_mem_insn_read(struct comedi_device *dev, return i; } -static int dt_pci_probe(struct comedi_device *dev, int bus, int slot); +static int setup_pci(struct comedi_device *dev) +{ + resource_size_t addr; + int ret; + + ret = comedi_pci_enable(devpriv->pci_dev, "dt3000"); + if (ret < 0) + return ret; + + addr = pci_resource_start(devpriv->pci_dev, 0); + devpriv->phys_addr = addr; + devpriv->io_addr = ioremap(devpriv->phys_addr, DT3000_SIZE); + if (!devpriv->io_addr) + return -ENOMEM; +#if DEBUG + printk("0x%08llx mapped to %p, ", + (unsigned long long)devpriv->phys_addr, devpriv->io_addr); +#endif + + return 0; +} + +static struct pci_dev *dt_pci_find_device(struct pci_dev *from, int *board) +{ + int i; + + for (from = pci_get_device(PCI_VENDOR_ID_DT, PCI_ANY_ID, from); + from != NULL; + from = pci_get_device(PCI_VENDOR_ID_DT, PCI_ANY_ID, from)) { + for (i = 0; i < n_dt3k_boards; i++) { + if (from->device == dt3k_boardtypes[i].device_id) { + *board = i; + return from; + } + } + printk + ("unknown Data Translation PCI device found with device_id=0x%04x\n", + from->device); + } + *board = -1; + return from; +} + +static int dt_pci_probe(struct comedi_device *dev, int bus, int slot) +{ + int board; + int ret; + struct pci_dev *pcidev; + + pcidev = NULL; + while ((pcidev = dt_pci_find_device(pcidev, &board)) != NULL) { + if ((bus == 0 && slot == 0) || + (pcidev->bus->number == bus && + PCI_SLOT(pcidev->devfn) == slot)) { + break; + } + } + devpriv->pci_dev = pcidev; + + if (board >= 0) + dev->board_ptr = dt3k_boardtypes + board; + + if (!devpriv->pci_dev) + return 0; + + ret = setup_pci(dev); + if (ret < 0) + return ret; + + return 1; +} static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -949,85 +958,65 @@ static int dt3000_detach(struct comedi_device *dev) if (devpriv->io_addr) iounmap(devpriv->io_addr); } - /* XXX */ return 0; } -static struct pci_dev *dt_pci_find_device(struct pci_dev *from, int *board); -static int setup_pci(struct comedi_device *dev); +static struct comedi_driver driver_dt3000 = { + .driver_name = "dt3000", + .module = THIS_MODULE, + .attach = dt3000_attach, + .detach = dt3000_detach, +}; -static int dt_pci_probe(struct comedi_device *dev, int bus, int slot) +static int __devinit driver_dt3000_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - int board; - int ret; - struct pci_dev *pcidev; - - pcidev = NULL; - while ((pcidev = dt_pci_find_device(pcidev, &board)) != NULL) { - if ((bus == 0 && slot == 0) || - (pcidev->bus->number == bus && - PCI_SLOT(pcidev->devfn) == slot)) { - break; - } - } - devpriv->pci_dev = pcidev; - - if (board >= 0) - dev->board_ptr = dt3k_boardtypes + board; + return comedi_pci_auto_config(dev, &driver_dt3000); +} - if (!devpriv->pci_dev) - return 0; +static void __devexit driver_dt3000_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} - ret = setup_pci(dev); - if (ret < 0) - return ret; +static DEFINE_PCI_DEVICE_TABLE(dt3k_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0022) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0027) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0023) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0024) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0028) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0025) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0026) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, dt3k_pci_table); - return 1; -} +static struct pci_driver driver_dt3000_pci_driver = { + .id_table = dt3k_pci_table, + .probe = driver_dt3000_pci_probe, + .remove = __devexit_p(driver_dt3000_pci_remove), +}; -static int setup_pci(struct comedi_device *dev) +static int __init driver_dt3000_init_module(void) { - resource_size_t addr; - int ret; - - ret = comedi_pci_enable(devpriv->pci_dev, "dt3000"); - if (ret < 0) - return ret; + int retval; - addr = pci_resource_start(devpriv->pci_dev, 0); - devpriv->phys_addr = addr; - devpriv->io_addr = ioremap(devpriv->phys_addr, DT3000_SIZE); - if (!devpriv->io_addr) - return -ENOMEM; -#if DEBUG - printk("0x%08llx mapped to %p, ", - (unsigned long long)devpriv->phys_addr, devpriv->io_addr); -#endif + retval = comedi_driver_register(&driver_dt3000); + if (retval < 0) + return retval; - return 0; + driver_dt3000_pci_driver.name = (char *)driver_dt3000.driver_name; + return pci_register_driver(&driver_dt3000_pci_driver); } +module_init(driver_dt3000_init_module); -static struct pci_dev *dt_pci_find_device(struct pci_dev *from, int *board) +static void __exit driver_dt3000_cleanup_module(void) { - int i; - - for (from = pci_get_device(PCI_VENDOR_ID_DT, PCI_ANY_ID, from); - from != NULL; - from = pci_get_device(PCI_VENDOR_ID_DT, PCI_ANY_ID, from)) { - for (i = 0; i < n_dt3k_boards; i++) { - if (from->device == dt3k_boardtypes[i].device_id) { - *board = i; - return from; - } - } - printk - ("unknown Data Translation PCI device found with device_id=0x%04x\n", - from->device); - } - *board = -1; - return from; + pci_unregister_driver(&driver_dt3000_pci_driver); + comedi_driver_unregister(&driver_dt3000); } +module_exit(driver_dt3000_cleanup_module); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); -- cgit v0.10.2 From e0eaa10d4d23e35a2bf6ac4b3dff81ae30b0d7e5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 4 May 2012 17:02:38 -0700 Subject: staging: comedi: refactor dt282x driver to remove forward declarations Move the struct comedi_driver and variables to the end of the source. This is more typical of how other drivers are written and removes the need for the forward declarations. Convert the driver to use the module_comedi_driver() macro which makes the code smaller and a bit simpler. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index 210b3f0..461a056 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -221,135 +221,6 @@ struct dt282x_board { int dabits; }; -static const struct dt282x_board boardtypes[] = { - {.name = "dt2821", - .adbits = 12, - .adchan_se = 16, - .adchan_di = 8, - .ai_speed = 20000, - .ispgl = 0, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt2821-f", - .adbits = 12, - .adchan_se = 16, - .adchan_di = 8, - .ai_speed = 6500, - .ispgl = 0, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt2821-g", - .adbits = 12, - .adchan_se = 16, - .adchan_di = 8, - .ai_speed = 4000, - .ispgl = 0, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt2823", - .adbits = 16, - .adchan_se = 0, - .adchan_di = 4, - .ai_speed = 10000, - .ispgl = 0, - .dachan = 2, - .dabits = 16, - }, - {.name = "dt2824-pgh", - .adbits = 12, - .adchan_se = 16, - .adchan_di = 8, - .ai_speed = 20000, - .ispgl = 0, - .dachan = 0, - .dabits = 0, - }, - {.name = "dt2824-pgl", - .adbits = 12, - .adchan_se = 16, - .adchan_di = 8, - .ai_speed = 20000, - .ispgl = 1, - .dachan = 0, - .dabits = 0, - }, - {.name = "dt2825", - .adbits = 12, - .adchan_se = 16, - .adchan_di = 8, - .ai_speed = 20000, - .ispgl = 1, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt2827", - .adbits = 16, - .adchan_se = 0, - .adchan_di = 4, - .ai_speed = 10000, - .ispgl = 0, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt2828", - .adbits = 12, - .adchan_se = 4, - .adchan_di = 0, - .ai_speed = 10000, - .ispgl = 0, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt2829", - .adbits = 16, - .adchan_se = 8, - .adchan_di = 0, - .ai_speed = 33250, - .ispgl = 0, - .dachan = 2, - .dabits = 16, - }, - {.name = "dt21-ez", - .adbits = 12, - .adchan_se = 16, - .adchan_di = 8, - .ai_speed = 10000, - .ispgl = 0, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt23-ez", - .adbits = 16, - .adchan_se = 16, - .adchan_di = 8, - .ai_speed = 10000, - .ispgl = 0, - .dachan = 0, - .dabits = 0, - }, - {.name = "dt24-ez", - .adbits = 12, - .adchan_se = 16, - .adchan_di = 8, - .ai_speed = 10000, - .ispgl = 0, - .dachan = 0, - .dabits = 0, - }, - {.name = "dt24-ez-pgl", - .adbits = 12, - .adchan_se = 16, - .adchan_di = 8, - .ai_speed = 10000, - .ispgl = 1, - .dachan = 0, - .dabits = 0, - }, -}; - #define this_board ((const struct dt282x_board *)dev->board_ptr) struct dt282x_private { @@ -410,33 +281,6 @@ struct dt282x_private { b \ } while (0) -static int dt282x_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int dt282x_detach(struct comedi_device *dev); -static struct comedi_driver driver_dt282x = { - .driver_name = "dt282x", - .module = THIS_MODULE, - .attach = dt282x_attach, - .detach = dt282x_detach, - .board_name = &boardtypes[0].name, - .num_names = ARRAY_SIZE(boardtypes), - .offset = sizeof(struct dt282x_board), -}; - -static int __init driver_dt282x_init_module(void) -{ - return comedi_driver_register(&driver_dt282x); -} - -static void __exit driver_dt282x_cleanup_module(void) -{ - comedi_driver_unregister(&driver_dt282x); -} - -module_init(driver_dt282x_init_module); -module_exit(driver_dt282x_cleanup_module); - -static void free_resources(struct comedi_device *dev); static int prep_ai_dma(struct comedi_device *dev, int chan, int size); static int prep_ao_dma(struct comedi_device *dev, int chan, int size); static int dt282x_ai_cancel(struct comedi_device *dev, @@ -1270,6 +1114,52 @@ enum { /* i/o base, irq, dma channels */ opt_ai_range, opt_ao0_range, opt_ao1_range, /* range */ }; +static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2) +{ + int ret; + + devpriv->usedma = 0; + + if (!dma1 && !dma2) { + printk(KERN_ERR " (no dma)"); + return 0; + } + + if (dma1 == dma2 || dma1 < 5 || dma2 < 5 || dma1 > 7 || dma2 > 7) + return -EINVAL; + + if (dma2 < dma1) { + int i; + i = dma1; + dma1 = dma2; + dma2 = i; + } + + ret = request_dma(dma1, "dt282x A"); + if (ret) + return -EBUSY; + devpriv->dma[0].chan = dma1; + + ret = request_dma(dma2, "dt282x B"); + if (ret) + return -EBUSY; + devpriv->dma[1].chan = dma2; + + devpriv->dma_maxsize = PAGE_SIZE; + devpriv->dma[0].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); + devpriv->dma[1].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); + if (!devpriv->dma[0].buf || !devpriv->dma[1].buf) { + printk(KERN_ERR " can't get DMA memory"); + return -ENOMEM; + } + + printk(KERN_INFO " (dma=%d,%d)", dma1, dma2); + + devpriv->usedma = 1; + + return 0; +} + /* options: 0 i/o base @@ -1468,51 +1358,146 @@ static int dt282x_detach(struct comedi_device *dev) return 0; } -static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2) -{ - int ret; - - devpriv->usedma = 0; - - if (!dma1 && !dma2) { - printk(KERN_ERR " (no dma)"); - return 0; - } - - if (dma1 == dma2 || dma1 < 5 || dma2 < 5 || dma1 > 7 || dma2 > 7) - return -EINVAL; - - if (dma2 < dma1) { - int i; - i = dma1; - dma1 = dma2; - dma2 = i; - } - - ret = request_dma(dma1, "dt282x A"); - if (ret) - return -EBUSY; - devpriv->dma[0].chan = dma1; - - ret = request_dma(dma2, "dt282x B"); - if (ret) - return -EBUSY; - devpriv->dma[1].chan = dma2; - - devpriv->dma_maxsize = PAGE_SIZE; - devpriv->dma[0].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); - devpriv->dma[1].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); - if (!devpriv->dma[0].buf || !devpriv->dma[1].buf) { - printk(KERN_ERR " can't get DMA memory"); - return -ENOMEM; - } - - printk(KERN_INFO " (dma=%d,%d)", dma1, dma2); - - devpriv->usedma = 1; +static const struct dt282x_board boardtypes[] = { + { + .name = "dt2821", + .adbits = 12, + .adchan_se = 16, + .adchan_di = 8, + .ai_speed = 20000, + .ispgl = 0, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt2821-f", + .adbits = 12, + .adchan_se = 16, + .adchan_di = 8, + .ai_speed = 6500, + .ispgl = 0, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt2821-g", + .adbits = 12, + .adchan_se = 16, + .adchan_di = 8, + .ai_speed = 4000, + .ispgl = 0, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt2823", + .adbits = 16, + .adchan_se = 0, + .adchan_di = 4, + .ai_speed = 10000, + .ispgl = 0, + .dachan = 2, + .dabits = 16, + }, { + .name = "dt2824-pgh", + .adbits = 12, + .adchan_se = 16, + .adchan_di = 8, + .ai_speed = 20000, + .ispgl = 0, + .dachan = 0, + .dabits = 0, + }, { + .name = "dt2824-pgl", + .adbits = 12, + .adchan_se = 16, + .adchan_di = 8, + .ai_speed = 20000, + .ispgl = 1, + .dachan = 0, + .dabits = 0, + }, { + .name = "dt2825", + .adbits = 12, + .adchan_se = 16, + .adchan_di = 8, + .ai_speed = 20000, + .ispgl = 1, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt2827", + .adbits = 16, + .adchan_se = 0, + .adchan_di = 4, + .ai_speed = 10000, + .ispgl = 0, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt2828", + .adbits = 12, + .adchan_se = 4, + .adchan_di = 0, + .ai_speed = 10000, + .ispgl = 0, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt2829", + .adbits = 16, + .adchan_se = 8, + .adchan_di = 0, + .ai_speed = 33250, + .ispgl = 0, + .dachan = 2, + .dabits = 16, + }, { + .name = "dt21-ez", + .adbits = 12, + .adchan_se = 16, + .adchan_di = 8, + .ai_speed = 10000, + .ispgl = 0, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt23-ez", + .adbits = 16, + .adchan_se = 16, + .adchan_di = 8, + .ai_speed = 10000, + .ispgl = 0, + .dachan = 0, + .dabits = 0, + }, { + .name = "dt24-ez", + .adbits = 12, + .adchan_se = 16, + .adchan_di = 8, + .ai_speed = 10000, + .ispgl = 0, + .dachan = 0, + .dabits = 0, + }, { + .name = "dt24-ez-pgl", + .adbits = 12, + .adchan_se = 16, + .adchan_di = 8, + .ai_speed = 10000, + .ispgl = 1, + .dachan = 0, + .dabits = 0, + }, +}; - return 0; -} +static struct comedi_driver dt282x_driver = { + .driver_name = "dt282x", + .module = THIS_MODULE, + .attach = dt282x_attach, + .detach = dt282x_detach, + .board_name = &boardtypes[0].name, + .num_names = ARRAY_SIZE(boardtypes), + .offset = sizeof(struct dt282x_board), +}; +module_comedi_driver(dt282x_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); -- cgit v0.10.2 From 7806012e97edf47e87eb42058878d8e574f7461f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 4 May 2012 17:09:02 -0700 Subject: staging: comedi: refactor dt2814 driver and use module_comedi_driver Move the struct comedi_driver to the end of the source and refactor the code to remove the forward declarations. Convert the driver to use the module_comedi_driver() macro which makes the code smaller and a bit simpler. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c index 1c6248c..a935e9c 100644 --- a/drivers/staging/comedi/drivers/dt2814.c +++ b/drivers/staging/comedi/drivers/dt2814.c @@ -60,31 +60,6 @@ addition, the clock does not seem to be very accurate. #define DT2814_ENB 0x10 #define DT2814_CHANMASK 0x0f -static int dt2814_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int dt2814_detach(struct comedi_device *dev); -static struct comedi_driver driver_dt2814 = { - .driver_name = "dt2814", - .module = THIS_MODULE, - .attach = dt2814_attach, - .detach = dt2814_detach, -}; - -static int __init driver_dt2814_init_module(void) -{ - return comedi_driver_register(&driver_dt2814); -} - -static void __exit driver_dt2814_cleanup_module(void) -{ - comedi_driver_unregister(&driver_dt2814); -} - -module_init(driver_dt2814_init_module); -module_exit(driver_dt2814_cleanup_module); - -static irqreturn_t dt2814_interrupt(int irq, void *dev); - struct dt2814_private { int ntrig; @@ -260,6 +235,45 @@ static int dt2814_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) } +static irqreturn_t dt2814_interrupt(int irq, void *d) +{ + int lo, hi; + struct comedi_device *dev = d; + struct comedi_subdevice *s; + int data; + + if (!dev->attached) { + comedi_error(dev, "spurious interrupt"); + return IRQ_HANDLED; + } + + s = dev->subdevices + 0; + + hi = inb(dev->iobase + DT2814_DATA); + lo = inb(dev->iobase + DT2814_DATA); + + data = (hi << 4) | (lo >> 4); + + if (!(--devpriv->ntrig)) { + int i; + + outb(0, dev->iobase + DT2814_CSR); + /* note: turning off timed mode triggers another + sample. */ + + for (i = 0; i < DT2814_TIMEOUT; i++) { + if (inb(dev->iobase + DT2814_CSR) & DT2814_FINISH) + break; + } + inb(dev->iobase + DT2814_DATA); + inb(dev->iobase + DT2814_DATA); + + s->async->events |= COMEDI_CB_EOA; + } + comedi_event(dev, s); + return IRQ_HANDLED; +} + static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) { int i, irq; @@ -360,44 +374,13 @@ static int dt2814_detach(struct comedi_device *dev) return 0; } -static irqreturn_t dt2814_interrupt(int irq, void *d) -{ - int lo, hi; - struct comedi_device *dev = d; - struct comedi_subdevice *s; - int data; - - if (!dev->attached) { - comedi_error(dev, "spurious interrupt"); - return IRQ_HANDLED; - } - - s = dev->subdevices + 0; - - hi = inb(dev->iobase + DT2814_DATA); - lo = inb(dev->iobase + DT2814_DATA); - - data = (hi << 4) | (lo >> 4); - - if (!(--devpriv->ntrig)) { - int i; - - outb(0, dev->iobase + DT2814_CSR); - /* note: turning off timed mode triggers another - sample. */ - - for (i = 0; i < DT2814_TIMEOUT; i++) { - if (inb(dev->iobase + DT2814_CSR) & DT2814_FINISH) - break; - } - inb(dev->iobase + DT2814_DATA); - inb(dev->iobase + DT2814_DATA); - - s->async->events |= COMEDI_CB_EOA; - } - comedi_event(dev, s); - return IRQ_HANDLED; -} +static struct comedi_driver dt2814_driver = { + .driver_name = "dt2814", + .module = THIS_MODULE, + .attach = dt2814_attach, + .detach = dt2814_detach, +}; +module_comedi_driver(dt2814_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); -- cgit v0.10.2 From a19fb006c4d37b321712268b3937079973c730d6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 7 May 2012 12:14:22 -0700 Subject: staging: comedi: rename addi CamelCase function pointers Rename the CamelCase variable names for the ADDI subdevice functions. This makes the code a bit cleaner and easier to follow. This will also help with converting the struct addi_board boardtypes array to C99 style initialization to help with maintaining the code. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 5b5dae4..49d11ef 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -2819,16 +2819,13 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Set the initialisation flag */ devpriv->b_AiInitialisation = 1; - s->insn_config = - this_board->i_hwdrv_InsnConfigAnalogInput; - s->insn_read = this_board->i_hwdrv_InsnReadAnalogInput; - s->insn_write = - this_board->i_hwdrv_InsnWriteAnalogInput; - s->insn_bits = this_board->i_hwdrv_InsnBitsAnalogInput; - s->do_cmdtest = - this_board->i_hwdrv_CommandTestAnalogInput; - s->do_cmd = this_board->i_hwdrv_CommandAnalogInput; - s->cancel = this_board->i_hwdrv_CancelAnalogInput; + s->insn_config = this_board->ai_config; + s->insn_read = this_board->ai_read; + s->insn_write = this_board->ai_write; + s->insn_bits = this_board->ai_bits; + s->do_cmdtest = this_board->ai_cmdtest; + s->do_cmd = this_board->ai_cmd; + s->cancel = this_board->ai_cancel; } else { s->type = COMEDI_SUBD_UNUSED; @@ -2844,10 +2841,8 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) s->len_chanlist = devpriv->s_EeParameters.i_NbrAoChannel; s->range_table = this_board->pr_AoRangelist; - s->insn_config = - this_board->i_hwdrv_InsnConfigAnalogOutput; - s->insn_write = - this_board->i_hwdrv_InsnWriteAnalogOutput; + s->insn_config = this_board->ao_config; + s->insn_write = this_board->ao_write; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -2862,12 +2857,10 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->s_EeParameters.i_NbrDiChannel; s->range_table = &range_digital; s->io_bits = 0; /* all bits input */ - s->insn_config = - this_board->i_hwdrv_InsnConfigDigitalInput; - s->insn_read = this_board->i_hwdrv_InsnReadDigitalInput; - s->insn_write = - this_board->i_hwdrv_InsnWriteDigitalInput; - s->insn_bits = this_board->i_hwdrv_InsnBitsDigitalInput; + s->insn_config = this_board->di_config; + s->insn_read = this_board->di_read; + s->insn_write = this_board->di_write; + s->insn_bits = this_board->di_bits; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -2884,13 +2877,11 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) s->range_table = &range_digital; s->io_bits = 0xf; /* all bits output */ - s->insn_config = this_board->i_hwdrv_InsnConfigDigitalOutput; /* for digital output memory.. */ - s->insn_write = - this_board->i_hwdrv_InsnWriteDigitalOutput; - s->insn_bits = - this_board->i_hwdrv_InsnBitsDigitalOutput; - s->insn_read = - this_board->i_hwdrv_InsnReadDigitalOutput; + /* insn_config - for digital output memory */ + s->insn_config = this_board->do_config; + s->insn_write = this_board->do_write; + s->insn_bits = this_board->do_bits; + s->insn_read = this_board->do_read; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -2905,10 +2896,10 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) s->len_chanlist = 1; s->range_table = &range_digital; - s->insn_write = this_board->i_hwdrv_InsnWriteTimer; - s->insn_read = this_board->i_hwdrv_InsnReadTimer; - s->insn_config = this_board->i_hwdrv_InsnConfigTimer; - s->insn_bits = this_board->i_hwdrv_InsnBitsTimer; + s->insn_write = this_board->timer_write; + s->insn_read = this_board->timer_read; + s->insn_config = this_board->timer_config; + s->insn_bits = this_board->timer_bits; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -2924,10 +2915,10 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) s->io_bits = 0; /* all bits input */ s->len_chanlist = this_board->i_NbrTTLChannel; s->range_table = &range_digital; - s->insn_config = this_board->i_hwdr_ConfigInitTTLIO; - s->insn_bits = this_board->i_hwdr_ReadTTLIOBits; - s->insn_read = this_board->i_hwdr_ReadTTLIOAllPortValue; - s->insn_write = this_board->i_hwdr_WriteTTLIOChlOnOff; + s->insn_config = this_board->ttl_config; + s->insn_bits = this_board->ttl_bits; + s->insn_read = this_board->ttl_read; + s->insn_write = this_board->ttl_write; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -3039,7 +3030,7 @@ static int i_ADDI_Detach(struct comedi_device *dev) static int i_ADDI_Reset(struct comedi_device *dev) { - this_board->i_hwdrv_Reset(dev); + this_board->reset(dev); return 0; } @@ -3065,7 +3056,7 @@ static int i_ADDI_Reset(struct comedi_device *dev) static irqreturn_t v_ADDI_Interrupt(int irq, void *d) { struct comedi_device *dev = d; - this_board->v_hwdrv_Interrupt(irq, d); + this_board->interrupt(irq, d); return IRQ_RETVAL(1); } diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h index c6980b7..0a153fe 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h @@ -94,111 +94,72 @@ struct addi_board { unsigned int ui_MinDelaytimeNs; /* Minimum Delay in Nano secs */ /* interrupt and reset */ - void (*v_hwdrv_Interrupt)(int irq, void *d); - int (*i_hwdrv_Reset)(struct comedi_device *dev); + void (*interrupt)(int irq, void *d); + int (*reset)(struct comedi_device *); /* Subdevice functions */ /* ANALOG INPUT */ - int (*i_hwdrv_InsnConfigAnalogInput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnReadAnalogInput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnWriteAnalogInput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnBitsAnalogInput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_CommandTestAnalogInput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd); - int (*i_hwdrv_CommandAnalogInput)(struct comedi_device *dev, - struct comedi_subdevice *s); - int (*i_hwdrv_CancelAnalogInput)(struct comedi_device *dev, - struct comedi_subdevice *s); + int (*ai_config)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*ai_read)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*ai_write)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*ai_bits)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*ai_cmdtest)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_cmd *); + int (*ai_cmd)(struct comedi_device *, struct comedi_subdevice *); + int (*ai_cancel)(struct comedi_device *, struct comedi_subdevice *); /* Analog Output */ - int (*i_hwdrv_InsnConfigAnalogOutput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnWriteAnalogOutput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnBitsAnalogOutput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); + int (*ao_config)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*ao_write)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*ao_bits)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); /* Digital Input */ - int (*i_hwdrv_InsnConfigDigitalInput) (struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnReadDigitalInput) (struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnWriteDigitalInput) (struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnBitsDigitalInput) (struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); + int (*di_config)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*di_read)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*di_write)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*di_bits)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); /* Digital Output */ - int (*i_hwdrv_InsnConfigDigitalOutput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnWriteDigitalOutput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnBitsDigitalOutput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnReadDigitalOutput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); + int (*do_config)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*do_write)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*do_bits)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*do_read)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); /* TIMER */ - int (*i_hwdrv_InsnConfigTimer)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - int (*i_hwdrv_InsnWriteTimer)(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnReadTimer)(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - int (*i_hwdrv_InsnBitsTimer)(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); + int (*timer_config)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*timer_write)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*timer_read)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*timer_bits)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); /* TTL IO */ - int (*i_hwdr_ConfigInitTTLIO)(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdr_ReadTTLIOBits)(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - int (*i_hwdr_ReadTTLIOAllPortValue)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdr_WriteTTLIOChlOnOff)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); + int (*ttl_config)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*ttl_bits)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*ttl_read)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*ttl_write)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); }; /* MODULE INFO STRUCTURE */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index e886ced..ffe390c 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -156,7 +156,7 @@ int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subd } else us_ConvertTiming = (unsigned short) (devpriv->ui_EocEosConversionTime / 1000); /* nano to useconds */ - /* this_board->i_hwdrv_InsnReadAnalogInput(dev,us_ConvertTiming,insn->n,&insn->chanspec,data,insn->unused[0]); */ + /* this_board->ai_read(dev,us_ConvertTiming,insn->n,&insn->chanspec,data,insn->unused[0]); */ /* Clear software registers */ devpriv->b_TimerSelectMode = 0; @@ -670,7 +670,7 @@ int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subde /* mode 1 */ devpriv->ui_AiTimer0 = cmd->convert_arg; /* timer constant in nano seconds */ - /* return this_board->i_hwdrv_CommandAnalogInput(1,dev,s); */ + /* return this_board->ai_cmd(1,dev,s); */ return i_APCI3120_CyclicAnalogInput(1, dev, s); } @@ -680,7 +680,7 @@ int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subde /* mode 2 */ devpriv->ui_AiTimer1 = cmd->scan_begin_arg; devpriv->ui_AiTimer0 = cmd->convert_arg; /* variable changed timer2 to timer0 */ - /* return this_board->i_hwdrv_CommandAnalogInput(2,dev,s); */ + /* return this_board->ai_cmd(2,dev,s); */ return i_APCI3120_CyclicAnalogInput(2, dev, s); } return -1; @@ -1922,7 +1922,7 @@ int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevic ui_Timervalue2 = data[1] / 1000; /* convert nano seconds to u seconds */ - /* this_board->i_hwdrv_InsnConfigTimer(dev, ui_Timervalue2,(unsigned char)data[0]); */ + /* this_board->timer_config(dev, ui_Timervalue2,(unsigned char)data[0]); */ us_TmpValue = (unsigned short) inw(devpriv->iobase + APCI3120_RD_STATUS); /* @@ -2092,7 +2092,7 @@ int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice ui_Timervalue2 = 0; } - /* this_board->i_hwdrv_InsnWriteTimer(dev,data[0],ui_Timervalue2); */ + /* this_board->timer_write(dev,data[0],ui_Timervalue2); */ switch (data[0]) { case APCI3120_START: @@ -2260,7 +2260,7 @@ int i_APCI3120_InsnReadTimer(struct comedi_device *dev, struct comedi_subdevice comedi_error(dev, "\nread:timer2 not configured "); } - /* this_board->i_hwdrv_InsnReadTimer(dev,data); */ + /* this_board->timer_read(dev,data); */ if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* Read the LOW unsigned short of Timer 2 register */ @@ -2331,7 +2331,7 @@ int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev, ui_Chan = CR_CHAN(insn->chanspec); /* channel specified */ - /* this_board->i_hwdrv_InsnReadDigitalInput(dev,ui_Chan,data); */ + /* this_board->di_read(dev,ui_Chan,data); */ if (ui_Chan <= 3) { ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI3120_RD_STATUS); @@ -2379,7 +2379,7 @@ int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, struct comedi_sub *****/ *data = (ui_TmpValue >> 8) & 0xf; - /* this_board->i_hwdrv_InsnBitsDigitalInput(dev,data); */ + /* this_board->di_bits(dev,data); */ return insn->n; } @@ -2595,7 +2595,7 @@ int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev, ui_Range = CR_RANGE(insn->chanspec); ui_Channel = CR_CHAN(insn->chanspec); - /* this_board->i_hwdrv_InsnWriteAnalogOutput(dev, ui_Range, ui_Channel,data[0]); */ + /* this_board->ao_write(dev, ui_Range, ui_Channel,data[0]); */ if (ui_Range) { /* if 1 then unipolar */ if (data[0] != 0) -- cgit v0.10.2 From 2b7a521b121ebc16b9137f07ded7874105c9486a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 8 May 2012 16:19:34 -0700 Subject: staging: comedi: mite: mite_io_addr and daq_io_addr are void __iomem * The mite_io_addr and daq_io_addr variables in struct mite_struct are both ioremap'ed pci resources and should be void __iomem * not void *. This quiets a lot of sparse warings for the write[lwb],read[lwb] calls in the comedi mite drives like: warning: incorrect type in argument 1 (different address spaces) expected void const volatile [noderef] *addr got void * warning: incorrect type in argument 2 (different address spaces) expected void volatile [noderef] *addr got void * It also exposed some warnings in the mite ni_660x driver where the daq_io_address was getting cast as a void *const. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h index 999551f..83f1b27 100644 --- a/drivers/staging/comedi/drivers/mite.h +++ b/drivers/staging/comedi/drivers/mite.h @@ -66,9 +66,9 @@ struct mite_struct { struct pci_dev *pcidev; resource_size_t mite_phys_addr; - void *mite_io_addr; + void __iomem *mite_io_addr; resource_size_t daq_phys_addr; - void *daq_io_addr; + void __iomem *daq_io_addr; struct mite_channel channels[MAX_MITE_DMA_CHANNELS]; short channel_allocated[MAX_MITE_DMA_CHANNELS]; diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index eea7047..21eb7fb 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -761,7 +761,7 @@ static inline void ni_660x_write_register(struct comedi_device *dev, unsigned chip_index, unsigned bits, enum NI_660x_Register reg) { - void *const write_address = + void __iomem *write_address = private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] + registerData[reg].offset; @@ -784,7 +784,7 @@ static inline unsigned ni_660x_read_register(struct comedi_device *dev, unsigned chip_index, enum NI_660x_Register reg) { - void *const read_address = + void __iomem *read_address = private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] + registerData[reg].offset; -- cgit v0.10.2 From 54fe68a8d7e6f3f3f24150ef555b05dcc2fa0461 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 8 May 2012 16:27:55 -0700 Subject: staging: comedi: rtf520: las0, las1, and lcfg are void __iomem * MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The las0, las1, and lcfg variables in struct rtdPrivate are all ioremap'ed pci resources and should be void __iomem * not void *. This quiets a lot of sparse warings for the writel and readl like: warning: incorrect type in argument 1 (different address spaces)    expected void const volatile [noderef] *addr    got void * warning: incorrect type in argument 2 (different address spaces)    expected void volatile [noderef] *addr    got void * Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 0c15b82..0e62bae 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -339,9 +339,9 @@ static const struct rtdBoard rtd520Boards[] = { */ struct rtdPrivate { /* memory mapped board structures */ - void *las0; - void *las1; - void *lcfg; + void __iomem *las0; + void __iomem *las1; + void __iomem *lcfg; unsigned long intCount; /* interrupt count */ long aiCount; /* total transfer size (samples) */ -- cgit v0.10.2 From a5011a261574239403468368605f5e0625dcfb56 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 9 May 2012 09:20:08 -0700 Subject: staging: comedi: refactor sysfs files in comedi_fops.c Refactor the sysfs attributes and functions to remove the need for the forward declarations and use the DEVICE_ATTR macro to define them. Instead of individually creating sysfs device attribute files, wrap them in an attribute_group and use the sysfs_create_group function to create them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 06fc656..44ca1fe 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -129,15 +129,295 @@ static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s); static int comedi_fasync(int fd, struct file *file, int on); static int is_device_busy(struct comedi_device *dev); + static int resize_async_buffer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_async *async, unsigned new_size); + struct comedi_async *async, unsigned new_size) +{ + int retval; + + if (new_size > async->max_bufsize) + return -EPERM; + + if (s->busy) { + DPRINTK("subdevice is busy, cannot resize buffer\n"); + return -EBUSY; + } + if (async->mmap_count) { + DPRINTK("subdevice is mmapped, cannot resize buffer\n"); + return -EBUSY; + } + + if (!async->prealloc_buf) + return -EINVAL; + + /* make sure buffer is an integral number of pages + * (we round up) */ + new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK; + + retval = comedi_buf_alloc(dev, s, new_size); + if (retval < 0) + return retval; + + if (s->buf_change) { + retval = s->buf_change(dev, s, new_size); + if (retval < 0) + return retval; + } + + DPRINTK("comedi%i subd %d buffer resized to %i bytes\n", + dev->minor, (int)(s - dev->subdevices), async->prealloc_bufsz); + return 0; +} + +/* sysfs attribute files */ + +static const unsigned bytes_per_kibi = 1024; + +static ssize_t show_max_read_buffer_kb(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t retval; + struct comedi_device_file_info *info = dev_get_drvdata(dev); + unsigned max_buffer_size_kb = 0; + struct comedi_subdevice *const read_subdevice = + comedi_get_read_subdevice(info); + + mutex_lock(&info->device->mutex); + if (read_subdevice && + (read_subdevice->subdev_flags & SDF_CMD_READ) && + read_subdevice->async) { + max_buffer_size_kb = read_subdevice->async->max_bufsize / + bytes_per_kibi; + } + retval = snprintf(buf, PAGE_SIZE, "%i\n", max_buffer_size_kb); + mutex_unlock(&info->device->mutex); + + return retval; +} + +static ssize_t store_max_read_buffer_kb(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct comedi_device_file_info *info = dev_get_drvdata(dev); + unsigned int new_max_size_kb; + unsigned int new_max_size; + int ret; + struct comedi_subdevice *const read_subdevice = + comedi_get_read_subdevice(info); + + ret = kstrtouint(buf, 10, &new_max_size_kb); + if (ret) + return ret; + if (new_max_size_kb > (UINT_MAX / bytes_per_kibi)) + return -EINVAL; + new_max_size = new_max_size_kb * bytes_per_kibi; + + mutex_lock(&info->device->mutex); + if (read_subdevice == NULL || + (read_subdevice->subdev_flags & SDF_CMD_READ) == 0 || + read_subdevice->async == NULL) { + mutex_unlock(&info->device->mutex); + return -EINVAL; + } + read_subdevice->async->max_bufsize = new_max_size; + mutex_unlock(&info->device->mutex); + + return count; +} + +static DEVICE_ATTR(max_read_buffer_kb, S_IRUGO | S_IWUSR, + show_max_read_buffer_kb, store_max_read_buffer_kb); + +static ssize_t show_read_buffer_kb(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t retval; + struct comedi_device_file_info *info = dev_get_drvdata(dev); + unsigned buffer_size_kb = 0; + struct comedi_subdevice *const read_subdevice = + comedi_get_read_subdevice(info); + + mutex_lock(&info->device->mutex); + if (read_subdevice && + (read_subdevice->subdev_flags & SDF_CMD_READ) && + read_subdevice->async) { + buffer_size_kb = read_subdevice->async->prealloc_bufsz / + bytes_per_kibi; + } + retval = snprintf(buf, PAGE_SIZE, "%i\n", buffer_size_kb); + mutex_unlock(&info->device->mutex); + + return retval; +} + +static ssize_t store_read_buffer_kb(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct comedi_device_file_info *info = dev_get_drvdata(dev); + unsigned int new_size_kb; + unsigned int new_size; + int retval; + int ret; + struct comedi_subdevice *const read_subdevice = + comedi_get_read_subdevice(info); + + ret = kstrtouint(buf, 10, &new_size_kb); + if (ret) + return ret; + if (new_size_kb > (UINT_MAX / bytes_per_kibi)) + return -EINVAL; + new_size = new_size_kb * bytes_per_kibi; + + mutex_lock(&info->device->mutex); + if (read_subdevice == NULL || + (read_subdevice->subdev_flags & SDF_CMD_READ) == 0 || + read_subdevice->async == NULL) { + mutex_unlock(&info->device->mutex); + return -EINVAL; + } + retval = resize_async_buffer(info->device, read_subdevice, + read_subdevice->async, new_size); + mutex_unlock(&info->device->mutex); + + if (retval < 0) + return retval; + return count; +} -/* declarations for sysfs attribute files */ -static struct device_attribute dev_attr_max_read_buffer_kb; -static struct device_attribute dev_attr_read_buffer_kb; -static struct device_attribute dev_attr_max_write_buffer_kb; -static struct device_attribute dev_attr_write_buffer_kb; +static DEVICE_ATTR(read_buffer_kb, S_IRUGO | S_IWUSR | S_IWGRP, + show_read_buffer_kb, store_read_buffer_kb); + +static ssize_t show_max_write_buffer_kb(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t retval; + struct comedi_device_file_info *info = dev_get_drvdata(dev); + unsigned max_buffer_size_kb = 0; + struct comedi_subdevice *const write_subdevice = + comedi_get_write_subdevice(info); + + mutex_lock(&info->device->mutex); + if (write_subdevice && + (write_subdevice->subdev_flags & SDF_CMD_WRITE) && + write_subdevice->async) { + max_buffer_size_kb = write_subdevice->async->max_bufsize / + bytes_per_kibi; + } + retval = snprintf(buf, PAGE_SIZE, "%i\n", max_buffer_size_kb); + mutex_unlock(&info->device->mutex); + + return retval; +} + +static ssize_t store_max_write_buffer_kb(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct comedi_device_file_info *info = dev_get_drvdata(dev); + unsigned int new_max_size_kb; + unsigned int new_max_size; + int ret; + struct comedi_subdevice *const write_subdevice = + comedi_get_write_subdevice(info); + + ret = kstrtouint(buf, 10, &new_max_size_kb); + if (ret) + return ret; + if (new_max_size_kb > (UINT_MAX / bytes_per_kibi)) + return -EINVAL; + new_max_size = new_max_size_kb * bytes_per_kibi; + + mutex_lock(&info->device->mutex); + if (write_subdevice == NULL || + (write_subdevice->subdev_flags & SDF_CMD_WRITE) == 0 || + write_subdevice->async == NULL) { + mutex_unlock(&info->device->mutex); + return -EINVAL; + } + write_subdevice->async->max_bufsize = new_max_size; + mutex_unlock(&info->device->mutex); + + return count; +} + +static DEVICE_ATTR(max_write_buffer_kb, S_IRUGO | S_IWUSR, + show_max_write_buffer_kb, store_max_write_buffer_kb); + +static ssize_t show_write_buffer_kb(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t retval; + struct comedi_device_file_info *info = dev_get_drvdata(dev); + unsigned buffer_size_kb = 0; + struct comedi_subdevice *const write_subdevice = + comedi_get_write_subdevice(info); + + mutex_lock(&info->device->mutex); + if (write_subdevice && + (write_subdevice->subdev_flags & SDF_CMD_WRITE) && + write_subdevice->async) { + buffer_size_kb = write_subdevice->async->prealloc_bufsz / + bytes_per_kibi; + } + retval = snprintf(buf, PAGE_SIZE, "%i\n", buffer_size_kb); + mutex_unlock(&info->device->mutex); + + return retval; +} + +static ssize_t store_write_buffer_kb(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct comedi_device_file_info *info = dev_get_drvdata(dev); + unsigned int new_size_kb; + unsigned int new_size; + int retval; + int ret; + struct comedi_subdevice *const write_subdevice = + comedi_get_write_subdevice(info); + + ret = kstrtouint(buf, 10, &new_size_kb); + if (ret) + return ret; + if (new_size_kb > (UINT_MAX / bytes_per_kibi)) + return -EINVAL; + new_size = ((uint64_t) new_size_kb) * bytes_per_kibi; + + mutex_lock(&info->device->mutex); + if (write_subdevice == NULL || + (write_subdevice->subdev_flags & SDF_CMD_WRITE) == 0 || + write_subdevice->async == NULL) { + mutex_unlock(&info->device->mutex); + return -EINVAL; + } + retval = resize_async_buffer(info->device, write_subdevice, + write_subdevice->async, new_size); + mutex_unlock(&info->device->mutex); + + if (retval < 0) + return retval; + return count; +} + +static DEVICE_ATTR(write_buffer_kb, S_IRUGO | S_IWUSR | S_IWGRP, + show_write_buffer_kb, store_write_buffer_kb); + +static struct attribute *comedi_attrs[] = { + &dev_attr_max_read_buffer_kb.attr, + &dev_attr_read_buffer_kb.attr, + &dev_attr_max_write_buffer_kb.attr, + &dev_attr_write_buffer_kb.attr, + NULL +}; + +static const struct attribute_group comedi_sysfs_files = { + .attrs = comedi_attrs, +}; static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) @@ -1937,804 +2217,453 @@ ok: dev->use_count++; - mutex_unlock(&dev->mutex); - - return 0; -} - -static int comedi_close(struct inode *inode, struct file *file) -{ - const unsigned minor = iminor(inode); - struct comedi_subdevice *s = NULL; - int i; - struct comedi_device_file_info *dev_file_info; - struct comedi_device *dev; - dev_file_info = comedi_get_device_file_info(minor); - - if (dev_file_info == NULL) - return -ENODEV; - dev = dev_file_info->device; - if (dev == NULL) - return -ENODEV; - - mutex_lock(&dev->mutex); - - if (dev->subdevices) { - for (i = 0; i < dev->n_subdevices; i++) { - s = dev->subdevices + i; - - if (s->busy == file) - do_cancel(dev, s); - if (s->lock == file) - s->lock = NULL; - } - } - if (dev->attached && dev->use_count == 1 && dev->close) - dev->close(dev); - - module_put(THIS_MODULE); - if (dev->attached) - module_put(dev->driver->module); - - dev->use_count--; - - mutex_unlock(&dev->mutex); - - if (file->f_flags & FASYNC) - comedi_fasync(-1, file, 0); - - return 0; -} - -static int comedi_fasync(int fd, struct file *file, int on) -{ - const unsigned minor = iminor(file->f_dentry->d_inode); - struct comedi_device_file_info *dev_file_info; - struct comedi_device *dev; - dev_file_info = comedi_get_device_file_info(minor); - - if (dev_file_info == NULL) - return -ENODEV; - dev = dev_file_info->device; - if (dev == NULL) - return -ENODEV; - - return fasync_helper(fd, file, on, &dev->async_queue); -} - -const struct file_operations comedi_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = comedi_unlocked_ioctl, - .compat_ioctl = comedi_compat_ioctl, - .open = comedi_open, - .release = comedi_close, - .read = comedi_read, - .write = comedi_write, - .mmap = comedi_mmap, - .poll = comedi_poll, - .fasync = comedi_fasync, - .llseek = noop_llseek, -}; - -struct class *comedi_class; -static struct cdev comedi_cdev; - -static void comedi_cleanup_legacy_minors(void) -{ - unsigned i; - - for (i = 0; i < comedi_num_legacy_minors; i++) - comedi_free_board_minor(i); -} - -static int __init comedi_init(void) -{ - int i; - int retval; - - printk(KERN_INFO "comedi: version " COMEDI_RELEASE - " - http://www.comedi.org\n"); - - if (comedi_num_legacy_minors < 0 || - comedi_num_legacy_minors > COMEDI_NUM_BOARD_MINORS) { - printk(KERN_ERR "comedi: error: invalid value for module " - "parameter \"comedi_num_legacy_minors\". Valid values " - "are 0 through %i.\n", COMEDI_NUM_BOARD_MINORS); - return -EINVAL; - } - - /* - * comedi is unusable if both comedi_autoconfig and - * comedi_num_legacy_minors are zero, so we might as well adjust the - * defaults in that case - */ - if (comedi_autoconfig == 0 && comedi_num_legacy_minors == 0) - comedi_num_legacy_minors = 16; - - memset(comedi_file_info_table, 0, - sizeof(struct comedi_device_file_info *) * COMEDI_NUM_MINORS); - - retval = register_chrdev_region(MKDEV(COMEDI_MAJOR, 0), - COMEDI_NUM_MINORS, "comedi"); - if (retval) - return -EIO; - cdev_init(&comedi_cdev, &comedi_fops); - comedi_cdev.owner = THIS_MODULE; - kobject_set_name(&comedi_cdev.kobj, "comedi"); - if (cdev_add(&comedi_cdev, MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS)) { - unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), - COMEDI_NUM_MINORS); - return -EIO; - } - comedi_class = class_create(THIS_MODULE, "comedi"); - if (IS_ERR(comedi_class)) { - printk(KERN_ERR "comedi: failed to create class"); - cdev_del(&comedi_cdev); - unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), - COMEDI_NUM_MINORS); - return PTR_ERR(comedi_class); - } - - /* XXX requires /proc interface */ - comedi_proc_init(); - - /* create devices files for legacy/manual use */ - for (i = 0; i < comedi_num_legacy_minors; i++) { - int minor; - minor = comedi_alloc_board_minor(NULL); - if (minor < 0) { - comedi_cleanup_legacy_minors(); - cdev_del(&comedi_cdev); - unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), - COMEDI_NUM_MINORS); - return minor; - } - } - - return 0; -} - -static void __exit comedi_cleanup(void) -{ - int i; - - comedi_cleanup_legacy_minors(); - for (i = 0; i < COMEDI_NUM_MINORS; ++i) - BUG_ON(comedi_file_info_table[i]); - - class_destroy(comedi_class); - cdev_del(&comedi_cdev); - unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS); - - comedi_proc_cleanup(); -} - -module_init(comedi_init); -module_exit(comedi_cleanup); - -void comedi_error(const struct comedi_device *dev, const char *s) -{ - printk(KERN_ERR "comedi%d: %s: %s\n", dev->minor, - dev->driver->driver_name, s); -} -EXPORT_SYMBOL(comedi_error); - -void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) -{ - struct comedi_async *async = s->async; - unsigned runflags = 0; - unsigned runflags_mask = 0; - - /* DPRINTK("comedi_event 0x%x\n",mask); */ - - if ((comedi_get_subdevice_runflags(s) & SRF_RUNNING) == 0) - return; - - if (s-> - async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | - COMEDI_CB_OVERFLOW)) { - runflags_mask |= SRF_RUNNING; - } - /* remember if an error event has occurred, so an error - * can be returned the next time the user does a read() */ - if (s->async->events & (COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) { - runflags_mask |= SRF_ERROR; - runflags |= SRF_ERROR; - } - if (runflags_mask) { - /*sets SRF_ERROR and SRF_RUNNING together atomically */ - comedi_set_subdevice_runflags(s, runflags_mask, runflags); - } - - if (async->cb_mask & s->async->events) { - if (comedi_get_subdevice_runflags(s) & SRF_USER) { - wake_up_interruptible(&async->wait_head); - if (s->subdev_flags & SDF_CMD_READ) - kill_fasync(&dev->async_queue, SIGIO, POLL_IN); - if (s->subdev_flags & SDF_CMD_WRITE) - kill_fasync(&dev->async_queue, SIGIO, POLL_OUT); - } else { - if (async->cb_func) - async->cb_func(s->async->events, async->cb_arg); - } - } - s->async->events = 0; -} -EXPORT_SYMBOL(comedi_event); - -unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s) -{ - unsigned long flags; - unsigned runflags; + mutex_unlock(&dev->mutex); - spin_lock_irqsave(&s->spin_lock, flags); - runflags = s->runflags; - spin_unlock_irqrestore(&s->spin_lock, flags); - return runflags; + return 0; } -EXPORT_SYMBOL(comedi_get_subdevice_runflags); -static int is_device_busy(struct comedi_device *dev) +static int comedi_close(struct inode *inode, struct file *file) { - struct comedi_subdevice *s; + const unsigned minor = iminor(inode); + struct comedi_subdevice *s = NULL; int i; + struct comedi_device_file_info *dev_file_info; + struct comedi_device *dev; + dev_file_info = comedi_get_device_file_info(minor); - if (!dev->attached) - return 0; + if (dev_file_info == NULL) + return -ENODEV; + dev = dev_file_info->device; + if (dev == NULL) + return -ENODEV; - for (i = 0; i < dev->n_subdevices; i++) { - s = dev->subdevices + i; - if (s->busy) - return 1; - if (s->async && s->async->mmap_count) - return 1; + mutex_lock(&dev->mutex); + + if (dev->subdevices) { + for (i = 0; i < dev->n_subdevices; i++) { + s = dev->subdevices + i; + + if (s->busy == file) + do_cancel(dev, s); + if (s->lock == file) + s->lock = NULL; + } } + if (dev->attached && dev->use_count == 1 && dev->close) + dev->close(dev); + + module_put(THIS_MODULE); + if (dev->attached) + module_put(dev->driver->module); + + dev->use_count--; + + mutex_unlock(&dev->mutex); + + if (file->f_flags & FASYNC) + comedi_fasync(-1, file, 0); return 0; } -static void comedi_device_init(struct comedi_device *dev) +static int comedi_fasync(int fd, struct file *file, int on) { - memset(dev, 0, sizeof(struct comedi_device)); - spin_lock_init(&dev->spinlock); - mutex_init(&dev->mutex); - dev->minor = -1; -} + const unsigned minor = iminor(file->f_dentry->d_inode); + struct comedi_device_file_info *dev_file_info; + struct comedi_device *dev; + dev_file_info = comedi_get_device_file_info(minor); -static void comedi_device_cleanup(struct comedi_device *dev) -{ + if (dev_file_info == NULL) + return -ENODEV; + dev = dev_file_info->device; if (dev == NULL) - return; - mutex_lock(&dev->mutex); - comedi_device_detach(dev); - mutex_unlock(&dev->mutex); - mutex_destroy(&dev->mutex); + return -ENODEV; + + return fasync_helper(fd, file, on, &dev->async_queue); } -int comedi_alloc_board_minor(struct device *hardware_device) +const struct file_operations comedi_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = comedi_unlocked_ioctl, + .compat_ioctl = comedi_compat_ioctl, + .open = comedi_open, + .release = comedi_close, + .read = comedi_read, + .write = comedi_write, + .mmap = comedi_mmap, + .poll = comedi_poll, + .fasync = comedi_fasync, + .llseek = noop_llseek, +}; + +struct class *comedi_class; +static struct cdev comedi_cdev; + +static void comedi_cleanup_legacy_minors(void) { - struct comedi_device_file_info *info; - struct device *csdev; unsigned i; - int retval; - info = kzalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL); - if (info == NULL) - return -ENOMEM; - info->device = kzalloc(sizeof(struct comedi_device), GFP_KERNEL); - if (info->device == NULL) { - kfree(info); - return -ENOMEM; - } - info->hardware_device = hardware_device; - comedi_device_init(info->device); - spin_lock(&comedi_file_info_table_lock); - for (i = 0; i < COMEDI_NUM_BOARD_MINORS; ++i) { - if (comedi_file_info_table[i] == NULL) { - comedi_file_info_table[i] = info; - break; - } - } - spin_unlock(&comedi_file_info_table_lock); - if (i == COMEDI_NUM_BOARD_MINORS) { - comedi_device_cleanup(info->device); - kfree(info->device); - kfree(info); - printk(KERN_ERR - "comedi: error: " - "ran out of minor numbers for board device files.\n"); - return -EBUSY; - } - info->device->minor = i; - csdev = device_create(comedi_class, hardware_device, - MKDEV(COMEDI_MAJOR, i), NULL, "comedi%i", i); - if (!IS_ERR(csdev)) - info->device->class_dev = csdev; - dev_set_drvdata(csdev, info); - retval = device_create_file(csdev, &dev_attr_max_read_buffer_kb); - if (retval) { - printk(KERN_ERR - "comedi: " - "failed to create sysfs attribute file \"%s\".\n", - dev_attr_max_read_buffer_kb.attr.name); - comedi_free_board_minor(i); - return retval; - } - retval = device_create_file(csdev, &dev_attr_read_buffer_kb); - if (retval) { - printk(KERN_ERR - "comedi: " - "failed to create sysfs attribute file \"%s\".\n", - dev_attr_read_buffer_kb.attr.name); - comedi_free_board_minor(i); - return retval; - } - retval = device_create_file(csdev, &dev_attr_max_write_buffer_kb); - if (retval) { - printk(KERN_ERR - "comedi: " - "failed to create sysfs attribute file \"%s\".\n", - dev_attr_max_write_buffer_kb.attr.name); - comedi_free_board_minor(i); - return retval; - } - retval = device_create_file(csdev, &dev_attr_write_buffer_kb); - if (retval) { - printk(KERN_ERR - "comedi: " - "failed to create sysfs attribute file \"%s\".\n", - dev_attr_write_buffer_kb.attr.name); + for (i = 0; i < comedi_num_legacy_minors; i++) comedi_free_board_minor(i); - return retval; - } - return i; } -void comedi_free_board_minor(unsigned minor) +static int __init comedi_init(void) { - struct comedi_device_file_info *info; + int i; + int retval; - BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS); - spin_lock(&comedi_file_info_table_lock); - info = comedi_file_info_table[minor]; - comedi_file_info_table[minor] = NULL; - spin_unlock(&comedi_file_info_table_lock); + printk(KERN_INFO "comedi: version " COMEDI_RELEASE + " - http://www.comedi.org\n"); - if (info) { - struct comedi_device *dev = info->device; - if (dev) { - if (dev->class_dev) { - device_destroy(comedi_class, - MKDEV(COMEDI_MAJOR, dev->minor)); - } - comedi_device_cleanup(dev); - kfree(dev); - } - kfree(info); + if (comedi_num_legacy_minors < 0 || + comedi_num_legacy_minors > COMEDI_NUM_BOARD_MINORS) { + printk(KERN_ERR "comedi: error: invalid value for module " + "parameter \"comedi_num_legacy_minors\". Valid values " + "are 0 through %i.\n", COMEDI_NUM_BOARD_MINORS); + return -EINVAL; } -} - -int comedi_find_board_minor(struct device *hardware_device) -{ - int minor; - struct comedi_device_file_info *info; - for (minor = 0; minor < COMEDI_NUM_BOARD_MINORS; minor++) { - spin_lock(&comedi_file_info_table_lock); - info = comedi_file_info_table[minor]; - if (info && info->hardware_device == hardware_device) { - spin_unlock(&comedi_file_info_table_lock); - return minor; - } - spin_unlock(&comedi_file_info_table_lock); - } - return -ENODEV; -} + /* + * comedi is unusable if both comedi_autoconfig and + * comedi_num_legacy_minors are zero, so we might as well adjust the + * defaults in that case + */ + if (comedi_autoconfig == 0 && comedi_num_legacy_minors == 0) + comedi_num_legacy_minors = 16; -int comedi_alloc_subdevice_minor(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - struct comedi_device_file_info *info; - struct device *csdev; - unsigned i; - int retval; + memset(comedi_file_info_table, 0, + sizeof(struct comedi_device_file_info *) * COMEDI_NUM_MINORS); - info = kmalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL); - if (info == NULL) - return -ENOMEM; - info->device = dev; - info->read_subdevice = s; - info->write_subdevice = s; - spin_lock(&comedi_file_info_table_lock); - for (i = COMEDI_FIRST_SUBDEVICE_MINOR; i < COMEDI_NUM_MINORS; ++i) { - if (comedi_file_info_table[i] == NULL) { - comedi_file_info_table[i] = info; - break; - } - } - spin_unlock(&comedi_file_info_table_lock); - if (i == COMEDI_NUM_MINORS) { - kfree(info); - printk(KERN_ERR - "comedi: error: " - "ran out of minor numbers for board device files.\n"); - return -EBUSY; - } - s->minor = i; - csdev = device_create(comedi_class, dev->class_dev, - MKDEV(COMEDI_MAJOR, i), NULL, "comedi%i_subd%i", - dev->minor, (int)(s - dev->subdevices)); - if (!IS_ERR(csdev)) - s->class_dev = csdev; - dev_set_drvdata(csdev, info); - retval = device_create_file(csdev, &dev_attr_max_read_buffer_kb); - if (retval) { - printk(KERN_ERR - "comedi: " - "failed to create sysfs attribute file \"%s\".\n", - dev_attr_max_read_buffer_kb.attr.name); - comedi_free_subdevice_minor(s); - return retval; - } - retval = device_create_file(csdev, &dev_attr_read_buffer_kb); - if (retval) { - printk(KERN_ERR - "comedi: " - "failed to create sysfs attribute file \"%s\".\n", - dev_attr_read_buffer_kb.attr.name); - comedi_free_subdevice_minor(s); - return retval; + retval = register_chrdev_region(MKDEV(COMEDI_MAJOR, 0), + COMEDI_NUM_MINORS, "comedi"); + if (retval) + return -EIO; + cdev_init(&comedi_cdev, &comedi_fops); + comedi_cdev.owner = THIS_MODULE; + kobject_set_name(&comedi_cdev.kobj, "comedi"); + if (cdev_add(&comedi_cdev, MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS)) { + unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), + COMEDI_NUM_MINORS); + return -EIO; } - retval = device_create_file(csdev, &dev_attr_max_write_buffer_kb); - if (retval) { - printk(KERN_ERR - "comedi: " - "failed to create sysfs attribute file \"%s\".\n", - dev_attr_max_write_buffer_kb.attr.name); - comedi_free_subdevice_minor(s); - return retval; + comedi_class = class_create(THIS_MODULE, "comedi"); + if (IS_ERR(comedi_class)) { + printk(KERN_ERR "comedi: failed to create class"); + cdev_del(&comedi_cdev); + unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), + COMEDI_NUM_MINORS); + return PTR_ERR(comedi_class); } - retval = device_create_file(csdev, &dev_attr_write_buffer_kb); - if (retval) { - printk(KERN_ERR - "comedi: " - "failed to create sysfs attribute file \"%s\".\n", - dev_attr_write_buffer_kb.attr.name); - comedi_free_subdevice_minor(s); - return retval; + + /* XXX requires /proc interface */ + comedi_proc_init(); + + /* create devices files for legacy/manual use */ + for (i = 0; i < comedi_num_legacy_minors; i++) { + int minor; + minor = comedi_alloc_board_minor(NULL); + if (minor < 0) { + comedi_cleanup_legacy_minors(); + cdev_del(&comedi_cdev); + unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), + COMEDI_NUM_MINORS); + return minor; + } } - return i; + + return 0; } -void comedi_free_subdevice_minor(struct comedi_subdevice *s) +static void __exit comedi_cleanup(void) { - struct comedi_device_file_info *info; - - if (s == NULL) - return; - if (s->minor < 0) - return; + int i; - BUG_ON(s->minor >= COMEDI_NUM_MINORS); - BUG_ON(s->minor < COMEDI_FIRST_SUBDEVICE_MINOR); + comedi_cleanup_legacy_minors(); + for (i = 0; i < COMEDI_NUM_MINORS; ++i) + BUG_ON(comedi_file_info_table[i]); - spin_lock(&comedi_file_info_table_lock); - info = comedi_file_info_table[s->minor]; - comedi_file_info_table[s->minor] = NULL; - spin_unlock(&comedi_file_info_table_lock); + class_destroy(comedi_class); + cdev_del(&comedi_cdev); + unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS); - if (s->class_dev) { - device_destroy(comedi_class, MKDEV(COMEDI_MAJOR, s->minor)); - s->class_dev = NULL; - } - kfree(info); + comedi_proc_cleanup(); } -struct comedi_device_file_info *comedi_get_device_file_info(unsigned minor) -{ - struct comedi_device_file_info *info; +module_init(comedi_init); +module_exit(comedi_cleanup); - BUG_ON(minor >= COMEDI_NUM_MINORS); - spin_lock(&comedi_file_info_table_lock); - info = comedi_file_info_table[minor]; - spin_unlock(&comedi_file_info_table_lock); - return info; +void comedi_error(const struct comedi_device *dev, const char *s) +{ + printk(KERN_ERR "comedi%d: %s: %s\n", dev->minor, + dev->driver->driver_name, s); } -EXPORT_SYMBOL_GPL(comedi_get_device_file_info); +EXPORT_SYMBOL(comedi_error); -static int resize_async_buffer(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_async *async, unsigned new_size) +void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) { - int retval; + struct comedi_async *async = s->async; + unsigned runflags = 0; + unsigned runflags_mask = 0; - if (new_size > async->max_bufsize) - return -EPERM; + /* DPRINTK("comedi_event 0x%x\n",mask); */ - if (s->busy) { - DPRINTK("subdevice is busy, cannot resize buffer\n"); - return -EBUSY; + if ((comedi_get_subdevice_runflags(s) & SRF_RUNNING) == 0) + return; + + if (s-> + async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | + COMEDI_CB_OVERFLOW)) { + runflags_mask |= SRF_RUNNING; } - if (async->mmap_count) { - DPRINTK("subdevice is mmapped, cannot resize buffer\n"); - return -EBUSY; + /* remember if an error event has occurred, so an error + * can be returned the next time the user does a read() */ + if (s->async->events & (COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) { + runflags_mask |= SRF_ERROR; + runflags |= SRF_ERROR; } - - if (!async->prealloc_buf) - return -EINVAL; - - /* make sure buffer is an integral number of pages - * (we round up) */ - new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK; - - retval = comedi_buf_alloc(dev, s, new_size); - if (retval < 0) - return retval; - - if (s->buf_change) { - retval = s->buf_change(dev, s, new_size); - if (retval < 0) - return retval; + if (runflags_mask) { + /*sets SRF_ERROR and SRF_RUNNING together atomically */ + comedi_set_subdevice_runflags(s, runflags_mask, runflags); } - DPRINTK("comedi%i subd %d buffer resized to %i bytes\n", - dev->minor, (int)(s - dev->subdevices), async->prealloc_bufsz); - return 0; + if (async->cb_mask & s->async->events) { + if (comedi_get_subdevice_runflags(s) & SRF_USER) { + wake_up_interruptible(&async->wait_head); + if (s->subdev_flags & SDF_CMD_READ) + kill_fasync(&dev->async_queue, SIGIO, POLL_IN); + if (s->subdev_flags & SDF_CMD_WRITE) + kill_fasync(&dev->async_queue, SIGIO, POLL_OUT); + } else { + if (async->cb_func) + async->cb_func(s->async->events, async->cb_arg); + } + } + s->async->events = 0; } +EXPORT_SYMBOL(comedi_event); -/* sysfs attribute files */ - -static const unsigned bytes_per_kibi = 1024; - -static ssize_t show_max_read_buffer_kb(struct device *dev, - struct device_attribute *attr, char *buf) +unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s) { - ssize_t retval; - struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned max_buffer_size_kb = 0; - struct comedi_subdevice *const read_subdevice = - comedi_get_read_subdevice(info); - - mutex_lock(&info->device->mutex); - if (read_subdevice && - (read_subdevice->subdev_flags & SDF_CMD_READ) && - read_subdevice->async) { - max_buffer_size_kb = read_subdevice->async->max_bufsize / - bytes_per_kibi; - } - retval = snprintf(buf, PAGE_SIZE, "%i\n", max_buffer_size_kb); - mutex_unlock(&info->device->mutex); + unsigned long flags; + unsigned runflags; - return retval; + spin_lock_irqsave(&s->spin_lock, flags); + runflags = s->runflags; + spin_unlock_irqrestore(&s->spin_lock, flags); + return runflags; } +EXPORT_SYMBOL(comedi_get_subdevice_runflags); -static ssize_t store_max_read_buffer_kb(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static int is_device_busy(struct comedi_device *dev) { - struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned int new_max_size_kb; - unsigned int new_max_size; - int ret; - struct comedi_subdevice *const read_subdevice = - comedi_get_read_subdevice(info); + struct comedi_subdevice *s; + int i; - ret = kstrtouint(buf, 10, &new_max_size_kb); - if (ret) - return ret; - if (new_max_size_kb > (UINT_MAX / bytes_per_kibi)) - return -EINVAL; - new_max_size = new_max_size_kb * bytes_per_kibi; + if (!dev->attached) + return 0; - mutex_lock(&info->device->mutex); - if (read_subdevice == NULL || - (read_subdevice->subdev_flags & SDF_CMD_READ) == 0 || - read_subdevice->async == NULL) { - mutex_unlock(&info->device->mutex); - return -EINVAL; + for (i = 0; i < dev->n_subdevices; i++) { + s = dev->subdevices + i; + if (s->busy) + return 1; + if (s->async && s->async->mmap_count) + return 1; } - read_subdevice->async->max_bufsize = new_max_size; - mutex_unlock(&info->device->mutex); - return count; + return 0; } -static struct device_attribute dev_attr_max_read_buffer_kb = { - .attr = { - .name = "max_read_buffer_kb", - .mode = S_IRUGO | S_IWUSR}, - .show = &show_max_read_buffer_kb, - .store = &store_max_read_buffer_kb -}; +static void comedi_device_init(struct comedi_device *dev) +{ + memset(dev, 0, sizeof(struct comedi_device)); + spin_lock_init(&dev->spinlock); + mutex_init(&dev->mutex); + dev->minor = -1; +} -static ssize_t show_read_buffer_kb(struct device *dev, - struct device_attribute *attr, char *buf) +static void comedi_device_cleanup(struct comedi_device *dev) { - ssize_t retval; - struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned buffer_size_kb = 0; - struct comedi_subdevice *const read_subdevice = - comedi_get_read_subdevice(info); + if (dev == NULL) + return; + mutex_lock(&dev->mutex); + comedi_device_detach(dev); + mutex_unlock(&dev->mutex); + mutex_destroy(&dev->mutex); +} + +int comedi_alloc_board_minor(struct device *hardware_device) +{ + struct comedi_device_file_info *info; + struct device *csdev; + unsigned i; + int retval; + + info = kzalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL); + if (info == NULL) + return -ENOMEM; + info->device = kzalloc(sizeof(struct comedi_device), GFP_KERNEL); + if (info->device == NULL) { + kfree(info); + return -ENOMEM; + } + info->hardware_device = hardware_device; + comedi_device_init(info->device); + spin_lock(&comedi_file_info_table_lock); + for (i = 0; i < COMEDI_NUM_BOARD_MINORS; ++i) { + if (comedi_file_info_table[i] == NULL) { + comedi_file_info_table[i] = info; + break; + } + } + spin_unlock(&comedi_file_info_table_lock); + if (i == COMEDI_NUM_BOARD_MINORS) { + comedi_device_cleanup(info->device); + kfree(info->device); + kfree(info); + printk(KERN_ERR + "comedi: error: " + "ran out of minor numbers for board device files.\n"); + return -EBUSY; + } + info->device->minor = i; + csdev = device_create(comedi_class, hardware_device, + MKDEV(COMEDI_MAJOR, i), NULL, "comedi%i", i); + if (!IS_ERR(csdev)) + info->device->class_dev = csdev; + dev_set_drvdata(csdev, info); - mutex_lock(&info->device->mutex); - if (read_subdevice && - (read_subdevice->subdev_flags & SDF_CMD_READ) && - read_subdevice->async) { - buffer_size_kb = read_subdevice->async->prealloc_bufsz / - bytes_per_kibi; + retval = sysfs_create_group(&csdev->kobj, &comedi_sysfs_files); + if (retval) { + printk(KERN_ERR + "comedi: failed to create sysfs attribute files\n"); + comedi_free_board_minor(i); + return retval; } - retval = snprintf(buf, PAGE_SIZE, "%i\n", buffer_size_kb); - mutex_unlock(&info->device->mutex); - return retval; + return i; } -static ssize_t store_read_buffer_kb(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +void comedi_free_board_minor(unsigned minor) { - struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned int new_size_kb; - unsigned int new_size; - int retval; - int ret; - struct comedi_subdevice *const read_subdevice = - comedi_get_read_subdevice(info); + struct comedi_device_file_info *info; - ret = kstrtouint(buf, 10, &new_size_kb); - if (ret) - return ret; - if (new_size_kb > (UINT_MAX / bytes_per_kibi)) - return -EINVAL; - new_size = new_size_kb * bytes_per_kibi; + BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS); + spin_lock(&comedi_file_info_table_lock); + info = comedi_file_info_table[minor]; + comedi_file_info_table[minor] = NULL; + spin_unlock(&comedi_file_info_table_lock); - mutex_lock(&info->device->mutex); - if (read_subdevice == NULL || - (read_subdevice->subdev_flags & SDF_CMD_READ) == 0 || - read_subdevice->async == NULL) { - mutex_unlock(&info->device->mutex); - return -EINVAL; + if (info) { + struct comedi_device *dev = info->device; + if (dev) { + if (dev->class_dev) { + device_destroy(comedi_class, + MKDEV(COMEDI_MAJOR, dev->minor)); + } + comedi_device_cleanup(dev); + kfree(dev); + } + kfree(info); } - retval = resize_async_buffer(info->device, read_subdevice, - read_subdevice->async, new_size); - mutex_unlock(&info->device->mutex); - - if (retval < 0) - return retval; - return count; } -static struct device_attribute dev_attr_read_buffer_kb = { - .attr = { - .name = "read_buffer_kb", - .mode = S_IRUGO | S_IWUSR | S_IWGRP}, - .show = &show_read_buffer_kb, - .store = &store_read_buffer_kb -}; - -static ssize_t show_max_write_buffer_kb(struct device *dev, - struct device_attribute *attr, - char *buf) +int comedi_find_board_minor(struct device *hardware_device) { - ssize_t retval; - struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned max_buffer_size_kb = 0; - struct comedi_subdevice *const write_subdevice = - comedi_get_write_subdevice(info); + int minor; + struct comedi_device_file_info *info; - mutex_lock(&info->device->mutex); - if (write_subdevice && - (write_subdevice->subdev_flags & SDF_CMD_WRITE) && - write_subdevice->async) { - max_buffer_size_kb = write_subdevice->async->max_bufsize / - bytes_per_kibi; + for (minor = 0; minor < COMEDI_NUM_BOARD_MINORS; minor++) { + spin_lock(&comedi_file_info_table_lock); + info = comedi_file_info_table[minor]; + if (info && info->hardware_device == hardware_device) { + spin_unlock(&comedi_file_info_table_lock); + return minor; + } + spin_unlock(&comedi_file_info_table_lock); } - retval = snprintf(buf, PAGE_SIZE, "%i\n", max_buffer_size_kb); - mutex_unlock(&info->device->mutex); - - return retval; + return -ENODEV; } -static ssize_t store_max_write_buffer_kb(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +int comedi_alloc_subdevice_minor(struct comedi_device *dev, + struct comedi_subdevice *s) { - struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned int new_max_size_kb; - unsigned int new_max_size; - int ret; - struct comedi_subdevice *const write_subdevice = - comedi_get_write_subdevice(info); + struct comedi_device_file_info *info; + struct device *csdev; + unsigned i; + int retval; - ret = kstrtouint(buf, 10, &new_max_size_kb); - if (ret) - return ret; - if (new_max_size_kb > (UINT_MAX / bytes_per_kibi)) - return -EINVAL; - new_max_size = new_max_size_kb * bytes_per_kibi; + info = kmalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL); + if (info == NULL) + return -ENOMEM; + info->device = dev; + info->read_subdevice = s; + info->write_subdevice = s; + spin_lock(&comedi_file_info_table_lock); + for (i = COMEDI_FIRST_SUBDEVICE_MINOR; i < COMEDI_NUM_MINORS; ++i) { + if (comedi_file_info_table[i] == NULL) { + comedi_file_info_table[i] = info; + break; + } + } + spin_unlock(&comedi_file_info_table_lock); + if (i == COMEDI_NUM_MINORS) { + kfree(info); + printk(KERN_ERR + "comedi: error: " + "ran out of minor numbers for board device files.\n"); + return -EBUSY; + } + s->minor = i; + csdev = device_create(comedi_class, dev->class_dev, + MKDEV(COMEDI_MAJOR, i), NULL, "comedi%i_subd%i", + dev->minor, (int)(s - dev->subdevices)); + if (!IS_ERR(csdev)) + s->class_dev = csdev; + dev_set_drvdata(csdev, info); - mutex_lock(&info->device->mutex); - if (write_subdevice == NULL || - (write_subdevice->subdev_flags & SDF_CMD_WRITE) == 0 || - write_subdevice->async == NULL) { - mutex_unlock(&info->device->mutex); - return -EINVAL; + retval = sysfs_create_group(&csdev->kobj, &comedi_sysfs_files); + if (retval) { + printk(KERN_ERR + "comedi: failed to create sysfs attribute files\n"); + comedi_free_subdevice_minor(s); + return retval; } - write_subdevice->async->max_bufsize = new_max_size; - mutex_unlock(&info->device->mutex); - return count; + return i; } -static struct device_attribute dev_attr_max_write_buffer_kb = { - .attr = { - .name = "max_write_buffer_kb", - .mode = S_IRUGO | S_IWUSR}, - .show = &show_max_write_buffer_kb, - .store = &store_max_write_buffer_kb -}; - -static ssize_t show_write_buffer_kb(struct device *dev, - struct device_attribute *attr, char *buf) +void comedi_free_subdevice_minor(struct comedi_subdevice *s) { - ssize_t retval; - struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned buffer_size_kb = 0; - struct comedi_subdevice *const write_subdevice = - comedi_get_write_subdevice(info); - - mutex_lock(&info->device->mutex); - if (write_subdevice && - (write_subdevice->subdev_flags & SDF_CMD_WRITE) && - write_subdevice->async) { - buffer_size_kb = write_subdevice->async->prealloc_bufsz / - bytes_per_kibi; - } - retval = snprintf(buf, PAGE_SIZE, "%i\n", buffer_size_kb); - mutex_unlock(&info->device->mutex); + struct comedi_device_file_info *info; - return retval; -} + if (s == NULL) + return; + if (s->minor < 0) + return; -static ssize_t store_write_buffer_kb(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned int new_size_kb; - unsigned int new_size; - int retval; - int ret; - struct comedi_subdevice *const write_subdevice = - comedi_get_write_subdevice(info); + BUG_ON(s->minor >= COMEDI_NUM_MINORS); + BUG_ON(s->minor < COMEDI_FIRST_SUBDEVICE_MINOR); - ret = kstrtouint(buf, 10, &new_size_kb); - if (ret) - return ret; - if (new_size_kb > (UINT_MAX / bytes_per_kibi)) - return -EINVAL; - new_size = ((uint64_t) new_size_kb) * bytes_per_kibi; + spin_lock(&comedi_file_info_table_lock); + info = comedi_file_info_table[s->minor]; + comedi_file_info_table[s->minor] = NULL; + spin_unlock(&comedi_file_info_table_lock); - mutex_lock(&info->device->mutex); - if (write_subdevice == NULL || - (write_subdevice->subdev_flags & SDF_CMD_WRITE) == 0 || - write_subdevice->async == NULL) { - mutex_unlock(&info->device->mutex); - return -EINVAL; + if (s->class_dev) { + device_destroy(comedi_class, MKDEV(COMEDI_MAJOR, s->minor)); + s->class_dev = NULL; } - retval = resize_async_buffer(info->device, write_subdevice, - write_subdevice->async, new_size); - mutex_unlock(&info->device->mutex); - - if (retval < 0) - return retval; - return count; + kfree(info); } -static struct device_attribute dev_attr_write_buffer_kb = { - .attr = { - .name = "write_buffer_kb", - .mode = S_IRUGO | S_IWUSR | S_IWGRP}, - .show = &show_write_buffer_kb, - .store = &store_write_buffer_kb -}; +struct comedi_device_file_info *comedi_get_device_file_info(unsigned minor) +{ + struct comedi_device_file_info *info; + + BUG_ON(minor >= COMEDI_NUM_MINORS); + spin_lock(&comedi_file_info_table_lock); + info = comedi_file_info_table[minor]; + spin_unlock(&comedi_file_info_table_lock); + return info; +} +EXPORT_SYMBOL_GPL(comedi_get_device_file_info); -- cgit v0.10.2 From be10ac2b961e348919ce09d2b88471116d865087 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 7 May 2012 07:38:22 -0700 Subject: staging: rtl8712: Fix typos. Signed-off-by: Justin P. Mattock Acked-by: Larry Finger Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8712/drv_types.h b/drivers/staging/rtl8712/drv_types.h index e83665d..62b5566 100644 --- a/drivers/staging/rtl8712/drv_types.h +++ b/drivers/staging/rtl8712/drv_types.h @@ -146,7 +146,7 @@ struct dvobj_priv { /** * struct _adapter - the main adapter structure for this device. * - * bup: True indicates that the interface is Up. + * bup: True indicates that the interface is up. */ struct _adapter { struct dvobj_priv dvobjpriv; diff --git a/drivers/staging/rtl8712/ieee80211.h b/drivers/staging/rtl8712/ieee80211.h index 3c0092b..21515c3 100644 --- a/drivers/staging/rtl8712/ieee80211.h +++ b/drivers/staging/rtl8712/ieee80211.h @@ -705,7 +705,7 @@ enum ieee80211_state { IEEE80211_ASSOCIATING_RETRY, /* the association procedure is sending AUTH request*/ IEEE80211_ASSOCIATING_AUTHENTICATING, - /* the association procedure has successfully authentcated + /* the association procedure has successfully authenticated * and is sending association request */ IEEE80211_ASSOCIATING_AUTHENTICATED, diff --git a/drivers/staging/rtl8712/if_ether.h b/drivers/staging/rtl8712/if_ether.h index 2bbe527..9916b6a 100644 --- a/drivers/staging/rtl8712/if_ether.h +++ b/drivers/staging/rtl8712/if_ether.h @@ -25,7 +25,7 @@ ******************************************************************************/ /* * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket + * operating system. INET is implemented using the BSD Socket * interface as the means of communication with the user level. * * Global definitions for the Ethernet IEEE 802.3 interface. diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c index 7bbd53a..448f00d 100644 --- a/drivers/staging/rtl8712/os_intfs.c +++ b/drivers/staging/rtl8712/os_intfs.c @@ -52,7 +52,7 @@ static int lbkmode = RTL8712_AIR_TRX; static int hci = RTL8712_USB; static int ampdu_enable = 1;/*for enable tx_ampdu*/ -/* The video_mode variable is for vedio mode.*/ +/* The video_mode variable is for video mode.*/ /* It may be specify when inserting module with video_mode=1 parameter.*/ static int video_mode = 1; /* enable video mode*/ @@ -248,7 +248,7 @@ static u32 start_drv_threads(struct _adapter *padapter) void r8712_stop_drv_threads(struct _adapter *padapter) { - /*Below is to termindate r8712_cmd_thread & event_thread...*/ + /*Below is to terminate r8712_cmd_thread & event_thread...*/ up(&padapter->cmdpriv.cmd_queue_sema); if (padapter->cmdThread) _down_sema(&padapter->cmdpriv.terminate_cmdthread_sema); diff --git a/drivers/staging/rtl8712/rtl8712_cmd.c b/drivers/staging/rtl8712/rtl8712_cmd.c index 9f6ebc4..6c4a94c 100644 --- a/drivers/staging/rtl8712/rtl8712_cmd.c +++ b/drivers/staging/rtl8712/rtl8712_cmd.c @@ -69,7 +69,7 @@ static void check_hw_pbc(struct _adapter *padapter) * After trigger PBC, the variable will be set to false */ DBG_8712("CheckPbcGPIO - PBC is pressed !!!!\n"); /* 0 is the default value and it means the application monitors - * the HW PBC doesn't privde its pid to driver. */ + * the HW PBC doesn't provide its pid to driver. */ if (padapter->pid == 0) return; kill_pid(find_vpid(padapter->pid), SIGUSR1, 1); @@ -382,7 +382,7 @@ _next: *pcmdbuf = cpu_to_le32((cmdsz & 0x0000ffff) | (pcmd->cmdcode << 16) | (pcmdpriv->cmd_seq << 24)); - pcmdbuf += 2 ; /* 8 bytes aligment */ + pcmdbuf += 2 ; /* 8 bytes alignment */ memcpy((u8 *)pcmdbuf, pcmd->parmbuf, pcmd->cmdsz); while (check_cmd_fifo(padapter, wr_sz) == _FAIL) { if ((padapter->bDriverStopped == true) || @@ -471,7 +471,7 @@ void r8712_event_handle(struct _adapter *padapter, uint *peventbuf) pevt_priv->event_seq++; /* update evt_seq */ if (pevt_priv->event_seq > 127) pevt_priv->event_seq = 0; - peventbuf = peventbuf + 2; /* move to event content, 8 bytes aligment */ + peventbuf = peventbuf + 2; /* move to event content, 8 bytes alignment */ if (peventbuf) { event_callback = wlanevents[evt_code].event_callback; if (event_callback) diff --git a/drivers/staging/rtl8712/rtl8712_cmd.h b/drivers/staging/rtl8712/rtl8712_cmd.h index 766a646..039ab3e 100644 --- a/drivers/staging/rtl8712/rtl8712_cmd.h +++ b/drivers/staging/rtl8712/rtl8712_cmd.h @@ -121,7 +121,7 @@ enum rtl8712_h2c_cmd { GEN_CMD_CODE(_GetCurDataRate) , GEN_CMD_CODE(_GetTxRetrycnt), /* to record times that Tx retry to - * transmmit packet after association + * transmit packet after association */ GEN_CMD_CODE(_GetRxRetrycnt), /* to record total number of the * received frame with ReTry bit set in diff --git a/drivers/staging/rtl8712/rtl8712_efuse.c b/drivers/staging/rtl8712/rtl8712_efuse.c index b08e9a2..377fca9 100644 --- a/drivers/staging/rtl8712/rtl8712_efuse.c +++ b/drivers/staging/rtl8712/rtl8712_efuse.c @@ -417,7 +417,7 @@ u8 r8712_efuse_pg_packet_write(struct _adapter *padapter, const u8 offset, } else { /* write header fail */ bResult = false; if (0xFF == efuse_data) - return bResult; /* not thing damaged. */ + return bResult; /* nothing damaged. */ /* call rescue procedure */ if (fix_header(padapter, efuse_data, efuse_addr) == false) diff --git a/drivers/staging/rtl8712/rtl8712_gp_bitdef.h b/drivers/staging/rtl8712/rtl8712_gp_bitdef.h index 884a821..138ea45 100644 --- a/drivers/staging/rtl8712/rtl8712_gp_bitdef.h +++ b/drivers/staging/rtl8712/rtl8712_gp_bitdef.h @@ -70,7 +70,7 @@ #define GPIOSEL_BT 2 /* BT_coex*/ #define GPIOSEL_WLANDBG 3 /* WLANDBG*/ #define GPIOSEL_GPIO_MASK (~(BIT(0)|BIT(1))) -/* HW Readio OFF switch (GPIO BIT) */ +/* HW Radio OFF switch (GPIO BIT) */ #define HAL_8192S_HW_GPIO_OFF_BIT BIT(3) #define HAL_8192S_HW_GPIO_OFF_MASK 0xF7 #define HAL_8192S_HW_GPIO_WPS_BIT BIT(4) diff --git a/drivers/staging/rtl8712/rtl8712_hal.h b/drivers/staging/rtl8712/rtl8712_hal.h index d19865a..4c51fa3 100644 --- a/drivers/staging/rtl8712/rtl8712_hal.h +++ b/drivers/staging/rtl8712/rtl8712_hal.h @@ -83,7 +83,7 @@ struct fw_priv { /*8-bytes alignment required*/ unsigned char rfintfs; /* 0:SWSI, 1:HWSI, 2:HWPI*/ unsigned char def_nettype; unsigned char turboMode; - unsigned char lowPowerMode;/* 0: noral mode, 1: low power mode*/ + unsigned char lowPowerMode;/* 0: normal mode, 1: low power mode*/ /*--- long word 2 ----*/ unsigned char lbk_mode; /*0x00: normal, 0x03: MACLBK, 0x01: PHYLBK*/ unsigned char mp_mode; /* 1: for MP use, 0: for normal driver */ @@ -123,7 +123,7 @@ struct fw_priv { /*8-bytes alignment required*/ unsigned char rsvd053; }; -struct fw_hdr {/*8-byte alinment required*/ +struct fw_hdr {/*8-byte alignment required*/ unsigned short signature; unsigned short version; /*0x8000 ~ 0x8FFF for FPGA version, *0x0000 ~ 0x7FFF for ASIC version,*/ diff --git a/drivers/staging/rtl8712/rtl8712_led.c b/drivers/staging/rtl8712/rtl8712_led.c index bac56e5..c9eb4b7 100644 --- a/drivers/staging/rtl8712/rtl8712_led.c +++ b/drivers/staging/rtl8712/rtl8712_led.c @@ -60,7 +60,7 @@ enum _LED_STATE_871x { * the # of times to blink is depend on time * for scanning. */ LED_NO_LINK_BLINK = 7, /* LED is blinking during no link state. */ - LED_BLINK_StartToBlink = 8,/* Customzied for Sercomm Printer + LED_BLINK_StartToBlink = 8,/* Customized for Sercomm Printer * Server case */ LED_BLINK_WPS = 9, /* LED is blinkg during WPS communication */ LED_TXRX_BLINK = 10, @@ -826,7 +826,7 @@ static void BlinkTimerCallback(unsigned long data) { struct LED_871x *pLed = (struct LED_871x *)data; - /* This fixed the crash problem on Fedora 12 when trying to do thei + /* This fixed the crash problem on Fedora 12 when trying to do the * insmod;ifconfig up;rmmod commands. */ if ((pLed->padapter->bSurpriseRemoved == true) || (pLed->padapter->bDriverStopped == true)) @@ -836,7 +836,7 @@ static void BlinkTimerCallback(unsigned long data) /* Description: * Callback function of LED BlinkWorkItem. - * We dispatch acture LED blink action according to LedStrategy. + * We dispatch actual LED blink action according to LedStrategy. */ static void BlinkWorkItemCallback(struct work_struct *work) { diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c index fa6dc9c..5d7217f 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.c +++ b/drivers/staging/rtl8712/rtl8712_recv.c @@ -459,7 +459,7 @@ void r8712_rxcmd_event_hdl(struct _adapter *padapter, void *prxcmdbuf) cmd_seq = (u8)((le32_to_cpu(voffset) >> 24) & 0x7f); eid = (u8)((le32_to_cpu(voffset) >> 16) & 0xff); r8712_event_handle(padapter, (uint *)poffset); - poffset += (cmd_len + 8);/*8 bytes aligment*/ + poffset += (cmd_len + 8);/*8 bytes alignment*/ } while (le32_to_cpu(voffset) & BIT(31)); } @@ -603,7 +603,7 @@ static int recv_indicatepkt_reorder(struct _adapter *padapter, } } spin_lock_irqsave(&ppending_recvframe_queue->lock, irql); - /*s2. check if winstart_b(indicate_seq) needs to been updated*/ + /*s2. check if winstart_b(indicate_seq) needs to be updated*/ if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) goto _err_exit; /*s3. Insert all packet into Reorder Queue to maintain its ordering.*/ diff --git a/drivers/staging/rtl8712/rtl871x_cmd.h b/drivers/staging/rtl8712/rtl871x_cmd.h index 757ebf7..9d93189 100644 --- a/drivers/staging/rtl8712/rtl871x_cmd.h +++ b/drivers/staging/rtl8712/rtl871x_cmd.h @@ -720,7 +720,7 @@ struct DisconnectCtrlEx_param { * Result: * 0x00: success * 0x01: success, and check Response. - * 0x02: cmd ignored due to duplicated sequcne number + * 0x02: cmd ignored due to duplicated sequence number * 0x03: cmd dropped due to invalid cmd code * 0x04: reserved. */ diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index 3b23bef..35e781f 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -241,7 +241,7 @@ static inline char *translate_scan(struct _adapter *padapter, /* Add frequency/channel */ iwe.cmd = SIOCGIWFREQ; { - /* check legel index */ + /* check legal index */ u8 dsconfig = pnetwork->network.Configuration.DSConfig; if (dsconfig >= 1 && dsconfig <= sizeof( ieee80211_wlan_frequencies) / sizeof(long)) @@ -809,11 +809,11 @@ static int r871x_wx_set_pmkid(struct net_device *dev, /* There are the BSSID information in the bssid.sa_data array. - If cmd is IW_PMKSA_FLUSH, it means the wpa_suppplicant wants to clear - all the PMKID information. If cmd is IW_PMKSA_ADD, it means the - wpa_supplicant wants to add a PMKID/BSSID to driver. + If cmd is IW_PMKSA_FLUSH, it means the wpa_supplicant wants to clear + all the PMKID information. If cmd is IW_PMKSA_ADD, it means the + wpa_supplicant wants to add a PMKID/BSSID to driver. If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to - remove a PMKID/BSSID from driver. + remove a PMKID/BSSID from driver. */ if (pPMK == NULL) return -EINVAL; @@ -923,7 +923,7 @@ static int r8711_wx_get_range(struct net_device *dev, range->max_qual.noise = 100; range->max_qual.updated = 7; /* Updated all three */ range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */ - /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ + /* TODO: Find real 'good' to 'bad' threshold value for RSSI */ range->avg_qual.level = 20 + -98; range->avg_qual.noise = 0; range->avg_qual.updated = 7; /* Updated all three */ @@ -1070,7 +1070,7 @@ FREE_EXT: * MAC# of a preferred Access Point. * Currently, the request comes via Wireless Extensions' SIOCSIWAP ioctl. * - * For this operation to succeed, there is no need for the interface to be Up. + * For this operation to succeed, there is no need for the interface to be up. * */ static int r8711_wx_set_wap(struct net_device *dev, diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_set.c b/drivers/staging/rtl8712/rtl871x_ioctl_set.c index fb29b42..f352b32 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_set.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_set.c @@ -264,7 +264,7 @@ void r8712_set_802_11_infrastructure_mode(struct _adapter *padapter, (*pold_state == Ndis802_11Infrastructure) || (*pold_state == Ndis802_11IBSS)) { /* will clr Linked_state before this function, - * we must have chked whether issue dis-assoc_cmd or + * we must have checked whether issue dis-assoc_cmd or * not */ r8712_ind_disconnect(padapter); } diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c index 4277d03..dc7adc1 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.c +++ b/drivers/staging/rtl8712/rtl871x_mlme.c @@ -137,7 +137,7 @@ static void _free_network_nolock(struct mlme_priv *pmlmepriv, /* return the wlan_network with the matching addr - Shall be calle under atomic context... + Shall be called under atomic context... to avoid possible racing condition... */ static struct wlan_network *_r8712_find_network(struct __queue *scanned_queue, @@ -255,7 +255,7 @@ void r8712_free_network_queue(struct _adapter *dev) /* return the wlan_network with the matching addr - Shall be calle under atomic context... + Shall be called under atomic context... to avoid possible racing condition... */ static struct wlan_network *r8712_find_network(struct __queue *scanned_queue, @@ -1037,7 +1037,7 @@ void r8712_cpwm_event_callback(struct _adapter *adapter, u8 *pbuf) * and the WiFi client will drop the data with seq number 0. * So, the 8712 firmware has to inform driver with receiving the * ADDBA-Req frame so that the driver can reset the - * sequence value of Rx reorder contorl. + * sequence value of Rx reorder control. */ void r8712_got_addbareq_event_callback(struct _adapter *adapter, u8 *pbuf) { @@ -1775,7 +1775,7 @@ static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len) phtpriv->rx_ampdu_maxlen = max_ampdu_sz; } /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info - * if A-MPDU Rx is enabled, reseting rx_ordering_ctrl + * if A-MPDU Rx is enabled, resetting rx_ordering_ctrl * wstart_b(indicate_seq) to default value=0xffff * todo: check if AP can send A-MPDU packets */ diff --git a/drivers/staging/rtl8712/rtl871x_mlme.h b/drivers/staging/rtl8712/rtl871x_mlme.h index 71ca013..42bd0bf 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.h +++ b/drivers/staging/rtl8712/rtl871x_mlme.h @@ -69,8 +69,8 @@ since mlme_priv is a shared resource between many threads, like ISR/Call-Back functions, the OID handlers, and even timer functions. Each _queue has its own locks, already. Other items are protected by mlme_priv.lock. -To avoid possible dead lock, any thread trying to modifiying mlme_priv -SHALL not lock up more than one locks at a time! +To avoid possible dead lock, any thread trying to modify mlme_priv +SHALL not lock up more than one lock at a time! */ #define traffic_threshold 10 @@ -132,7 +132,7 @@ static inline sint get_fwstate(struct mlme_priv *pmlmepriv) * therefore set it to be the critical section... * * ### NOTE:#### (!!!!) - * TAKE CARE THAT BEFORE CALLING THIS FUNC, LOCK pmlmepriv->lock + * TAKE CARE BEFORE CALLING THIS FUNC, LOCK pmlmepriv->lock */ static inline void set_fwstate(struct mlme_priv *pmlmepriv, sint state) { diff --git a/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h b/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h index 23532a7..8e25862 100644 --- a/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h +++ b/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h @@ -184,7 +184,7 @@ /*RxIQ DC offset, Rx digital filter, DC notch filter */ #define rOFDM0_XARxAFE 0xc10 -#define rOFDM0_XARxIQImbalance 0xc14 /* RxIQ imblance matrix */ +#define rOFDM0_XARxIQImbalance 0xc14 /* RxIQ imbalance matrix */ #define rOFDM0_XBRxAFE 0xc18 #define rOFDM0_XBRxIQImbalance 0xc1c #define rOFDM0_XCRxAFE 0xc20 @@ -603,7 +603,7 @@ #define bCCKRxIG 0x7f00 #define bCCKLNAPolarity 0x800000 #define bCCKRx1stGain 0x7f0000 -#define bCCKRFExtend 0x20000000 /* CCK Rx Iinital gain polarity */ +#define bCCKRFExtend 0x20000000 /* CCK Rx inital gain polarity */ #define bCCKRxAGCSatLevel 0x1f000000 #define bCCKRxAGCSatCount 0xe0 #define bCCKRxRFSettle 0x1f /* AGCsamp_dly */ diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c index aa57e77..2ddb757 100644 --- a/drivers/staging/rtl8712/rtl871x_xmit.c +++ b/drivers/staging/rtl8712/rtl871x_xmit.c @@ -72,7 +72,7 @@ sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv)); spin_lock_init(&pxmitpriv->lock); /* - Please insert all the queue initializaiton using _init_queue below + Please insert all the queue initialization using _init_queue below */ pxmitpriv->adapter = padapter; _init_queue(&pxmitpriv->be_pending); diff --git a/drivers/staging/rtl8712/rtl871x_xmit.h b/drivers/staging/rtl8712/rtl871x_xmit.h index 638b79b..ee90698 100644 --- a/drivers/staging/rtl8712/rtl871x_xmit.h +++ b/drivers/staging/rtl8712/rtl871x_xmit.h @@ -119,7 +119,7 @@ struct pkt_attrib { u8 priority; u8 encrypt; /* when 0 indicate no encrypt. when non-zero, - * indicate the encrypt algorith*/ + * indicate the encrypt algorithm*/ u8 iv_len; u8 icv_len; unsigned char iv[8]; diff --git a/drivers/staging/rtl8712/usb_halinit.c b/drivers/staging/rtl8712/usb_halinit.c index 46287c1..b4ae11a 100644 --- a/drivers/staging/rtl8712/usb_halinit.c +++ b/drivers/staging/rtl8712/usb_halinit.c @@ -141,7 +141,7 @@ u8 r8712_usb_hal_bus_init(struct _adapter *padapter) /* Enable AFE PLL Macro Block */ val8 = r8712_read8(padapter, AFE_PLL_CTRL); r8712_write8(padapter, AFE_PLL_CTRL, (val8 | 0x11)); - /* Attatch AFE PLL to MACTOP/BB/PCIe Digital */ + /* Attach AFE PLL to MACTOP/BB/PCIe Digital */ val8 = r8712_read8(padapter, SYS_ISO_CTRL); r8712_write8(padapter, SYS_ISO_CTRL, (val8 & 0xEE)); /* Switch to 40M clock */ @@ -234,7 +234,7 @@ u8 r8712_usb_hal_bus_init(struct _adapter *padapter) udelay(500); r8712_write8(padapter, AFE_PLL_CTRL, (val8 | 0x11)); udelay(500); - /* Attatch AFE PLL to MACTOP/BB/PCIe Digital */ + /* Attach AFE PLL to MACTOP/BB/PCIe Digital */ val8 = r8712_read8(padapter, SYS_ISO_CTRL); r8712_write8(padapter, SYS_ISO_CTRL, (val8 & 0xEE)); /* Switch to 40M clock */ diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c index e419b4f..a0de043 100644 --- a/drivers/staging/rtl8712/usb_intf.c +++ b/drivers/staging/rtl8712/usb_intf.c @@ -644,7 +644,7 @@ static void r871xu_dev_remove(struct usb_interface *pusb_intf) /* decrease the reference count of the usb device structure * when disconnect */ usb_put_dev(udev); - /* If we didn't unplug usb dongle and remove/insert modlue, driver + /* If we didn't unplug usb dongle and remove/insert module, driver * fails on sitesurvey for the first time when device is up. * Reset usb port for sitesurvey fail issue. */ if (udev->state != USB_STATE_NOTATTACHED) -- cgit v0.10.2 From a26c43a9512a2f70cf66157e69f2cd2725ce60bf Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Mon, 7 May 2012 08:21:59 +0900 Subject: staging: wlags49_h2: Fix spelling Endianess to Endianness in wlags49_h2 Correct spelling typo "Endianess" to "Endianness" in wlags49_h2. Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlags49_h2/hcf.c b/drivers/staging/wlags49_h2/hcf.c index 5957c3a..366e4a4 100644 --- a/drivers/staging/wlags49_h2/hcf.c +++ b/drivers/staging/wlags49_h2/hcf.c @@ -2871,8 +2871,8 @@ or * The Assert validates the HCF assumption about Hermes implementation upon which the range of * Pseudo-RIDs is based. * Then the control fields up to the start of the 802.3 frame are read from the NIC into the lookahead buffer. -* The status field is converted to native Endianess. -* The length is, after implicit Endianess conversion if needed, and adjustment for the 14 bytes of the +* The status field is converted to native Endianness. +* The length is, after implicit Endianness conversion if needed, and adjustment for the 14 bytes of the * 802.3 MAC header, stored in IFB_RxLen. * In MAC Monitor mode, 802.11 control frames with a TOTAL length of 14 are received, so without this * length adjustment, IFB_RxLen could not be used to distinguish these frames from "no frame". @@ -2894,7 +2894,7 @@ or * - the Hermes reported Tunnel encapsulation or * - the Hermes reported 1042 Encapsulation and hcf_encap reports that the HCF would not have used * 1042 as the encapsulation mechanism -* Note that the first field of the RxFS in bufp has Native Endianess due to the conversion done by the +* Note that the first field of the RxFS in bufp has Native Endianness due to the conversion done by the * BE_PAR in get_frag. *36: The Type field is the only word kept (after moving) of the just read 8 bytes, it is moved to the * L-field. The original L-field and 6 byte SNAP header are discarded, so IFB_RxLen and buf_addr must @@ -3831,7 +3831,7 @@ get_fid( IFBP ifbp ) *.DESCRIPTION * process the single byte (if applicable) read by the previous get_frag and copy len (or len-1) bytes from * NIC to bufp. - * On a Big Endian platform, the parameter word_len controls the number of leading bytes whose endianess is + * On a Big Endian platform, the parameter word_len controls the number of leading bytes whose endianness is * converted (i.e. byte swapped) * * @@ -3980,7 +3980,7 @@ get_frag( IFBP ifbp, wci_bufp bufp, int len BE_PAR( int word_len ) ) * appropriate means on H-I: always * and on H-II if F/W supplier reflects a primary (i.e. only after an Hermes Reset or Init * command). - * QUESTION ;? !!!!!! should, For each of the above RIDs the Endianess is converted to native Endianess. + * QUESTION ;? !!!!!! should, For each of the above RIDs the Endianness is converted to native Endianness. * Only the return code of the first hcf_get_info is used. All hcf_get_info calls are made, regardless of * the success or failure of the 1st hcf_get_info. The assumptions are: * - if any call fails, they all fail, so remembering the result of the 1st call is adequate diff --git a/drivers/staging/wlags49_h2/hcf.h b/drivers/staging/wlags49_h2/hcf.h index 95527b5..68e2330 100644 --- a/drivers/staging/wlags49_h2/hcf.h +++ b/drivers/staging/wlags49_h2/hcf.h @@ -90,7 +90,7 @@ #define LOF(x) (sizeof(x)/sizeof(hcf_16)-1) -/* Endianess +/* Endianness * Little Endian (a.k.a. Intel), least significant byte first * Big Endian (a.k.a. Motorola), most significant byte first * @@ -101,7 +101,7 @@ */ /* To increase portability, use unsigned char and unsigned char * when accessing parts of larger - * types to convert their Endianess + * types to convert their Endianness */ #define CNV_END_SHORT(w) (hcf_16)( ((hcf_16)(w) & 0x00FF) << 8 | ((hcf_16)(w) & 0xFF00) >> 8 ) @@ -109,14 +109,14 @@ #if HCF_BIG_ENDIAN //******************************************** B I G E N D I A N ******************************************* -#define CNV_LITTLE_TO_SHORT(w) CNV_END_SHORT(w) // endianess conversion needed -#define CNV_BIG_TO_SHORT(w) (w) // no endianess conversion needed +#define CNV_LITTLE_TO_SHORT(w) CNV_END_SHORT(w) // endianness conversion needed +#define CNV_BIG_TO_SHORT(w) (w) // no endianness conversion needed #define CNV_LITTLE_TO_LONG(dw) CNV_END_LONG(dw) #define CNV_LONG_TO_LITTLE(dw) CNV_END_LONG(dw) #else //****************************************** L I T T L E E N D I A N **************************************** -#define CNV_LITTLE_TO_SHORT(w) (w) // no endianess conversion needed -#define CNV_BIG_TO_SHORT(w) CNV_END_SHORT(w) // endianess conversion needed +#define CNV_LITTLE_TO_SHORT(w) (w) // no endianness conversion needed +#define CNV_BIG_TO_SHORT(w) CNV_END_SHORT(w) // endianness conversion needed #define CNV_LITTLE_TO_LONG(dw) (dw) #define CNV_LONG_TO_LITTLE(dw) (dw) diff --git a/drivers/staging/wlags49_h2/mmd.c b/drivers/staging/wlags49_h2/mmd.c index c8f5210..7204a37 100644 --- a/drivers/staging/wlags49_h2/mmd.c +++ b/drivers/staging/wlags49_h2/mmd.c @@ -101,10 +101,10 @@ * supp address of the supplier specification * * Description: mmd_check_comp is a support routine to check the compatibility between an actor and a -* supplier. mmd_check_comp is independent of the endianess of the actp and supp structures. This is +* supplier. mmd_check_comp is independent of the endianness of the actp and supp structures. This is * achieved by checking the "bottom" or "role" fields of these structures. Since these fields are restricted * to a limited range, comparing the contents to a value with a known endian-ess gives a clue to their actual -* endianess. +* endianness. * *.DIAGRAM *1a: The role-field of the actor structure has a known non-zero, not "byte symmetric" value (namely @@ -114,16 +114,16 @@ * for a supplier. A supplier has always exactly 1 variant,top,bottom record with (officially, but see the * note below) each of these 3 values in the range 1 through 99, so one byte of the word value of variant, * top and bottom words is 0x00 and the other byte is non-zero. Whether the lowest address byte or the -* highest address byte is non-zero depends on the Endianess of the LTV. If and only if the word value of +* highest address byte is non-zero depends on the Endianness of the LTV. If and only if the word value of * bottom is less than 0x0100, the supplier is Native Endian. * NOTE: the variant field of the supplier structure can not be used for the Endian Detection Algorithm, * because a a zero-valued variant has been used as Controlled Deployment indication in the past. * Note: An actor may have multiple sets of variant,top,bottom records, including dummy sets with variant, -* top and bottom fields with a zero-value. As a consequence the endianess of the actor can not be determined +* top and bottom fields with a zero-value. As a consequence the endianness of the actor can not be determined * based on its variant,top,bottom values. * * Note: the L and T field of the structures are always in Native Endian format, so you can not draw -* conclusions concerning the Endianess of the structure based on these two fields. +* conclusions concerning the Endianness of the structure based on these two fields. * *1b/2b * The only purpose of the CFG_RANGE_SPEC_BYTE_STRCT is to give easy access to the non-zero byte of the word @@ -149,7 +149,7 @@ * * This is implemented as: * #if HCF_BIG_ENDIAN == 0 //platform is LE -* sup/act_endian becomes reverse of structure-endianess as determined in 1a/1b +* sup/act_endian becomes reverse of structure-endianness as determined in 1a/1b * #endif *6: Each of the actor variant-bottom-top records is checked against the (single) supplier variant-bottom-top * range till either an acceptable match is found or all actor records are tried. As explained above, due to -- cgit v0.10.2 From 8878451510b11ee9095198f42bf1d59e6bab66fb Mon Sep 17 00:00:00 2001 From: Johannes Thumshirn Date: Sat, 5 May 2012 16:31:50 +0200 Subject: staging: line6/midibuf.c changed printk(KERN_DEBUG, ... to pr_debug( Changed printk(KERN_DEBUG, ...) call to pr_debug call in function void line6_midibuf_status(struct MidiBuffer *this) Signed-off-by: Johannes Thumshirn Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/line6/midibuf.c b/drivers/staging/line6/midibuf.c index 7b532e5..836e8c8 100644 --- a/drivers/staging/line6/midibuf.c +++ b/drivers/staging/line6/midibuf.c @@ -64,7 +64,7 @@ int line6_midibuf_init(struct MidiBuffer *this, int size, int split) void line6_midibuf_status(struct MidiBuffer *this) { - printk(KERN_DEBUG "midibuf size=%d split=%d pos_read=%d pos_write=%d " + pr_debug("midibuf size=%d split=%d pos_read=%d pos_write=%d " "full=%d command_prev=%02x\n", this->size, this->split, this->pos_read, this->pos_write, this->full, this->command_prev); } -- cgit v0.10.2 From bc8fa144afe33bfbcae20dca4faff836ec7efedc Mon Sep 17 00:00:00 2001 From: Johannes Thumshirn Date: Sat, 5 May 2012 16:31:51 +0200 Subject: staging: line6/midi.c: Added space between switch and open parenthesis Added space between switch and open parenthesis to make checkpatch.pl happy Signed-off-by: Johannes Thumshirn Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c index 13d0293..5040729 100644 --- a/drivers/staging/line6/midi.c +++ b/drivers/staging/line6/midi.c @@ -406,7 +406,7 @@ int line6_init_midi(struct usb_line6 *line6) line6midi->line6 = line6; - switch(line6->product) { + switch (line6->product) { case LINE6_DEVID_PODHD300: case LINE6_DEVID_PODHD500: line6midi->midi_mask_transmit = 1; -- cgit v0.10.2 From 82a74d4a8022fc01b99550e4cd6b90802acd4ef9 Mon Sep 17 00:00:00 2001 From: Johannes Thumshirn Date: Sat, 5 May 2012 16:31:52 +0200 Subject: staging: line6/pcm.c: Removed trailing whitespace Removed a line of only whitespace Signed-off-by: Johannes Thumshirn Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c index 90d2d44..5e319e3 100644 --- a/drivers/staging/line6/pcm.c +++ b/drivers/staging/line6/pcm.c @@ -99,7 +99,7 @@ int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels) unsigned long flags_new = flags_old | channels; unsigned long flags_final = flags_old; int err = 0; - + line6pcm->prev_fbuf = NULL; if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_BUFFER)) { -- cgit v0.10.2 From 14fc42355f10199f39bc38dd2d3e9288a31e770c Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 8 May 2012 10:11:56 -0700 Subject: staging: Remove test of is_broadcast with is_multicast A broadcast packet is a multicast packet, no need to test twice. Reorder one defective test in rtl_core of is_multi_ether_addr before is_broadcast_ether_addr as the is_multi returns true for broadcast frames. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c index 77bb068..89ed86e 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c @@ -413,10 +413,7 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, /* Determine fragmentation size based on destination (multicast * and broadcast are not fragmented) */ -// if (is_multicast_ether_addr(dest) || -// is_broadcast_ether_addr(dest)) { - if (is_multicast_ether_addr(header.addr1) || - is_broadcast_ether_addr(header.addr1)) { + if (is_multicast_ether_addr(header.addr1)) { frag_size = MAX_FRAG_THRESHOLD; qos_ctl = QOS_CTL_NOTCONTAIN_ACK; } diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index a513ec7..fd22b75 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -2003,8 +2003,7 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, } memcpy(&dest, frag_hdr->addr1, ETH_ALEN); - if (is_multicast_ether_addr(dest) || - is_broadcast_ether_addr(dest)) { + if (is_multicast_ether_addr(dest)) { Duration = 0; RtsDur = 0; bRTSEnable = 0; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 97a5f49..4f602b2 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -2024,10 +2024,10 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb) stype = WLAN_FC_GET_STYPE(fc); pda_addr = header->addr1; - if (is_multicast_ether_addr(pda_addr)) - multi_addr = true; - else if (is_broadcast_ether_addr(pda_addr)) + if (is_broadcast_ether_addr(pda_addr)) broad_addr = true; + else if (is_multicast_ether_addr(pda_addr)) + multi_addr = true; else uni_addr = true; @@ -2358,8 +2358,7 @@ static void rtl8192_rx_normal(struct net_device *dev) stats.RxBufShift); skb_trim(skb, skb->len - 4/*sCrcLng*/); rtllib_hdr = (struct rtllib_hdr_1addr *)skb->data; - if (!is_broadcast_ether_addr(rtllib_hdr->addr1) && - !is_multicast_ether_addr(rtllib_hdr->addr1)) { + if (!is_multicast_ether_addr(rtllib_hdr->addr1)) { /* unicast packet */ unicast_packet = true; } diff --git a/drivers/staging/rtl8192e/rtl819x_TSProc.c b/drivers/staging/rtl8192e/rtl819x_TSProc.c index 711a096..658e875 100644 --- a/drivers/staging/rtl8192e/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192e/rtl819x_TSProc.c @@ -310,7 +310,7 @@ bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS, u8 *Addr, u8 TID, enum tr_select TxRxSelect, bool bAddNewTs) { u8 UP = 0; - if (is_broadcast_ether_addr(Addr) || is_multicast_ether_addr(Addr)) { + if (is_multicast_ether_addr(Addr)) { RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR! get TS for Broadcast or " "Multicast\n"); return false; diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index 40a59c9..8b8a5c6 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -1000,7 +1000,7 @@ static int rtllib_rx_data_filter(struct rtllib_device *ieee, u16 fc, return -1; /* {broad,multi}cast packets to our BSS go through */ - if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst)) { + if (is_multicast_ether_addr(dst)) { if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN)) return -1; } @@ -1269,7 +1269,7 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, sc = le16_to_cpu(hdr->seq_ctl); /*Filter pkt not to me*/ - multicast = is_multicast_ether_addr(hdr->addr1)|is_broadcast_ether_addr(hdr->addr1); + multicast = is_multicast_ether_addr(hdr->addr1); unicast = !multicast; if (unicast && (compare_ether_addr(dev->dev_addr, hdr->addr1) != 0)) { if (ieee->bNetPromiscuousMode) @@ -1350,7 +1350,7 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, /* Get TS for Rx Reorder */ hdr = (struct rtllib_hdr_4addr *) skb->data; if (ieee->current_network.qos_data.active && IsQoSDataFrame(skb->data) - && !is_multicast_ether_addr(hdr->addr1) && !is_broadcast_ether_addr(hdr->addr1) + && !is_multicast_ether_addr(hdr->addr1) && (!bToOtherSTA)) { TID = Frame_QoSTID(skb->data); SeqNum = WLAN_GET_SEQ_SEQ(sc); diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c index f24aa00c..42900ee 100644 --- a/drivers/staging/rtl8192e/rtllib_tx.c +++ b/drivers/staging/rtl8192e/rtllib_tx.c @@ -296,8 +296,7 @@ static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee, return; if (!IsQoSDataFrame(skb->data)) return; - if (is_multicast_ether_addr(hdr->addr1) || - is_broadcast_ether_addr(hdr->addr1)) + if (is_multicast_ether_addr(hdr->addr1)) return; if (tcb_desc->bdhcp || ieee->CntAfterLink < 2) @@ -515,7 +514,7 @@ u16 rtllib_query_seqnum(struct rtllib_device *ieee, struct sk_buff *skb, { u16 seqnum = 0; - if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst)) + if (is_multicast_ether_addr(dst)) return 0; if (IsQoSDataFrame(skb->data)) { struct tx_ts_record *pTS = NULL; @@ -698,8 +697,7 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) ETH_ALEN); } - bIsMulticast = is_broadcast_ether_addr(header.addr1) || - is_multicast_ether_addr(header.addr1); + bIsMulticast = is_multicast_ether_addr(header.addr1); header.frame_ctl = cpu_to_le16(fc); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index 6249c3f..e3cf7a4 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -1285,7 +1285,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, */ //added by amy for reorder if(ieee->current_network.qos_data.active && IsQoSDataFrame(skb->data) - && !is_multicast_ether_addr(hdr->addr1) && !is_broadcast_ether_addr(hdr->addr1)) + && !is_multicast_ether_addr(hdr->addr1)) { TID = Frame_QoSTID(skb->data); SeqNum = WLAN_GET_SEQ_SEQ(sc); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c index 59c45a5..3f5ceeb 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c @@ -314,7 +314,7 @@ void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* s if (!IsQoSDataFrame(skb->data)) return; - if (is_multicast_ether_addr(hdr->addr1) || is_broadcast_ether_addr(hdr->addr1)) + if (is_multicast_ether_addr(hdr->addr1)) return; //check packet and mode later #ifdef TO_DO_LIST @@ -575,7 +575,7 @@ void ieee80211_txrate_selectmode(struct ieee80211_device* ieee, cb_desc* tcb_des void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u8* dst) { - if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst)) + if (is_multicast_ether_addr(dst)) return; if (IsQoSDataFrame(skb->data)) //we deal qos data only { @@ -693,8 +693,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) /* Determine fragmentation size based on destination (multicast * and broadcast are not fragmented) */ - if (is_multicast_ether_addr(header.addr1) || - is_broadcast_ether_addr(header.addr1)) { + if (is_multicast_ether_addr(header.addr1)) { frag_size = MAX_FRAG_THRESHOLD; qos_ctl |= QOS_CTL_NOTCONTAIN_ACK; } diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c index 957ce4e..06a9824 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c @@ -350,7 +350,7 @@ bool GetTs( // We do not build any TS for Broadcast or Multicast stream. // So reject these kinds of search here. // - if(is_broadcast_ether_addr(Addr) || is_multicast_ether_addr(Addr)) + if (is_multicast_ether_addr(Addr)) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "get TS for Broadcast or Multicast\n"); return false; diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index c0edf97..e4bdf2a 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -452,7 +452,7 @@ RXbBulkInProcessData ( } } - if (!is_multicast_ether_addr(pMACHeader->abyAddr1) && !is_broadcast_ether_addr(pMACHeader->abyAddr1)) { + if (!is_multicast_ether_addr(pMACHeader->abyAddr1)) { if ( WCTLbIsDuplicate(&(pDevice->sDupRxCache), (PS802_11Header) pbyFrame) ) { pDevice->s802_11Counter.FrameDuplicateCount++; return FALSE; -- cgit v0.10.2 From 374212750b06ae2270e0e1e5843cfb33d5faf3f9 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 8 May 2012 23:04:55 +0300 Subject: mei: use pr_err instead of printk(KERN_ERR pr_ format is more compact and enable utilizing of pr_fmt macro Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 20f80df..ef5e3ec 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -1201,7 +1201,7 @@ static int __init mei_init_module(void) /* init pci module */ ret = pci_register_driver(&mei_driver); if (ret < 0) - printk(KERN_ERR "mei: Error registering driver.\n"); + pr_err("error registering driver.\n"); return ret; } -- cgit v0.10.2 From 32c826b66cc6f91831b5473a0ddceb410d4ffaf0 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 8 May 2012 23:04:56 +0300 Subject: mei: pci_probe/remove: use dev_err instead of printk(KERN_ERR Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index ef5e3ec..6510c5a 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -951,7 +951,7 @@ static int __devinit mei_probe(struct pci_dev *pdev, /* enable pci dev */ err = pci_enable_device(pdev); if (err) { - printk(KERN_ERR "mei: Failed to enable pci device.\n"); + dev_err(&pdev->dev, "failed to enable pci device.\n"); goto end; } /* set PCI host mastering */ @@ -959,7 +959,7 @@ static int __devinit mei_probe(struct pci_dev *pdev, /* pci request regions for mei driver */ err = pci_request_regions(pdev, mei_driver_name); if (err) { - printk(KERN_ERR "mei: Failed to get pci regions.\n"); + dev_err(&pdev->dev, "failed to get pci regions.\n"); goto disable_device; } /* allocates and initializes the mei dev structure */ @@ -971,7 +971,7 @@ static int __devinit mei_probe(struct pci_dev *pdev, /* mapping IO device memory */ dev->mem_addr = pci_iomap(pdev, 0, 0); if (!dev->mem_addr) { - printk(KERN_ERR "mei: mapping I/O device memory failure.\n"); + dev_err(&pdev->dev, "mapping I/O device memory failure.\n"); err = -ENOMEM; goto free_device; } @@ -990,13 +990,13 @@ static int __devinit mei_probe(struct pci_dev *pdev, IRQF_SHARED, mei_driver_name, dev); if (err) { - printk(KERN_ERR "mei: request_threaded_irq failure. irq = %d\n", + dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n", pdev->irq); goto unmap_memory; } INIT_DELAYED_WORK(&dev->timer_work, mei_timer); if (mei_hw_init(dev)) { - printk(KERN_ERR "mei: Init hw failure.\n"); + dev_err(&pdev->dev, "init hw failure.\n"); err = -ENODEV; goto release_irq; } @@ -1034,7 +1034,7 @@ disable_device: pci_disable_device(pdev); end: mutex_unlock(&mei_mutex); - printk(KERN_ERR "mei: Driver initialization failed.\n"); + dev_err(&pdev->dev, "initialization failed.\n"); return err; } @@ -1153,8 +1153,8 @@ static int mei_pci_resume(struct device *device) IRQF_SHARED, mei_driver_name, dev); if (err) { - printk(KERN_ERR "mei: Request_irq failure. irq = %d\n", - pdev->irq); + dev_err(&pdev->dev, "request_threaded_irq failed: irq = %d.\n", + pdev->irq); return err; } -- cgit v0.10.2 From b544f3fd3ac509850f8f1c28b302ae4e65b88346 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 May 2012 16:38:58 +0300 Subject: uuid: add uuid.h to exported header list uuid is used in mei.h interface Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 3c9b616..137dd4b 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -381,6 +381,7 @@ header-y += unistd.h header-y += usbdevice_fs.h header-y += utime.h header-y += utsname.h +header-y += uuid.h header-y += uvcvideo.h header-y += v4l2-mediabus.h header-y += v4l2-subdev.h diff --git a/include/linux/uuid.h b/include/linux/uuid.h index 5b7efbf..f86c37b 100644 --- a/include/linux/uuid.h +++ b/include/linux/uuid.h @@ -54,6 +54,8 @@ typedef struct { UUID_BE(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00) +#ifdef __KERNEL__ + static inline int uuid_le_cmp(const uuid_le u1, const uuid_le u2) { return memcmp(&u1, &u2, sizeof(uuid_le)); @@ -67,4 +69,6 @@ static inline int uuid_be_cmp(const uuid_be u1, const uuid_be u2) extern void uuid_le_gen(uuid_le *u); extern void uuid_be_gen(uuid_be *u); +#endif /* __KERNEL__ */ + #endif -- cgit v0.10.2 From 4f3afe1d8c8e5dc41bb5820c01b4f3cfc2dc1205 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 May 2012 16:38:59 +0300 Subject: mei: export mei.h for the user space The header exports API for application layer 1. move under include/linux and add to the export list 2. update include path n the sources 3. update TODO Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/misc/mei/TODO b/drivers/misc/mei/TODO index fc26601..ed4d16c 100644 --- a/drivers/misc/mei/TODO +++ b/drivers/misc/mei/TODO @@ -1,7 +1,6 @@ TODO: - Cleanup and split the timer function Upon Unstaging: - - move mei.h to include/linux/mei.h - Documentation/ioctl/ioctl-number.txt - move mei.txt under Documentation/mei/ - move mei-amt-version.c under Documentation/mei diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index afb0a58..a7d0bb0 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -22,7 +22,7 @@ #include "mei_dev.h" #include "hw.h" #include "interface.h" -#include "mei.h" +#include const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c index 9a2cfaf..428d21e 100644 --- a/drivers/misc/mei/interface.c +++ b/drivers/misc/mei/interface.c @@ -16,7 +16,7 @@ #include #include "mei_dev.h" -#include "mei.h" +#include #include "interface.h" diff --git a/drivers/misc/mei/interface.h b/drivers/misc/mei/interface.h index 0d00435..ddff5d1 100644 --- a/drivers/misc/mei/interface.h +++ b/drivers/misc/mei/interface.h @@ -19,7 +19,7 @@ #ifndef _MEI_INTERFACE_H_ #define _MEI_INTERFACE_H_ -#include "mei.h" +#include #include "mei_dev.h" diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 2007d24..93936f1 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -22,7 +22,7 @@ #include #include "mei_dev.h" -#include "mei.h" +#include #include "hw.h" #include "interface.h" diff --git a/drivers/misc/mei/iorw.c b/drivers/misc/mei/iorw.c index 0a80dc4..f9cced6 100644 --- a/drivers/misc/mei/iorw.c +++ b/drivers/misc/mei/iorw.c @@ -35,7 +35,7 @@ #include "mei_dev.h" #include "hw.h" -#include "mei.h" +#include #include "interface.h" diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 6510c5a..c703332 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -38,7 +38,7 @@ #include #include "mei_dev.h" -#include "mei.h" +#include #include "interface.h" static const char mei_driver_name[] = "mei"; diff --git a/drivers/misc/mei/mei-amt-version.c b/drivers/misc/mei/mei-amt-version.c index ac2a507..01804f2 100644 --- a/drivers/misc/mei/mei-amt-version.c +++ b/drivers/misc/mei/mei-amt-version.c @@ -74,7 +74,7 @@ #include #include #include -#include "mei.h" +#include /***************************************************************************** * Intel Management Engine Interface diff --git a/drivers/misc/mei/mei.h b/drivers/misc/mei/mei.h deleted file mode 100644 index bc0d8b6..0000000 --- a/drivers/misc/mei/mei.h +++ /dev/null @@ -1,110 +0,0 @@ -/****************************************************************************** - * Intel Management Engine Interface (Intel MEI) Linux driver - * Intel MEI Interface Header - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Corporation. - * linux-mei@linux.intel.com - * http://www.intel.com - * - * BSD LICENSE - * - * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ - -#ifndef _LINUX_MEI_H -#define _LINUX_MEI_H - -#include - -/* - * This IOCTL is used to associate the current file descriptor with a - * FW Client (given by UUID). This opens a communication channel - * between a host client and a FW client. From this point every read and write - * will communicate with the associated FW client. - * Only in close() (file_operation release()) the communication between - * the clients is disconnected - * - * The IOCTL argument is a struct with a union that contains - * the input parameter and the output parameter for this IOCTL. - * - * The input parameter is UUID of the FW Client. - * The output parameter is the properties of the FW client - * (FW protocol version and max message size). - * - */ -#define IOCTL_MEI_CONNECT_CLIENT \ - _IOWR('H' , 0x01, struct mei_connect_client_data) - -/* - * Intel MEI client information struct - */ -struct mei_client { - __u32 max_msg_length; - __u8 protocol_version; - __u8 reserved[3]; -}; - -/* - * IOCTL Connect Client Data structure - */ -struct mei_connect_client_data { - union { - uuid_le in_client_uuid; - struct mei_client out_client_properties; - }; -}; - -#endif /* _LINUX_MEI_H */ diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 10b1b4e..63d7ee9 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -19,7 +19,7 @@ #include #include -#include "mei.h" +#include #include "hw.h" /* diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 1e62851..6be5605 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -24,7 +24,7 @@ #include "mei_dev.h" #include "hw.h" #include "interface.h" -#include "mei.h" +#include static const u8 mei_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 }; static const u8 mei_stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 }; diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 137dd4b..b344a66 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -240,6 +240,7 @@ header-y += map_to_7segment.h header-y += matroxfb.h header-y += mdio.h header-y += media.h +header-y += mei.h header-y += mempolicy.h header-y += meye.h header-y += mii.h diff --git a/include/linux/mei.h b/include/linux/mei.h new file mode 100644 index 0000000..bc0d8b6 --- /dev/null +++ b/include/linux/mei.h @@ -0,0 +1,110 @@ +/****************************************************************************** + * Intel Management Engine Interface (Intel MEI) Linux driver + * Intel MEI Interface Header + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Corporation. + * linux-mei@linux.intel.com + * http://www.intel.com + * + * BSD LICENSE + * + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +#ifndef _LINUX_MEI_H +#define _LINUX_MEI_H + +#include + +/* + * This IOCTL is used to associate the current file descriptor with a + * FW Client (given by UUID). This opens a communication channel + * between a host client and a FW client. From this point every read and write + * will communicate with the associated FW client. + * Only in close() (file_operation release()) the communication between + * the clients is disconnected + * + * The IOCTL argument is a struct with a union that contains + * the input parameter and the output parameter for this IOCTL. + * + * The input parameter is UUID of the FW Client. + * The output parameter is the properties of the FW client + * (FW protocol version and max message size). + * + */ +#define IOCTL_MEI_CONNECT_CLIENT \ + _IOWR('H' , 0x01, struct mei_connect_client_data) + +/* + * Intel MEI client information struct + */ +struct mei_client { + __u32 max_msg_length; + __u8 protocol_version; + __u8 reserved[3]; +}; + +/* + * IOCTL Connect Client Data structure + */ +struct mei_connect_client_data { + union { + uuid_le in_client_uuid; + struct mei_client out_client_properties; + }; +}; + +#endif /* _LINUX_MEI_H */ -- cgit v0.10.2 From 5a44988207ee16b96e5445b8e95ab9881ce310cc Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 May 2012 16:39:00 +0300 Subject: mei: move doc files Documentation/misc-devices/mei 1. move mei.txt, TODO, and the example code under Documentation/misc-devices/mei 2. update the TODO file Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/Makefile b/Documentation/Makefile index 30b656e..31d302b 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -1,3 +1,3 @@ obj-m := DocBook/ accounting/ auxdisplay/ connector/ \ filesystems/ filesystems/configfs/ ia64/ laptops/ networking/ \ - pcmcia/ spi/ timers/ watchdog/src/ + pcmcia/ spi/ timers/ watchdog/src/ misc-devices/mei/ diff --git a/Documentation/misc-devices/mei/Makefile b/Documentation/misc-devices/mei/Makefile new file mode 100644 index 0000000..00e8c3e --- /dev/null +++ b/Documentation/misc-devices/mei/Makefile @@ -0,0 +1,8 @@ +# kbuild trick to avoid linker error. Can be omitted if a module is built. +obj- := dummy.o + +# List of programs to build +hostprogs-y := mei-amt-version +HOSTCFLAGS_mei-amt-version.o += -I$(objtree)/usr/include +# Tell kbuild to always build the programs +always := $(hostprogs-y) diff --git a/Documentation/misc-devices/mei/TODO b/Documentation/misc-devices/mei/TODO new file mode 100644 index 0000000..933b299 --- /dev/null +++ b/Documentation/misc-devices/mei/TODO @@ -0,0 +1,5 @@ +TODO: + - Cleanup and split the timer function +Upon Unstaging: + - Documentation/ioctl/ioctl-number.txt + - Updated MAINTAINERS diff --git a/Documentation/misc-devices/mei/mei-amt-version.c b/Documentation/misc-devices/mei/mei-amt-version.c new file mode 100644 index 0000000..01804f2 --- /dev/null +++ b/Documentation/misc-devices/mei/mei-amt-version.c @@ -0,0 +1,481 @@ +/****************************************************************************** + * Intel Management Engine Interface (Intel MEI) Linux driver + * Intel MEI Interface Header + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Corporation. + * linux-mei@linux.intel.com + * http://www.intel.com + * + * BSD LICENSE + * + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/***************************************************************************** + * Intel Management Engine Interface + *****************************************************************************/ + +#define mei_msg(_me, fmt, ARGS...) do { \ + if (_me->verbose) \ + fprintf(stderr, fmt, ##ARGS); \ +} while (0) + +#define mei_err(_me, fmt, ARGS...) do { \ + fprintf(stderr, "Error: " fmt, ##ARGS); \ +} while (0) + +struct mei { + uuid_le guid; + bool initialized; + bool verbose; + unsigned int buf_size; + unsigned char prot_ver; + int fd; +}; + +static void mei_deinit(struct mei *cl) +{ + if (cl->fd != -1) + close(cl->fd); + cl->fd = -1; + cl->buf_size = 0; + cl->prot_ver = 0; + cl->initialized = false; +} + +static bool mei_init(struct mei *me, const uuid_le *guid, + unsigned char req_protocol_version, bool verbose) +{ + int result; + struct mei_client *cl; + struct mei_connect_client_data data; + + mei_deinit(me); + + me->verbose = verbose; + + me->fd = open("/dev/mei", O_RDWR); + if (me->fd == -1) { + mei_err(me, "Cannot establish a handle to the Intel MEI driver\n"); + goto err; + } + memcpy(&me->guid, guid, sizeof(*guid)); + memset(&data, 0, sizeof(data)); + me->initialized = true; + + memcpy(&data.in_client_uuid, &me->guid, sizeof(me->guid)); + result = ioctl(me->fd, IOCTL_MEI_CONNECT_CLIENT, &data); + if (result) { + mei_err(me, "IOCTL_MEI_CONNECT_CLIENT receive message. err=%d\n", result); + goto err; + } + cl = &data.out_client_properties; + mei_msg(me, "max_message_length %d\n", cl->max_msg_length); + mei_msg(me, "protocol_version %d\n", cl->protocol_version); + + if ((req_protocol_version > 0) && + (cl->protocol_version != req_protocol_version)) { + mei_err(me, "Intel MEI protocol version not supported\n"); + goto err; + } + + me->buf_size = cl->max_msg_length; + me->prot_ver = cl->protocol_version; + + return true; +err: + mei_deinit(me); + return false; +} + +static ssize_t mei_recv_msg(struct mei *me, unsigned char *buffer, + ssize_t len, unsigned long timeout) +{ + ssize_t rc; + + mei_msg(me, "call read length = %zd\n", len); + + rc = read(me->fd, buffer, len); + if (rc < 0) { + mei_err(me, "read failed with status %zd %s\n", + rc, strerror(errno)); + mei_deinit(me); + } else { + mei_msg(me, "read succeeded with result %zd\n", rc); + } + return rc; +} + +static ssize_t mei_send_msg(struct mei *me, const unsigned char *buffer, + ssize_t len, unsigned long timeout) +{ + struct timeval tv; + ssize_t written; + ssize_t rc; + fd_set set; + + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000000; + + mei_msg(me, "call write length = %zd\n", len); + + written = write(me->fd, buffer, len); + if (written < 0) { + rc = -errno; + mei_err(me, "write failed with status %zd %s\n", + written, strerror(errno)); + goto out; + } + + FD_ZERO(&set); + FD_SET(me->fd, &set); + rc = select(me->fd + 1 , &set, NULL, NULL, &tv); + if (rc > 0 && FD_ISSET(me->fd, &set)) { + mei_msg(me, "write success\n"); + } else if (rc == 0) { + mei_err(me, "write failed on timeout with status\n"); + goto out; + } else { /* rc < 0 */ + mei_err(me, "write failed on select with status %zd\n", rc); + goto out; + } + + rc = written; +out: + if (rc < 0) + mei_deinit(me); + + return rc; +} + +/*************************************************************************** + * Intel Advanced Management Technolgy ME Client + ***************************************************************************/ + +#define AMT_MAJOR_VERSION 1 +#define AMT_MINOR_VERSION 1 + +#define AMT_STATUS_SUCCESS 0x0 +#define AMT_STATUS_INTERNAL_ERROR 0x1 +#define AMT_STATUS_NOT_READY 0x2 +#define AMT_STATUS_INVALID_AMT_MODE 0x3 +#define AMT_STATUS_INVALID_MESSAGE_LENGTH 0x4 + +#define AMT_STATUS_HOST_IF_EMPTY_RESPONSE 0x4000 +#define AMT_STATUS_SDK_RESOURCES 0x1004 + + +#define AMT_BIOS_VERSION_LEN 65 +#define AMT_VERSIONS_NUMBER 50 +#define AMT_UNICODE_STRING_LEN 20 + +struct amt_unicode_string { + uint16_t length; + char string[AMT_UNICODE_STRING_LEN]; +} __attribute__((packed)); + +struct amt_version_type { + struct amt_unicode_string description; + struct amt_unicode_string version; +} __attribute__((packed)); + +struct amt_version { + uint8_t major; + uint8_t minor; +} __attribute__((packed)); + +struct amt_code_versions { + uint8_t bios[AMT_BIOS_VERSION_LEN]; + uint32_t count; + struct amt_version_type versions[AMT_VERSIONS_NUMBER]; +} __attribute__((packed)); + +/*************************************************************************** + * Intel Advanced Management Technolgy Host Interface + ***************************************************************************/ + +struct amt_host_if_msg_header { + struct amt_version version; + uint16_t _reserved; + uint32_t command; + uint32_t length; +} __attribute__((packed)); + +struct amt_host_if_resp_header { + struct amt_host_if_msg_header header; + uint32_t status; + unsigned char data[0]; +} __attribute__((packed)); + +const uuid_le MEI_IAMTHIF = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, \ + 0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, 0x81, 0x4c); + +#define AMT_HOST_IF_CODE_VERSIONS_REQUEST 0x0400001A +#define AMT_HOST_IF_CODE_VERSIONS_RESPONSE 0x0480001A + +const struct amt_host_if_msg_header CODE_VERSION_REQ = { + .version = {AMT_MAJOR_VERSION, AMT_MINOR_VERSION}, + ._reserved = 0, + .command = AMT_HOST_IF_CODE_VERSIONS_REQUEST, + .length = 0 +}; + + +struct amt_host_if { + struct mei mei_cl; + unsigned long send_timeout; + bool initialized; +}; + + +static bool amt_host_if_init(struct amt_host_if *acmd, + unsigned long send_timeout, bool verbose) +{ + acmd->send_timeout = (send_timeout) ? send_timeout : 20000; + acmd->initialized = mei_init(&acmd->mei_cl, &MEI_IAMTHIF, 0, verbose); + return acmd->initialized; +} + +static void amt_host_if_deinit(struct amt_host_if *acmd) +{ + mei_deinit(&acmd->mei_cl); + acmd->initialized = false; +} + +static uint32_t amt_verify_code_versions(const struct amt_host_if_resp_header *resp) +{ + uint32_t status = AMT_STATUS_SUCCESS; + struct amt_code_versions *code_ver; + size_t code_ver_len; + uint32_t ver_type_cnt; + uint32_t len; + uint32_t i; + + code_ver = (struct amt_code_versions *)resp->data; + /* length - sizeof(status) */ + code_ver_len = resp->header.length - sizeof(uint32_t); + ver_type_cnt = code_ver_len - + sizeof(code_ver->bios) - + sizeof(code_ver->count); + if (code_ver->count != ver_type_cnt / sizeof(struct amt_version_type)) { + status = AMT_STATUS_INTERNAL_ERROR; + goto out; + } + + for (i = 0; i < code_ver->count; i++) { + len = code_ver->versions[i].description.length; + + if (len > AMT_UNICODE_STRING_LEN) { + status = AMT_STATUS_INTERNAL_ERROR; + goto out; + } + + len = code_ver->versions[i].version.length; + if (code_ver->versions[i].version.string[len] != '\0' || + len != strlen(code_ver->versions[i].version.string)) { + status = AMT_STATUS_INTERNAL_ERROR; + goto out; + } + } +out: + return status; +} + +static uint32_t amt_verify_response_header(uint32_t command, + const struct amt_host_if_msg_header *resp_hdr, + uint32_t response_size) +{ + if (response_size < sizeof(struct amt_host_if_resp_header)) { + return AMT_STATUS_INTERNAL_ERROR; + } else if (response_size != (resp_hdr->length + + sizeof(struct amt_host_if_msg_header))) { + return AMT_STATUS_INTERNAL_ERROR; + } else if (resp_hdr->command != command) { + return AMT_STATUS_INTERNAL_ERROR; + } else if (resp_hdr->_reserved != 0) { + return AMT_STATUS_INTERNAL_ERROR; + } else if (resp_hdr->version.major != AMT_MAJOR_VERSION || + resp_hdr->version.minor < AMT_MINOR_VERSION) { + return AMT_STATUS_INTERNAL_ERROR; + } + return AMT_STATUS_SUCCESS; +} + +static uint32_t amt_host_if_call(struct amt_host_if *acmd, + const unsigned char *command, ssize_t command_sz, + uint8_t **read_buf, uint32_t rcmd, + unsigned int expected_sz) +{ + uint32_t in_buf_sz; + uint32_t out_buf_sz; + ssize_t written; + uint32_t status; + struct amt_host_if_resp_header *msg_hdr; + + in_buf_sz = acmd->mei_cl.buf_size; + *read_buf = (uint8_t *)malloc(sizeof(uint8_t) * in_buf_sz); + if (*read_buf == NULL) + return AMT_STATUS_SDK_RESOURCES; + memset(*read_buf, 0, in_buf_sz); + msg_hdr = (struct amt_host_if_resp_header *)*read_buf; + + written = mei_send_msg(&acmd->mei_cl, + command, command_sz, acmd->send_timeout); + if (written != command_sz) + return AMT_STATUS_INTERNAL_ERROR; + + out_buf_sz = mei_recv_msg(&acmd->mei_cl, *read_buf, in_buf_sz, 2000); + if (out_buf_sz <= 0) + return AMT_STATUS_HOST_IF_EMPTY_RESPONSE; + + status = msg_hdr->status; + if (status != AMT_STATUS_SUCCESS) + return status; + + status = amt_verify_response_header(rcmd, + &msg_hdr->header, out_buf_sz); + if (status != AMT_STATUS_SUCCESS) + return status; + + if (expected_sz && expected_sz != out_buf_sz) + return AMT_STATUS_INTERNAL_ERROR; + + return AMT_STATUS_SUCCESS; +} + + +static uint32_t amt_get_code_versions(struct amt_host_if *cmd, + struct amt_code_versions *versions) +{ + struct amt_host_if_resp_header *response = NULL; + uint32_t status; + + status = amt_host_if_call(cmd, + (const unsigned char *)&CODE_VERSION_REQ, + sizeof(CODE_VERSION_REQ), + (uint8_t **)&response, + AMT_HOST_IF_CODE_VERSIONS_RESPONSE, 0); + + if (status != AMT_STATUS_SUCCESS) + goto out; + + status = amt_verify_code_versions(response); + if (status != AMT_STATUS_SUCCESS) + goto out; + + memcpy(versions, response->data, sizeof(struct amt_code_versions)); +out: + if (response != NULL) + free(response); + + return status; +} + +/************************** end of amt_host_if_command ***********************/ +int main(int argc, char **argv) +{ + struct amt_code_versions ver; + struct amt_host_if acmd; + unsigned int i; + uint32_t status; + int ret; + bool verbose; + + verbose = (argc > 1 && strcmp(argv[1], "-v") == 0); + + if (!amt_host_if_init(&acmd, 5000, verbose)) { + ret = 1; + goto out; + } + + status = amt_get_code_versions(&acmd, &ver); + + amt_host_if_deinit(&acmd); + + switch (status) { + case AMT_STATUS_HOST_IF_EMPTY_RESPONSE: + printf("Intel AMT: DISABLED\n"); + ret = 0; + break; + case AMT_STATUS_SUCCESS: + printf("Intel AMT: ENABLED\n"); + for (i = 0; i < ver.count; i++) { + printf("%s:\t%s\n", ver.versions[i].description.string, + ver.versions[i].version.string); + } + ret = 0; + break; + default: + printf("An error has occurred\n"); + ret = 1; + break; + } + +out: + return ret; +} diff --git a/Documentation/misc-devices/mei/mei.txt b/Documentation/misc-devices/mei/mei.txt new file mode 100644 index 0000000..2785697 --- /dev/null +++ b/Documentation/misc-devices/mei/mei.txt @@ -0,0 +1,215 @@ +Intel(R) Management Engine Interface (Intel(R) MEI) +======================= + +Introduction +======================= + +The Intel Management Engine (Intel ME) is an isolated and protected computing +resource (Co-processor) residing inside certain Intel chipsets. The Intel ME +provides support for computer/IT management features. The feature set +depends on the Intel chipset SKU. + +The Intel Management Engine Interface (Intel MEI, previously known as HECI) +is the interface between the Host and Intel ME. This interface is exposed +to the host as a PCI device. The Intel MEI Driver is in charge of the +communication channel between a host application and the Intel ME feature. + +Each Intel ME feature (Intel ME Client) is addressed by a GUID/UUID and +each client has its own protocol. The protocol is message-based with a +header and payload up to 512 bytes. + +Prominent usage of the Intel ME Interface is to communicate with Intel(R) +Active Management Technology (Intel AMT)implemented in firmware running on +the Intel ME. + +Intel AMT provides the ability to manage a host remotely out-of-band (OOB) +even when the operating system running on the host processor has crashed or +is in a sleep state. + +Some examples of Intel AMT usage are: + - Monitoring hardware state and platform components + - Remote power off/on (useful for green computing or overnight IT + maintenance) + - OS updates + - Storage of useful platform information such as software assets + - Built-in hardware KVM + - Selective network isolation of Ethernet and IP protocol flows based + on policies set by a remote management console + - IDE device redirection from remote management console + +Intel AMT (OOB) communication is based on SOAP (deprecated +starting with Release 6.0) over HTTP/S or WS-Management protocol over +HTTP/S that are received from a remote management console application. + +For more information about Intel AMT: +http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide + +Intel MEI Driver +======================= + +The driver exposes a misc device called /dev/mei. + +An application maintains communication with an Intel ME feature while +/dev/mei is open. The binding to a specific features is performed by calling +MEI_CONNECT_CLIENT_IOCTL, which passes the desired UUID. +The number of instances of an Intel ME feature that can be opened +at the same time depends on the Intel ME feature, but most of the +features allow only a single instance. + +The Intel AMT Host Interface (Intel AMTHI) feature supports multiple +simultaneous user applications. Therefore, the Intel MEI driver handles +this internally by maintaining request queues for the applications. + +The driver is oblivious to data that is passed between firmware feature +and host application. + +Because some of the Intel ME features can change the system +configuration, the driver by default allows only a privileged +user to access it. + +A code snippet for an application communicating with +Intel AMTHI client: + struct mei_connect_client_data data; + fd = open(MEI_DEVICE); + + data.d.in_client_uuid = AMTHI_UUID; + + ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &data); + + printf("Ver=%d, MaxLen=%ld\n", + data.d.in_client_uuid.protocol_version, + data.d.in_client_uuid.max_msg_length); + + [...] + + write(fd, amthi_req_data, amthi_req_data_len); + + [...] + + read(fd, &amthi_res_data, amthi_res_data_len); + + [...] + close(fd); + +IOCTL: +====== +The Intel MEI Driver supports the following IOCTL command: + IOCTL_MEI_CONNECT_CLIENT Connect to firmware Feature (client). + + usage: + struct mei_connect_client_data clientData; + ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &clientData); + + inputs: + mei_connect_client_data struct contain the following + input field: + + in_client_uuid - UUID of the FW Feature that needs + to connect to. + outputs: + out_client_properties - Client Properties: MTU and Protocol Version. + + error returns: + EINVAL Wrong IOCTL Number + ENODEV Device or Connection is not initialized or ready. + (e.g. Wrong UUID) + ENOMEM Unable to allocate memory to client internal data. + EFAULT Fatal Error (e.g. Unable to access user input data) + EBUSY Connection Already Open + + Notes: + max_msg_length (MTU) in client properties describes the maximum + data that can be sent or received. (e.g. if MTU=2K, can send + requests up to bytes 2k and received responses upto 2k bytes). + +Intel ME Applications: +============== + +1) Intel Local Management Service (Intel LMS) + + Applications running locally on the platform communicate with Intel AMT Release + 2.0 and later releases in the same way that network applications do via SOAP + over HTTP (deprecated starting with Release 6.0) or with WS-Management over + SOAP over HTTP. This means that some Intel AMT features can be accessed from a + local application using the same network interface as a remote application + communicating with Intel AMT over the network. + + When a local application sends a message addressed to the local Intel AMT host + name, the Intel LMS, which listens for traffic directed to the host name, + intercepts the message and routes it to the Intel MEI. + For more information: + http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide + Under "About Intel AMT" => "Local Access" + + For downloading Intel LMS: + http://software.intel.com/en-us/articles/download-the-latest-intel-amt-open-source-drivers/ + + The Intel LMS opens a connection using the Intel MEI driver to the Intel LMS + firmware feature using a defined UUID and then communicates with the feature + using a protocol called Intel AMT Port Forwarding Protocol(Intel APF protocol). + The protocol is used to maintain multiple sessions with Intel AMT from a + single application. + + See the protocol specification in the Intel AMT Software Development Kit(SDK) + http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide + Under "SDK Resources" => "Intel(R) vPro(TM) Gateway(MPS)" + => "Information for Intel(R) vPro(TM) Gateway Developers" + => "Description of the Intel AMT Port Forwarding (APF)Protocol" + + 2) Intel AMT Remote configuration using a Local Agent + A Local Agent enables IT personnel to configure Intel AMT out-of-the-box + without requiring installing additional data to enable setup. The remote + configuration process may involve an ISV-developed remote configuration + agent that runs on the host. + For more information: + http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide + Under "Setup and Configuration of Intel AMT" => + "SDK Tools Supporting Setup and Configuration" => + "Using the Local Agent Sample" + + An open source Intel AMT configuration utility, implementing a local agent + that accesses the Intel MEI driver, can be found here: + http://software.intel.com/en-us/articles/download-the-latest-intel-amt-open-source-drivers/ + + +Intel AMT OS Health Watchdog: +============================= +The Intel AMT Watchdog is an OS Health (Hang/Crash) watchdog. +Whenever the OS hangs or crashes, Intel AMT will send an event +to any subscriber to this event. This mechanism means that +IT knows when a platform crashes even when there is a hard failure on the host. + +The Intel AMT Watchdog is composed of two parts: + 1) Firmware feature - receives the heartbeats + and sends an event when the heartbeats stop. + 2) Intel MEI driver - connects to the watchdog feature, configures the + watchdog and sends the heartbeats. + +The Intel MEI driver uses the kernel watchdog to configure the Intel AMT +Watchdog and to send heartbeats to it. The default timeout of the +watchdog is 120 seconds. + +If the Intel AMT Watchdog feature does not exist (i.e. the connection failed), +the Intel MEI driver will disable the sending of heartbeats. + +Supported Chipsets: +================== +7 Series Chipset Family +6 Series Chipset Family +5 Series Chipset Family +4 Series Chipset Family +Mobile 4 Series Chipset Family +ICH9 +82946GZ/GL +82G35 Express +82Q963/Q965 +82P965/G965 +Mobile PM965/GM965 +Mobile GME965/GLE960 +82Q35 Express +82G33/G31/P35/P31 Express +82Q33 Express +82X38/X48 Express + +--- +linux-mei@linux.intel.com diff --git a/drivers/misc/mei/TODO b/drivers/misc/mei/TODO deleted file mode 100644 index ed4d16c..0000000 --- a/drivers/misc/mei/TODO +++ /dev/null @@ -1,9 +0,0 @@ -TODO: - - Cleanup and split the timer function -Upon Unstaging: - - Documentation/ioctl/ioctl-number.txt - - move mei.txt under Documentation/mei/ - - move mei-amt-version.c under Documentation/mei - - add hostprogs-y for mei-amt-version.c - - drop mei_version.h - - Updated MAINTAINERS diff --git a/drivers/misc/mei/mei-amt-version.c b/drivers/misc/mei/mei-amt-version.c deleted file mode 100644 index 01804f2..0000000 --- a/drivers/misc/mei/mei-amt-version.c +++ /dev/null @@ -1,481 +0,0 @@ -/****************************************************************************** - * Intel Management Engine Interface (Intel MEI) Linux driver - * Intel MEI Interface Header - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2012 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Corporation. - * linux-mei@linux.intel.com - * http://www.intel.com - * - * BSD LICENSE - * - * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/***************************************************************************** - * Intel Management Engine Interface - *****************************************************************************/ - -#define mei_msg(_me, fmt, ARGS...) do { \ - if (_me->verbose) \ - fprintf(stderr, fmt, ##ARGS); \ -} while (0) - -#define mei_err(_me, fmt, ARGS...) do { \ - fprintf(stderr, "Error: " fmt, ##ARGS); \ -} while (0) - -struct mei { - uuid_le guid; - bool initialized; - bool verbose; - unsigned int buf_size; - unsigned char prot_ver; - int fd; -}; - -static void mei_deinit(struct mei *cl) -{ - if (cl->fd != -1) - close(cl->fd); - cl->fd = -1; - cl->buf_size = 0; - cl->prot_ver = 0; - cl->initialized = false; -} - -static bool mei_init(struct mei *me, const uuid_le *guid, - unsigned char req_protocol_version, bool verbose) -{ - int result; - struct mei_client *cl; - struct mei_connect_client_data data; - - mei_deinit(me); - - me->verbose = verbose; - - me->fd = open("/dev/mei", O_RDWR); - if (me->fd == -1) { - mei_err(me, "Cannot establish a handle to the Intel MEI driver\n"); - goto err; - } - memcpy(&me->guid, guid, sizeof(*guid)); - memset(&data, 0, sizeof(data)); - me->initialized = true; - - memcpy(&data.in_client_uuid, &me->guid, sizeof(me->guid)); - result = ioctl(me->fd, IOCTL_MEI_CONNECT_CLIENT, &data); - if (result) { - mei_err(me, "IOCTL_MEI_CONNECT_CLIENT receive message. err=%d\n", result); - goto err; - } - cl = &data.out_client_properties; - mei_msg(me, "max_message_length %d\n", cl->max_msg_length); - mei_msg(me, "protocol_version %d\n", cl->protocol_version); - - if ((req_protocol_version > 0) && - (cl->protocol_version != req_protocol_version)) { - mei_err(me, "Intel MEI protocol version not supported\n"); - goto err; - } - - me->buf_size = cl->max_msg_length; - me->prot_ver = cl->protocol_version; - - return true; -err: - mei_deinit(me); - return false; -} - -static ssize_t mei_recv_msg(struct mei *me, unsigned char *buffer, - ssize_t len, unsigned long timeout) -{ - ssize_t rc; - - mei_msg(me, "call read length = %zd\n", len); - - rc = read(me->fd, buffer, len); - if (rc < 0) { - mei_err(me, "read failed with status %zd %s\n", - rc, strerror(errno)); - mei_deinit(me); - } else { - mei_msg(me, "read succeeded with result %zd\n", rc); - } - return rc; -} - -static ssize_t mei_send_msg(struct mei *me, const unsigned char *buffer, - ssize_t len, unsigned long timeout) -{ - struct timeval tv; - ssize_t written; - ssize_t rc; - fd_set set; - - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000000; - - mei_msg(me, "call write length = %zd\n", len); - - written = write(me->fd, buffer, len); - if (written < 0) { - rc = -errno; - mei_err(me, "write failed with status %zd %s\n", - written, strerror(errno)); - goto out; - } - - FD_ZERO(&set); - FD_SET(me->fd, &set); - rc = select(me->fd + 1 , &set, NULL, NULL, &tv); - if (rc > 0 && FD_ISSET(me->fd, &set)) { - mei_msg(me, "write success\n"); - } else if (rc == 0) { - mei_err(me, "write failed on timeout with status\n"); - goto out; - } else { /* rc < 0 */ - mei_err(me, "write failed on select with status %zd\n", rc); - goto out; - } - - rc = written; -out: - if (rc < 0) - mei_deinit(me); - - return rc; -} - -/*************************************************************************** - * Intel Advanced Management Technolgy ME Client - ***************************************************************************/ - -#define AMT_MAJOR_VERSION 1 -#define AMT_MINOR_VERSION 1 - -#define AMT_STATUS_SUCCESS 0x0 -#define AMT_STATUS_INTERNAL_ERROR 0x1 -#define AMT_STATUS_NOT_READY 0x2 -#define AMT_STATUS_INVALID_AMT_MODE 0x3 -#define AMT_STATUS_INVALID_MESSAGE_LENGTH 0x4 - -#define AMT_STATUS_HOST_IF_EMPTY_RESPONSE 0x4000 -#define AMT_STATUS_SDK_RESOURCES 0x1004 - - -#define AMT_BIOS_VERSION_LEN 65 -#define AMT_VERSIONS_NUMBER 50 -#define AMT_UNICODE_STRING_LEN 20 - -struct amt_unicode_string { - uint16_t length; - char string[AMT_UNICODE_STRING_LEN]; -} __attribute__((packed)); - -struct amt_version_type { - struct amt_unicode_string description; - struct amt_unicode_string version; -} __attribute__((packed)); - -struct amt_version { - uint8_t major; - uint8_t minor; -} __attribute__((packed)); - -struct amt_code_versions { - uint8_t bios[AMT_BIOS_VERSION_LEN]; - uint32_t count; - struct amt_version_type versions[AMT_VERSIONS_NUMBER]; -} __attribute__((packed)); - -/*************************************************************************** - * Intel Advanced Management Technolgy Host Interface - ***************************************************************************/ - -struct amt_host_if_msg_header { - struct amt_version version; - uint16_t _reserved; - uint32_t command; - uint32_t length; -} __attribute__((packed)); - -struct amt_host_if_resp_header { - struct amt_host_if_msg_header header; - uint32_t status; - unsigned char data[0]; -} __attribute__((packed)); - -const uuid_le MEI_IAMTHIF = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, \ - 0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, 0x81, 0x4c); - -#define AMT_HOST_IF_CODE_VERSIONS_REQUEST 0x0400001A -#define AMT_HOST_IF_CODE_VERSIONS_RESPONSE 0x0480001A - -const struct amt_host_if_msg_header CODE_VERSION_REQ = { - .version = {AMT_MAJOR_VERSION, AMT_MINOR_VERSION}, - ._reserved = 0, - .command = AMT_HOST_IF_CODE_VERSIONS_REQUEST, - .length = 0 -}; - - -struct amt_host_if { - struct mei mei_cl; - unsigned long send_timeout; - bool initialized; -}; - - -static bool amt_host_if_init(struct amt_host_if *acmd, - unsigned long send_timeout, bool verbose) -{ - acmd->send_timeout = (send_timeout) ? send_timeout : 20000; - acmd->initialized = mei_init(&acmd->mei_cl, &MEI_IAMTHIF, 0, verbose); - return acmd->initialized; -} - -static void amt_host_if_deinit(struct amt_host_if *acmd) -{ - mei_deinit(&acmd->mei_cl); - acmd->initialized = false; -} - -static uint32_t amt_verify_code_versions(const struct amt_host_if_resp_header *resp) -{ - uint32_t status = AMT_STATUS_SUCCESS; - struct amt_code_versions *code_ver; - size_t code_ver_len; - uint32_t ver_type_cnt; - uint32_t len; - uint32_t i; - - code_ver = (struct amt_code_versions *)resp->data; - /* length - sizeof(status) */ - code_ver_len = resp->header.length - sizeof(uint32_t); - ver_type_cnt = code_ver_len - - sizeof(code_ver->bios) - - sizeof(code_ver->count); - if (code_ver->count != ver_type_cnt / sizeof(struct amt_version_type)) { - status = AMT_STATUS_INTERNAL_ERROR; - goto out; - } - - for (i = 0; i < code_ver->count; i++) { - len = code_ver->versions[i].description.length; - - if (len > AMT_UNICODE_STRING_LEN) { - status = AMT_STATUS_INTERNAL_ERROR; - goto out; - } - - len = code_ver->versions[i].version.length; - if (code_ver->versions[i].version.string[len] != '\0' || - len != strlen(code_ver->versions[i].version.string)) { - status = AMT_STATUS_INTERNAL_ERROR; - goto out; - } - } -out: - return status; -} - -static uint32_t amt_verify_response_header(uint32_t command, - const struct amt_host_if_msg_header *resp_hdr, - uint32_t response_size) -{ - if (response_size < sizeof(struct amt_host_if_resp_header)) { - return AMT_STATUS_INTERNAL_ERROR; - } else if (response_size != (resp_hdr->length + - sizeof(struct amt_host_if_msg_header))) { - return AMT_STATUS_INTERNAL_ERROR; - } else if (resp_hdr->command != command) { - return AMT_STATUS_INTERNAL_ERROR; - } else if (resp_hdr->_reserved != 0) { - return AMT_STATUS_INTERNAL_ERROR; - } else if (resp_hdr->version.major != AMT_MAJOR_VERSION || - resp_hdr->version.minor < AMT_MINOR_VERSION) { - return AMT_STATUS_INTERNAL_ERROR; - } - return AMT_STATUS_SUCCESS; -} - -static uint32_t amt_host_if_call(struct amt_host_if *acmd, - const unsigned char *command, ssize_t command_sz, - uint8_t **read_buf, uint32_t rcmd, - unsigned int expected_sz) -{ - uint32_t in_buf_sz; - uint32_t out_buf_sz; - ssize_t written; - uint32_t status; - struct amt_host_if_resp_header *msg_hdr; - - in_buf_sz = acmd->mei_cl.buf_size; - *read_buf = (uint8_t *)malloc(sizeof(uint8_t) * in_buf_sz); - if (*read_buf == NULL) - return AMT_STATUS_SDK_RESOURCES; - memset(*read_buf, 0, in_buf_sz); - msg_hdr = (struct amt_host_if_resp_header *)*read_buf; - - written = mei_send_msg(&acmd->mei_cl, - command, command_sz, acmd->send_timeout); - if (written != command_sz) - return AMT_STATUS_INTERNAL_ERROR; - - out_buf_sz = mei_recv_msg(&acmd->mei_cl, *read_buf, in_buf_sz, 2000); - if (out_buf_sz <= 0) - return AMT_STATUS_HOST_IF_EMPTY_RESPONSE; - - status = msg_hdr->status; - if (status != AMT_STATUS_SUCCESS) - return status; - - status = amt_verify_response_header(rcmd, - &msg_hdr->header, out_buf_sz); - if (status != AMT_STATUS_SUCCESS) - return status; - - if (expected_sz && expected_sz != out_buf_sz) - return AMT_STATUS_INTERNAL_ERROR; - - return AMT_STATUS_SUCCESS; -} - - -static uint32_t amt_get_code_versions(struct amt_host_if *cmd, - struct amt_code_versions *versions) -{ - struct amt_host_if_resp_header *response = NULL; - uint32_t status; - - status = amt_host_if_call(cmd, - (const unsigned char *)&CODE_VERSION_REQ, - sizeof(CODE_VERSION_REQ), - (uint8_t **)&response, - AMT_HOST_IF_CODE_VERSIONS_RESPONSE, 0); - - if (status != AMT_STATUS_SUCCESS) - goto out; - - status = amt_verify_code_versions(response); - if (status != AMT_STATUS_SUCCESS) - goto out; - - memcpy(versions, response->data, sizeof(struct amt_code_versions)); -out: - if (response != NULL) - free(response); - - return status; -} - -/************************** end of amt_host_if_command ***********************/ -int main(int argc, char **argv) -{ - struct amt_code_versions ver; - struct amt_host_if acmd; - unsigned int i; - uint32_t status; - int ret; - bool verbose; - - verbose = (argc > 1 && strcmp(argv[1], "-v") == 0); - - if (!amt_host_if_init(&acmd, 5000, verbose)) { - ret = 1; - goto out; - } - - status = amt_get_code_versions(&acmd, &ver); - - amt_host_if_deinit(&acmd); - - switch (status) { - case AMT_STATUS_HOST_IF_EMPTY_RESPONSE: - printf("Intel AMT: DISABLED\n"); - ret = 0; - break; - case AMT_STATUS_SUCCESS: - printf("Intel AMT: ENABLED\n"); - for (i = 0; i < ver.count; i++) { - printf("%s:\t%s\n", ver.versions[i].description.string, - ver.versions[i].version.string); - } - ret = 0; - break; - default: - printf("An error has occurred\n"); - ret = 1; - break; - } - -out: - return ret; -} diff --git a/drivers/misc/mei/mei.txt b/drivers/misc/mei/mei.txt deleted file mode 100644 index 2785697..0000000 --- a/drivers/misc/mei/mei.txt +++ /dev/null @@ -1,215 +0,0 @@ -Intel(R) Management Engine Interface (Intel(R) MEI) -======================= - -Introduction -======================= - -The Intel Management Engine (Intel ME) is an isolated and protected computing -resource (Co-processor) residing inside certain Intel chipsets. The Intel ME -provides support for computer/IT management features. The feature set -depends on the Intel chipset SKU. - -The Intel Management Engine Interface (Intel MEI, previously known as HECI) -is the interface between the Host and Intel ME. This interface is exposed -to the host as a PCI device. The Intel MEI Driver is in charge of the -communication channel between a host application and the Intel ME feature. - -Each Intel ME feature (Intel ME Client) is addressed by a GUID/UUID and -each client has its own protocol. The protocol is message-based with a -header and payload up to 512 bytes. - -Prominent usage of the Intel ME Interface is to communicate with Intel(R) -Active Management Technology (Intel AMT)implemented in firmware running on -the Intel ME. - -Intel AMT provides the ability to manage a host remotely out-of-band (OOB) -even when the operating system running on the host processor has crashed or -is in a sleep state. - -Some examples of Intel AMT usage are: - - Monitoring hardware state and platform components - - Remote power off/on (useful for green computing or overnight IT - maintenance) - - OS updates - - Storage of useful platform information such as software assets - - Built-in hardware KVM - - Selective network isolation of Ethernet and IP protocol flows based - on policies set by a remote management console - - IDE device redirection from remote management console - -Intel AMT (OOB) communication is based on SOAP (deprecated -starting with Release 6.0) over HTTP/S or WS-Management protocol over -HTTP/S that are received from a remote management console application. - -For more information about Intel AMT: -http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide - -Intel MEI Driver -======================= - -The driver exposes a misc device called /dev/mei. - -An application maintains communication with an Intel ME feature while -/dev/mei is open. The binding to a specific features is performed by calling -MEI_CONNECT_CLIENT_IOCTL, which passes the desired UUID. -The number of instances of an Intel ME feature that can be opened -at the same time depends on the Intel ME feature, but most of the -features allow only a single instance. - -The Intel AMT Host Interface (Intel AMTHI) feature supports multiple -simultaneous user applications. Therefore, the Intel MEI driver handles -this internally by maintaining request queues for the applications. - -The driver is oblivious to data that is passed between firmware feature -and host application. - -Because some of the Intel ME features can change the system -configuration, the driver by default allows only a privileged -user to access it. - -A code snippet for an application communicating with -Intel AMTHI client: - struct mei_connect_client_data data; - fd = open(MEI_DEVICE); - - data.d.in_client_uuid = AMTHI_UUID; - - ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &data); - - printf("Ver=%d, MaxLen=%ld\n", - data.d.in_client_uuid.protocol_version, - data.d.in_client_uuid.max_msg_length); - - [...] - - write(fd, amthi_req_data, amthi_req_data_len); - - [...] - - read(fd, &amthi_res_data, amthi_res_data_len); - - [...] - close(fd); - -IOCTL: -====== -The Intel MEI Driver supports the following IOCTL command: - IOCTL_MEI_CONNECT_CLIENT Connect to firmware Feature (client). - - usage: - struct mei_connect_client_data clientData; - ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &clientData); - - inputs: - mei_connect_client_data struct contain the following - input field: - - in_client_uuid - UUID of the FW Feature that needs - to connect to. - outputs: - out_client_properties - Client Properties: MTU and Protocol Version. - - error returns: - EINVAL Wrong IOCTL Number - ENODEV Device or Connection is not initialized or ready. - (e.g. Wrong UUID) - ENOMEM Unable to allocate memory to client internal data. - EFAULT Fatal Error (e.g. Unable to access user input data) - EBUSY Connection Already Open - - Notes: - max_msg_length (MTU) in client properties describes the maximum - data that can be sent or received. (e.g. if MTU=2K, can send - requests up to bytes 2k and received responses upto 2k bytes). - -Intel ME Applications: -============== - -1) Intel Local Management Service (Intel LMS) - - Applications running locally on the platform communicate with Intel AMT Release - 2.0 and later releases in the same way that network applications do via SOAP - over HTTP (deprecated starting with Release 6.0) or with WS-Management over - SOAP over HTTP. This means that some Intel AMT features can be accessed from a - local application using the same network interface as a remote application - communicating with Intel AMT over the network. - - When a local application sends a message addressed to the local Intel AMT host - name, the Intel LMS, which listens for traffic directed to the host name, - intercepts the message and routes it to the Intel MEI. - For more information: - http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide - Under "About Intel AMT" => "Local Access" - - For downloading Intel LMS: - http://software.intel.com/en-us/articles/download-the-latest-intel-amt-open-source-drivers/ - - The Intel LMS opens a connection using the Intel MEI driver to the Intel LMS - firmware feature using a defined UUID and then communicates with the feature - using a protocol called Intel AMT Port Forwarding Protocol(Intel APF protocol). - The protocol is used to maintain multiple sessions with Intel AMT from a - single application. - - See the protocol specification in the Intel AMT Software Development Kit(SDK) - http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide - Under "SDK Resources" => "Intel(R) vPro(TM) Gateway(MPS)" - => "Information for Intel(R) vPro(TM) Gateway Developers" - => "Description of the Intel AMT Port Forwarding (APF)Protocol" - - 2) Intel AMT Remote configuration using a Local Agent - A Local Agent enables IT personnel to configure Intel AMT out-of-the-box - without requiring installing additional data to enable setup. The remote - configuration process may involve an ISV-developed remote configuration - agent that runs on the host. - For more information: - http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide - Under "Setup and Configuration of Intel AMT" => - "SDK Tools Supporting Setup and Configuration" => - "Using the Local Agent Sample" - - An open source Intel AMT configuration utility, implementing a local agent - that accesses the Intel MEI driver, can be found here: - http://software.intel.com/en-us/articles/download-the-latest-intel-amt-open-source-drivers/ - - -Intel AMT OS Health Watchdog: -============================= -The Intel AMT Watchdog is an OS Health (Hang/Crash) watchdog. -Whenever the OS hangs or crashes, Intel AMT will send an event -to any subscriber to this event. This mechanism means that -IT knows when a platform crashes even when there is a hard failure on the host. - -The Intel AMT Watchdog is composed of two parts: - 1) Firmware feature - receives the heartbeats - and sends an event when the heartbeats stop. - 2) Intel MEI driver - connects to the watchdog feature, configures the - watchdog and sends the heartbeats. - -The Intel MEI driver uses the kernel watchdog to configure the Intel AMT -Watchdog and to send heartbeats to it. The default timeout of the -watchdog is 120 seconds. - -If the Intel AMT Watchdog feature does not exist (i.e. the connection failed), -the Intel MEI driver will disable the sending of heartbeats. - -Supported Chipsets: -================== -7 Series Chipset Family -6 Series Chipset Family -5 Series Chipset Family -4 Series Chipset Family -Mobile 4 Series Chipset Family -ICH9 -82946GZ/GL -82G35 Express -82Q963/Q965 -82P965/G965 -Mobile PM965/GM965 -Mobile GME965/GLE960 -82Q35 Express -82G33/G31/P35/P31 Express -82Q33 Express -82X38/X48 Express - ---- -linux-mei@linux.intel.com -- cgit v0.10.2 From 4cd7a7e72e929cfe29c247293957848bc6874720 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 May 2012 16:39:01 +0300 Subject: mei: update Documentation/ioctl/ioctl-number.txt Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt index e34b531d..915f28c 100644 --- a/Documentation/ioctl/ioctl-number.txt +++ b/Documentation/ioctl/ioctl-number.txt @@ -120,6 +120,7 @@ Code Seq#(hex) Include File Comments 'G' 00-0F linux/gigaset_dev.h conflict! 'H' 00-7F linux/hiddev.h conflict! 'H' 00-0F linux/hidraw.h conflict! +'H' 01 linux/mei.h conflict! 'H' 00-0F sound/asound.h conflict! 'H' 20-40 sound/asound_fm.h conflict! 'H' 80-8F sound/sfnt_info.h conflict! diff --git a/Documentation/misc-devices/mei/TODO b/Documentation/misc-devices/mei/TODO index 933b299..286fabf 100644 --- a/Documentation/misc-devices/mei/TODO +++ b/Documentation/misc-devices/mei/TODO @@ -1,5 +1,4 @@ TODO: - Cleanup and split the timer function Upon Unstaging: - - Documentation/ioctl/ioctl-number.txt - Updated MAINTAINERS -- cgit v0.10.2 From de8fe0233f078e649d7c293218119234606c4546 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 May 2012 16:39:02 +0300 Subject: mei: update MAINTAINERS file Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/misc-devices/mei/TODO b/Documentation/misc-devices/mei/TODO index 286fabf..6b3625d 100644 --- a/Documentation/misc-devices/mei/TODO +++ b/Documentation/misc-devices/mei/TODO @@ -1,4 +1,2 @@ TODO: - Cleanup and split the timer function -Upon Unstaging: - - Updated MAINTAINERS diff --git a/MAINTAINERS b/MAINTAINERS index 4e8ace8..7c10c19 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3610,6 +3610,14 @@ S: Supported W: http://wireless.kernel.org/en/users/Drivers/iwmc3200wifi F: drivers/net/wireless/iwmc3200wifi/ +INTEL MANAGEMENT ENGINE (mei) +M: Tomas Winkler +L: linux-kernel@vger.kernel.org +S: Supported +F: include/linux/mei.h +F: drivers/misc/mei/* +F: Documentation/mei/* + IOC3 ETHERNET DRIVER M: Ralf Baechle L: linux-mips@linux-mips.org -- cgit v0.10.2 From d3465872c5b38613fb5ad10a9756db9372630b22 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Wed, 9 May 2012 15:27:19 +0200 Subject: Staging: IndustryPack bus for the Linux Kernel Add IndustryPack bus support for the Linux Kernel. This is a virtual bus that allows to perform all the operations between carrier and mezzanine boards. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 32b02e4..781cb98 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -24,6 +24,8 @@ menuconfig STAGING if STAGING +source "drivers/staging/ipack/Kconfig" + source "drivers/staging/et131x/Kconfig" source "drivers/staging/slicoss/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index e603c07..fd8b7ce3 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_OCTEON_ETHERNET) += octeon/ obj-$(CONFIG_VT6655) += vt6655/ obj-$(CONFIG_VT6656) += vt6656/ obj-$(CONFIG_VME_BUS) += vme/ +obj-$(CONFIG_IPACK_BUS) += ipack/ obj-$(CONFIG_DX_SEP) += sep/ obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_ZRAM) += zram/ diff --git a/drivers/staging/ipack/Kconfig b/drivers/staging/ipack/Kconfig new file mode 100644 index 0000000..e20187f --- /dev/null +++ b/drivers/staging/ipack/Kconfig @@ -0,0 +1,9 @@ +# +# IPACK configuration. +# + +menuconfig IPACK_BUS + tristate "IndustryPack bus support" + ---help--- + If you say Y here you get support for the IndustryPack Framework. + diff --git a/drivers/staging/ipack/Makefile b/drivers/staging/ipack/Makefile new file mode 100644 index 0000000..56e2340 --- /dev/null +++ b/drivers/staging/ipack/Makefile @@ -0,0 +1,4 @@ +# +# Makefile for the IPACK bridge device drivers. +# +obj-$(CONFIG_IPACK_BUS) += ipack.o diff --git a/drivers/staging/ipack/TODO b/drivers/staging/ipack/TODO new file mode 100644 index 0000000..167ae4d --- /dev/null +++ b/drivers/staging/ipack/TODO @@ -0,0 +1,21 @@ + TODO + ==== +Introduction +============ + +These drivers add support for IndustryPack devices: carrier and mezzanine +boards. + +The ipack driver is just an abstraction of the bus providing the common +operations between the two kind of boards. + +TODO +==== + +Ipack +----- + +* The structures and API exported can be improved a lot. For example, the + way to unregistering mezzanine devices, doing the mezzanine driver a call to + remove_device() to notify the carrier driver, or the opposite with the call to + the ipack_driver_ops' remove() function could be improved. diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c new file mode 100644 index 0000000..a54bfd7 --- /dev/null +++ b/drivers/staging/ipack/ipack.c @@ -0,0 +1,175 @@ +/* + * Industry-pack bus support functions. + * + * (C) 2011 Samuel Iglesias Gonsalvez , CERN + * (C) 2012 Samuel Iglesias Gonsalvez , Igalia + * + * 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. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include "ipack.h" + +#define to_ipack_dev(device) container_of(device, struct ipack_device, dev) +#define to_ipack_driver(drv) container_of(drv, struct ipack_driver, driver) + +/* used when allocating bus numbers */ +#define IPACK_MAXBUS 64 + +static DEFINE_MUTEX(ipack_mutex); + +struct ipack_busmap { + unsigned long busmap[IPACK_MAXBUS / (8*sizeof(unsigned long))]; +}; +static struct ipack_busmap busmap; + +static int ipack_bus_match(struct device *device, struct device_driver *driver) +{ + int ret; + struct ipack_device *dev = to_ipack_dev(device); + struct ipack_driver *drv = to_ipack_driver(driver); + + if (!drv->ops->match) + return -EINVAL; + + ret = drv->ops->match(dev); + if (ret) + dev->driver = drv; + + return 0; +} + +static int ipack_bus_probe(struct device *device) +{ + struct ipack_device *dev = to_ipack_dev(device); + + if (!dev->driver->ops->probe) + return -EINVAL; + + return dev->driver->ops->probe(dev); +} + +static int ipack_bus_remove(struct device *device) +{ + struct ipack_device *dev = to_ipack_dev(device); + + if (!dev->driver->ops->remove) + return -EINVAL; + + dev->driver->ops->remove(dev); + return 0; +} + +static struct bus_type ipack_bus_type = { + .name = "ipack", + .probe = ipack_bus_probe, + .match = ipack_bus_match, + .remove = ipack_bus_remove, +}; + +static int ipack_assign_bus_number(void) +{ + int busnum; + + mutex_lock(&ipack_mutex); + busnum = find_next_zero_bit(busmap.busmap, IPACK_MAXBUS, 1); + + if (busnum >= IPACK_MAXBUS) { + pr_err("too many buses\n"); + busnum = -1; + goto error_find_busnum; + } + + set_bit(busnum, busmap.busmap); + +error_find_busnum: + mutex_unlock(&ipack_mutex); + return busnum; +} + +int ipack_bus_register(struct ipack_bus_device *bus) +{ + int bus_nr; + + bus_nr = ipack_assign_bus_number(); + if (bus_nr < 0) + return -1; + + bus->bus_nr = bus_nr; + return 0; +} +EXPORT_SYMBOL_GPL(ipack_bus_register); + +int ipack_bus_unregister(struct ipack_bus_device *bus) +{ + mutex_lock(&ipack_mutex); + clear_bit(bus->bus_nr, busmap.busmap); + mutex_unlock(&ipack_mutex); + return 0; +} +EXPORT_SYMBOL_GPL(ipack_bus_unregister); + +int ipack_driver_register(struct ipack_driver *edrv) +{ + edrv->driver.bus = &ipack_bus_type; + return driver_register(&edrv->driver); +} +EXPORT_SYMBOL_GPL(ipack_driver_register); + +void ipack_driver_unregister(struct ipack_driver *edrv) +{ + driver_unregister(&edrv->driver); +} +EXPORT_SYMBOL_GPL(ipack_driver_unregister); + +static void ipack_device_release(struct device *dev) +{ +} + +int ipack_device_register(struct ipack_device *dev) +{ + int ret; + + dev->dev.bus = &ipack_bus_type; + dev->dev.release = ipack_device_release; + dev_set_name(&dev->dev, + "%s.%u.%u", dev->board_name, dev->bus_nr, dev->slot); + + ret = device_register(&dev->dev); + if (ret < 0) { + pr_err("error registering the device.\n"); + dev->driver->ops->remove(dev); + } + + return ret; +} +EXPORT_SYMBOL_GPL(ipack_device_register); + +void ipack_device_unregister(struct ipack_device *dev) +{ + device_unregister(&dev->dev); +} +EXPORT_SYMBOL_GPL(ipack_device_unregister); + +static int __init ipack_init(void) +{ + return bus_register(&ipack_bus_type); +} + +static void __exit ipack_exit(void) +{ + bus_unregister(&ipack_bus_type); +} + +module_init(ipack_init); +module_exit(ipack_exit); + +MODULE_AUTHOR("Samuel Iglesias Gonsalvez "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Industry-pack bus core"); diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h new file mode 100644 index 0000000..41d6172 --- /dev/null +++ b/drivers/staging/ipack/ipack.h @@ -0,0 +1,183 @@ +/* + * Industry-pack bus. + * + * (C) 2011 Samuel Iglesias Gonsalvez , CERN + * (C) 2012 Samuel Iglesias Gonsalvez , Igalia + * + * 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. + */ + +#include + +#define IPACK_BOARD_NAME_SIZE 16 +#define IPACK_IRQ_NAME_SIZE 50 +#define IPACK_IDPROM_OFFSET_I 0x01 +#define IPACK_IDPROM_OFFSET_P 0x03 +#define IPACK_IDPROM_OFFSET_A 0x05 +#define IPACK_IDPROM_OFFSET_C 0x07 +#define IPACK_IDPROM_OFFSET_MANUFACTURER_ID 0x09 +#define IPACK_IDPROM_OFFSET_MODEL 0x0B +#define IPACK_IDPROM_OFFSET_REVISION 0x0D +#define IPACK_IDPROM_OFFSET_RESERVED 0x0F +#define IPACK_IDPROM_OFFSET_DRIVER_ID_L 0x11 +#define IPACK_IDPROM_OFFSET_DRIVER_ID_H 0x13 +#define IPACK_IDPROM_OFFSET_NUM_BYTES 0x15 +#define IPACK_IDPROM_OFFSET_CRC 0x17 + +struct ipack_bus_ops; +struct ipack_driver; + +enum ipack_space { + IPACK_IO_SPACE = 0, + IPACK_ID_SPACE = 1, + IPACK_MEM_SPACE = 2, +}; + +/** + * struct ipack_addr_space - Virtual address space mapped for a specified type. + * + * @address: virtual address + * @size: size of the mapped space + */ +struct ipack_addr_space { + void *address; + unsigned int size; +}; + +/** + * struct ipack_device + * + * @board_name: IP mezzanine board name + * @bus_name: IP carrier board name + * @bus_nr: IP bus number where the device is plugged + * @slot: Slot where the device is plugged in the carrier board + * @irq: IRQ vector + * @driver: Pointer to the ipack_driver that manages the device + * @ops: Carrier board operations to access the device + * @id_space: Virtual address to ID space. + * @io_space: Virtual address to IO space. + * @mem_space: Virtual address to MEM space. + * @dev: device in kernel representation. + * + * Warning: Direct access to mapped memory is possible but the endianness + * is not the same with PCI carrier or VME carrier. The endianness is managed + * by the carrier board throught @ops. + */ +struct ipack_device { + char board_name[IPACK_BOARD_NAME_SIZE]; + char bus_name[IPACK_BOARD_NAME_SIZE]; + unsigned int bus_nr; + unsigned int slot; + unsigned int irq; + struct ipack_driver *driver; + struct ipack_bus_ops *ops; + struct ipack_addr_space id_space; + struct ipack_addr_space io_space; + struct ipack_addr_space mem_space; + struct device dev; +}; + +/* + * struct ipack_driver_ops -- callbacks to mezzanine driver for installing/removing one device + * + * @match: Match function + * @probe: Probe function + * @remove: tell the driver that the carrier board wants to remove one device + */ + +struct ipack_driver_ops { + int (*match) (struct ipack_device *dev); + int (*probe) (struct ipack_device *dev); + void (*remove) (struct ipack_device *dev); +}; + +/** + * struct ipack_driver -- Specific data to each mezzanine board driver + * + * @driver: Device driver kernel representation + * @ops: Mezzanine driver operations specific for the ipack bus. + */ +struct ipack_driver { + struct module *owner; + struct device_driver driver; + struct ipack_driver_ops *ops; +}; + +/* + * ipack_driver_register -- Register a new mezzanine driver + * + * Called by the mezzanine driver to register itself as a driver + * that can manage ipack devices. + */ + +int ipack_driver_register(struct ipack_driver *edrv); +void ipack_driver_unregister(struct ipack_driver *edrv); + +/* + * ipack_device_register -- register a new mezzanine device + * + * Register a new ipack device (mezzanine device). The call is done by + * the carrier device driver. + */ +int ipack_device_register(struct ipack_device *dev); +void ipack_device_unregister(struct ipack_device *dev); + +/** + * struct ipack_bus_ops - available operations on a bridge module + * + * @map_space: map IP address space + * @unmap_space: unmap IP address space + * @request_irq: request IRQ + * @free_irq: free IRQ + * @read8: read unsigned char + * @read16: read unsigned short + * @read32: read unsigned int + * @write8: read unsigned char + * @write16: read unsigned short + * @write32: read unsigned int + * @remove_device: tell the bridge module that the device has been removed + */ +struct ipack_bus_ops { + int (*map_space) (struct ipack_device *dev, unsigned int memory_size, int space); + int (*unmap_space) (struct ipack_device *dev, int space); + int (*request_irq) (struct ipack_device *dev, int vector, int (*handler)(void *), void *arg); + int (*free_irq) (struct ipack_device *dev); + int (*read8) (struct ipack_device *dev, int space, unsigned long offset, unsigned char *value); + int (*read16) (struct ipack_device *dev, int space, unsigned long offset, unsigned short *value); + int (*read32) (struct ipack_device *dev, int space, unsigned long offset, unsigned int *value); + int (*write8) (struct ipack_device *dev, int space, unsigned long offset, unsigned char value); + int (*write16) (struct ipack_device *dev, int space, unsigned long offset, unsigned short value); + int (*write32) (struct ipack_device *dev, int space, unsigned long offset, unsigned int value); + int (*remove_device) (struct ipack_device *dev); +}; + +/** + * struct ipack_bus_device + * + * @dev: pointer to carrier device + * @slots: number of slots available + * @bus_nr: ipack bus number + * @vector: IRQ base vector. IRQ vectors are $vector + $slot_number + */ +struct ipack_bus_device { + struct device *dev; + int slots; + int bus_nr; + int vector; +}; + +/** + * ipack_bus_register -- register a new ipack bus + * + * The carrier board device driver should call this function to register itself + * as available bus in ipack. + */ +int ipack_bus_register(struct ipack_bus_device *bus); + +/** + * ipack_bus_unregister -- unregister an ipack bus + */ +int ipack_bus_unregister(struct ipack_bus_device *bus); -- cgit v0.10.2 From 0eeca14f5a4c03e5475177aa39a8c4e43b7ebda8 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Wed, 9 May 2012 15:27:20 +0200 Subject: Staging: ipack: added support for the TEWS TPCI-200 carrier board Driver for the carrier board TEWS TPCI-200, a bridge between PCIe bus and IndustryPack bus. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/Kconfig b/drivers/staging/ipack/Kconfig index e20187f..30b28fe 100644 --- a/drivers/staging/ipack/Kconfig +++ b/drivers/staging/ipack/Kconfig @@ -7,3 +7,8 @@ menuconfig IPACK_BUS ---help--- If you say Y here you get support for the IndustryPack Framework. +if IPACK_BUS + +source "drivers/staging/ipack/bridges/Kconfig" + +endif # IPACK diff --git a/drivers/staging/ipack/Makefile b/drivers/staging/ipack/Makefile index 56e2340..59b8762 100644 --- a/drivers/staging/ipack/Makefile +++ b/drivers/staging/ipack/Makefile @@ -2,3 +2,4 @@ # Makefile for the IPACK bridge device drivers. # obj-$(CONFIG_IPACK_BUS) += ipack.o +obj-y += bridges/ diff --git a/drivers/staging/ipack/TODO b/drivers/staging/ipack/TODO index 167ae4d..d5a5735 100644 --- a/drivers/staging/ipack/TODO +++ b/drivers/staging/ipack/TODO @@ -12,6 +12,16 @@ operations between the two kind of boards. TODO ==== +TPCI-200 +-------- + +* It receives the name of the mezzanine plugged in each slot by SYSFS. + No autodetection supported yet, because the mezzanine driver could not be + loaded at the time that the tpci200 driver loads. + +* It has a linked list with the tpci200 devices it is managing. Get rid of it + and use driver_for_each_device() instead. + Ipack ----- diff --git a/drivers/staging/ipack/bridges/Kconfig b/drivers/staging/ipack/bridges/Kconfig new file mode 100644 index 0000000..97c837e --- /dev/null +++ b/drivers/staging/ipack/bridges/Kconfig @@ -0,0 +1,8 @@ +config BOARD_TPCI200 + tristate "TEWS TPCI-200 support for IndustryPack bus" + depends on IPACK_BUS + depends on PCI + help + This driver supports the TEWS TPCI200 device for the IndustryPack bus. + default n + diff --git a/drivers/staging/ipack/bridges/Makefile b/drivers/staging/ipack/bridges/Makefile new file mode 100644 index 0000000..d8b7645 --- /dev/null +++ b/drivers/staging/ipack/bridges/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_BOARD_TPCI200) += tpci200.o diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c new file mode 100644 index 0000000..6aeb660 --- /dev/null +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -0,0 +1,1183 @@ +/** + * tpci200.c + * + * driver for the TEWS TPCI-200 device + * Copyright (c) 2009 Nicolas Serafini, EIC2 SA + * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez , CERN + * Copyright (c) 2012 Samuel Iglesias Gonsalvez , Igalia + * + * 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. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include "tpci200.h" + +struct ipack_bus_ops tpci200_bus_ops; + +/* TPCI200 controls registers */ +static int control_reg[] = { + TPCI200_CONTROL_A_REG, + TPCI200_CONTROL_B_REG, + TPCI200_CONTROL_C_REG, + TPCI200_CONTROL_D_REG +}; + +/* Linked list to save the registered devices */ +static LIST_HEAD(tpci200_list); + +static int tpci200_slot_unregister(struct ipack_device *dev); + +static struct tpci200_board *check_slot(struct ipack_device *dev) +{ + struct tpci200_board *tpci200; + int found = 0; + + if (dev == NULL) { + pr_info("Slot doesn't exist.\n"); + return NULL; + } + + list_for_each_entry(tpci200, &tpci200_list, list) { + if (tpci200->number == dev->bus_nr) { + found = 1; + break; + } + } + + if (!found) { + pr_err("Carrier not found\n"); + return NULL; + } + + if (dev->slot >= TPCI200_NB_SLOT) { + pr_info("Slot [%s %d:%d] doesn't exist! Last tpci200 slot is %d.\n", + TPCI200_SHORTNAME, dev->bus_nr, dev->slot, + TPCI200_NB_SLOT-1); + return NULL; + } + + BUG_ON(tpci200->slots == NULL); + if (tpci200->slots[dev->slot].dev == NULL) { + pr_info("Slot [%s %d:%d] is not registered !\n", + TPCI200_SHORTNAME, dev->bus_nr, dev->slot); + return NULL; + } + + return tpci200; +} + +static inline unsigned char __tpci200_read8(void *address, unsigned long offset) +{ + return ioread8(address + (offset^1)); +} + +static inline unsigned short __tpci200_read16(void *address, + unsigned long offset) +{ + return ioread16(address + offset); +} + +static inline unsigned int __tpci200_read32(void *address, unsigned long offset) +{ + return swahw32(ioread32(address + offset)); +} + +static inline void __tpci200_write8(unsigned char value, + void *address, unsigned long offset) +{ + iowrite8(value, address+(offset^1)); +} + +static inline void __tpci200_write16(unsigned short value, void *address, + unsigned long offset) +{ + iowrite16(value, address+offset); +} + +static inline void __tpci200_write32(unsigned int value, void *address, + unsigned long offset) +{ + iowrite32(swahw32(value), address+offset); +} + +static struct ipack_addr_space *get_slot_address_space(struct ipack_device *dev, + int space) +{ + struct ipack_addr_space *addr; + + switch (space) { + case IPACK_IO_SPACE: + addr = &dev->io_space; + break; + case IPACK_ID_SPACE: + addr = &dev->id_space; + break; + case IPACK_MEM_SPACE: + addr = &dev->mem_space; + break; + default: + pr_err("Slot [%s %d:%d] space number %d doesn't exist !\n", + TPCI200_SHORTNAME, dev->bus_nr, dev->slot, space); + return NULL; + break; + } + + if ((addr->size == 0) || (addr->address == NULL)) { + pr_err("Error, slot space not mapped !\n"); + return NULL; + } + + return addr; +} + +static int tpci200_read8(struct ipack_device *dev, int space, + unsigned long offset, unsigned char *value) +{ + struct ipack_addr_space *addr; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) + return -EINVAL; + + addr = get_slot_address_space(dev, space); + if (addr == NULL) + return -EINVAL; + + if (offset >= addr->size) { + pr_err("Error, slot space offset error !\n"); + return -EFAULT; + } + + *value = __tpci200_read8(addr->address, offset); + + return 0; +} + +static int tpci200_read16(struct ipack_device *dev, int space, + unsigned long offset, unsigned short *value) +{ + struct ipack_addr_space *addr; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) + return -EINVAL; + + addr = get_slot_address_space(dev, space); + if (addr == NULL) + return -EINVAL; + + if ((offset+2) >= addr->size) { + pr_err("Error, slot space offset error !\n"); + return -EFAULT; + } + *value = __tpci200_read16(addr->address, offset); + + return 0; +} + +static int tpci200_read32(struct ipack_device *dev, int space, + unsigned long offset, unsigned int *value) +{ + struct ipack_addr_space *addr; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) + return -EINVAL; + + addr = get_slot_address_space(dev, space); + if (addr == NULL) + return -EINVAL; + + if ((offset+4) >= addr->size) { + pr_err("Error, slot space offset error !\n"); + return -EFAULT; + } + + *value = __tpci200_read32(addr->address, offset); + + return 0; +} + +static int tpci200_write8(struct ipack_device *dev, int space, + unsigned long offset, unsigned char value) +{ + struct ipack_addr_space *addr; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) + return -EINVAL; + + addr = get_slot_address_space(dev, space); + if (addr == NULL) + return -EINVAL; + + if (offset >= addr->size) { + pr_err("Error, slot space offset error !\n"); + return -EFAULT; + } + + __tpci200_write8(value, addr->address, offset); + + return 0; +} + +static int tpci200_write16(struct ipack_device *dev, int space, + unsigned long offset, unsigned short value) +{ + struct ipack_addr_space *addr; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) + return -EINVAL; + + addr = get_slot_address_space(dev, space); + if (addr == NULL) + return -EINVAL; + + if ((offset+2) >= addr->size) { + pr_err("Error, slot space offset error !\n"); + return -EFAULT; + } + + __tpci200_write16(value, addr->address, offset); + + return 0; +} + +static int tpci200_write32(struct ipack_device *dev, int space, + unsigned long offset, unsigned int value) +{ + struct ipack_addr_space *addr; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) + return -EINVAL; + + addr = get_slot_address_space(dev, space); + if (addr == NULL) + return -EINVAL; + + if ((offset+4) >= addr->size) { + pr_err("Error, slot space offset error !\n"); + return -EFAULT; + } + + __tpci200_write32(value, addr->address, offset); + + return 0; +} + +static void tpci200_unregister(struct tpci200_board *tpci200) +{ + int i; + + free_irq(tpci200->info->pdev->irq, (void *) tpci200); + + pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs); + pci_iounmap(tpci200->info->pdev, tpci200->info->ioidint_space); + pci_iounmap(tpci200->info->pdev, tpci200->info->mem8_space); + + pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR); + pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); + pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR); + + pci_disable_device(tpci200->info->pdev); + pci_dev_put(tpci200->info->pdev); + + kfree(tpci200->info); + + for (i = 0; i < TPCI200_NB_SLOT; i++) { + tpci200->slots[i].io_phys.address = NULL; + tpci200->slots[i].io_phys.size = 0; + tpci200->slots[i].id_phys.address = NULL; + tpci200->slots[i].id_phys.size = 0; + tpci200->slots[i].mem_phys.address = NULL; + tpci200->slots[i].mem_phys.size = 0; + } +} + +static irqreturn_t tpci200_interrupt(int irq, void *dev_id) +{ + struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id; + int i; + unsigned long flags; + unsigned short status_reg, reg_value; + unsigned short unhandled_ints = 0; + irqreturn_t ret = IRQ_NONE; + + spin_lock_irqsave(&tpci200->info->access_lock, flags); + + /* Read status register */ + status_reg = readw((unsigned short *) (tpci200->info->interface_regs + + TPCI200_STATUS_REG)); + + if (status_reg & TPCI200_SLOT_INT_MASK) { + unhandled_ints = status_reg & TPCI200_SLOT_INT_MASK; + /* callback to the IRQ handler for the corresponding slot */ + for (i = 0; i < TPCI200_NB_SLOT; i++) { + if ((tpci200->slots[i].irq != NULL) && + (status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2*i)))) { + + ret = tpci200->slots[i].irq->handler(tpci200->slots[i].irq->arg); + + /* Dummy reads */ + readw((unsigned short *) + (tpci200->slots[i].dev->io_space.address + + 0xC0)); + readw((unsigned short *) + (tpci200->slots[i].dev->io_space.address + + 0xC2)); + + unhandled_ints &= ~(((TPCI200_A_INT0 | TPCI200_A_INT1) << (2*i))); + } + } + } + /* Interrupt not handled are disabled */ + if (unhandled_ints) { + for (i = 0; i < TPCI200_NB_SLOT; i++) { + if (unhandled_ints & ((TPCI200_INT0_EN | TPCI200_INT1_EN) << (2*i))) { + pr_info("No registered ISR for slot [%s %d:%d]!. IRQ will be disabled.\n", + TPCI200_SHORTNAME, + tpci200->number, i); + reg_value = readw((unsigned short *)(tpci200->info->interface_regs + + control_reg[i])); + reg_value &= + ~(TPCI200_INT0_EN | TPCI200_INT1_EN); + writew(reg_value, (unsigned short *)(tpci200->info->interface_regs + + control_reg[i])); + } + } + } + + spin_unlock_irqrestore(&tpci200->info->access_lock, flags); + return ret; +} + +#ifdef CONFIG_SYSFS + +static struct ipack_device *tpci200_slot_register(const char *board_name, + int size, + unsigned int tpci200_number, + unsigned int slot_position) +{ + int found = 0; + struct ipack_device *dev = NULL; + struct tpci200_board *tpci200; + + list_for_each_entry(tpci200, &tpci200_list, list) { + if (tpci200->number == tpci200_number) { + found = 1; + break; + } + } + + if (!found) { + pr_err("carrier board not found for the device\n"); + return NULL; + } + + if (slot_position >= TPCI200_NB_SLOT) { + pr_info("Slot [%s %d:%d] doesn't exist!\n", + TPCI200_SHORTNAME, tpci200_number, slot_position); + goto out; + } + + if (mutex_lock_interruptible(&tpci200->mutex)) + goto out; + + if (tpci200->slots[slot_position].dev != NULL) { + pr_err("Slot [%s %d:%d] already installed !\n", + TPCI200_SHORTNAME, tpci200_number, slot_position); + goto out_unlock; + } + + dev = kzalloc(sizeof(struct ipack_device), GFP_KERNEL); + if (dev == NULL) { + pr_info("Slot [%s %d:%d] Unable to allocate memory for new slot !\n", + TPCI200_SHORTNAME, + tpci200_number, slot_position); + goto out_unlock; + } + + if (size > IPACK_BOARD_NAME_SIZE) { + pr_warning("Slot [%s %d:%d] name (%s) too long (%d > %d). Will be truncated!\n", + TPCI200_SHORTNAME, tpci200_number, slot_position, + board_name, (int)strlen(board_name), + IPACK_BOARD_NAME_SIZE); + + size = IPACK_BOARD_NAME_SIZE; + } + + strncpy(dev->board_name, board_name, size-1); + dev->board_name[size-1] = '\0'; + dev->bus_nr = tpci200->info->drv.bus_nr; + dev->slot = slot_position; + /* + * Give the same IRQ number as the slot number. + * The TPCI200 has assigned his own two IRQ by PCI bus driver + */ + dev->irq = slot_position; + + dev->id_space.address = NULL; + dev->id_space.size = 0; + dev->io_space.address = NULL; + dev->io_space.size = 0; + dev->mem_space.address = NULL; + dev->mem_space.size = 0; + + /* Give the operations structure */ + dev->ops = &tpci200_bus_ops; + tpci200->slots[slot_position].dev = dev; + + if (ipack_device_register(dev) < 0) { + tpci200_slot_unregister(dev); + kfree(dev); + } + +out_unlock: + mutex_unlock(&tpci200->mutex); +out: + return dev; +} + +static ssize_t tpci200_store_board(struct device *pdev, const char *buf, + size_t count, int slot) +{ + struct tpci200_board *card = dev_get_drvdata(pdev); + struct ipack_device *dev = card->slots[slot].dev; + + if (dev != NULL) + return -EBUSY; + + dev = tpci200_slot_register(buf, count, card->number, slot); + if (dev == NULL) + return -ENODEV; + + return count; +} + +static ssize_t tpci200_show_board(struct device *pdev, char *buf, int slot) +{ + struct tpci200_board *card = dev_get_drvdata(pdev); + struct ipack_device *dev = card->slots[slot].dev; + + if (dev != NULL) + return snprintf(buf, PAGE_SIZE, "%s\n", dev->board_name); + else + return snprintf(buf, PAGE_SIZE, "none\n"); +} + +static ssize_t tpci200_show_description(struct device *pdev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, + "TEWS tpci200 carrier PCI for Industry-pack mezzanines.\n"); +} + +static ssize_t tpci200_show_board_slot0(struct device *pdev, + struct device_attribute *attr, + char *buf) +{ + return tpci200_show_board(pdev, buf, 0); +} + +static ssize_t tpci200_store_board_slot0(struct device *pdev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + return tpci200_store_board(pdev, buf, count, 0); +} + +static ssize_t tpci200_show_board_slot1(struct device *pdev, + struct device_attribute *attr, + char *buf) +{ + return tpci200_show_board(pdev, buf, 1); +} + +static ssize_t tpci200_store_board_slot1(struct device *pdev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + return tpci200_store_board(pdev, buf, count, 1); +} + +static ssize_t tpci200_show_board_slot2(struct device *pdev, + struct device_attribute *attr, + char *buf) +{ + return tpci200_show_board(pdev, buf, 2); +} + +static ssize_t tpci200_store_board_slot2(struct device *pdev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + return tpci200_store_board(pdev, buf, count, 2); +} + + +static ssize_t tpci200_show_board_slot3(struct device *pdev, + struct device_attribute *attr, + char *buf) +{ + return tpci200_show_board(pdev, buf, 3); +} + +static ssize_t tpci200_store_board_slot3(struct device *pdev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + return tpci200_store_board(pdev, buf, count, 3); +} + +/* Declaration of the device attributes for the TPCI200 */ +static DEVICE_ATTR(description, S_IRUGO, + tpci200_show_description, NULL); +static DEVICE_ATTR(board_slot0, S_IRUGO | S_IWUSR, + tpci200_show_board_slot0, tpci200_store_board_slot0); +static DEVICE_ATTR(board_slot1, S_IRUGO | S_IWUSR, + tpci200_show_board_slot1, tpci200_store_board_slot1); +static DEVICE_ATTR(board_slot2, S_IRUGO | S_IWUSR, + tpci200_show_board_slot2, tpci200_store_board_slot2); +static DEVICE_ATTR(board_slot3, S_IRUGO | S_IWUSR, + tpci200_show_board_slot3, tpci200_store_board_slot3); + +static struct attribute *tpci200_attrs[] = { + &dev_attr_description.attr, + &dev_attr_board_slot0.attr, + &dev_attr_board_slot1.attr, + &dev_attr_board_slot2.attr, + &dev_attr_board_slot3.attr, + NULL, +}; + +static struct attribute_group tpci200_attr_group = { + .attrs = tpci200_attrs, +}; + +static int tpci200_create_sysfs_files(struct tpci200_board *card) +{ + return sysfs_create_group(&card->info->pdev->dev.kobj, + &tpci200_attr_group); +} + +static void tpci200_remove_sysfs_files(struct tpci200_board *card) +{ + sysfs_remove_group(&card->info->pdev->dev.kobj, &tpci200_attr_group); +} + +#else + +static int tpci200_create_sysfs_files(struct tpci200_board *card) +{ + return 0; +} + +static void tpci200_remove_sysfs_files(struct tpci200_board *card) +{ +} + +#endif /* CONFIG_SYSFS */ + +static int tpci200_register(struct tpci200_board *tpci200) +{ + int i; + int res; + unsigned long ioidint_base; + unsigned long mem_base; + unsigned short slot_ctrl; + + if (pci_enable_device(tpci200->info->pdev) < 0) + return -ENODEV; + + if (tpci200_create_sysfs_files(tpci200) < 0) { + pr_err("failed creating sysfs files\n"); + res = -EFAULT; + goto out_disable_pci; + } + + /* Request IP interface register (Bar 2) */ + res = pci_request_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR, + "Carrier IP interface registers"); + if (res) { + pr_err("(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 2 !", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); + goto out_remove_sysfs; + } + + /* Request IO ID INT space (Bar 3) */ + res = pci_request_region(tpci200->info->pdev, + TPCI200_IO_ID_INT_SPACES_BAR, + "Carrier IO ID INT space"); + if (res) { + pr_err("(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 3 !", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); + goto out_release_ip_space; + } + + /* Request MEM space (Bar 4) */ + res = pci_request_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR, + "Carrier MEM space"); + if (res) { + pr_err("(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); + goto out_release_ioid_int_space; + } + + /* Map internal tpci200 driver user space */ + tpci200->info->interface_regs = + ioremap(pci_resource_start(tpci200->info->pdev, + TPCI200_IP_INTERFACE_BAR), + TPCI200_IFACE_SIZE); + tpci200->info->ioidint_space = + ioremap(pci_resource_start(tpci200->info->pdev, + TPCI200_IO_ID_INT_SPACES_BAR), + TPCI200_IOIDINT_SIZE); + tpci200->info->mem8_space = + ioremap(pci_resource_start(tpci200->info->pdev, + TPCI200_MEM8_SPACE_BAR), + TPCI200_MEM8_SIZE); + + spin_lock_init(&tpci200->info->access_lock); + ioidint_base = pci_resource_start(tpci200->info->pdev, + TPCI200_IO_ID_INT_SPACES_BAR); + mem_base = pci_resource_start(tpci200->info->pdev, + TPCI200_MEM8_SPACE_BAR); + + /* Set the default parameters of the slot + * INT0 disabled, level sensitive + * INT1 disabled, level sensitive + * error interrupt disabled + * timeout interrupt disabled + * recover time disabled + * clock rate 8 MHz + */ + slot_ctrl = 0; + + /* Set all slot physical address space */ + for (i = 0; i < TPCI200_NB_SLOT; i++) { + tpci200->slots[i].io_phys.address = + (void *)ioidint_base + + TPCI200_IO_SPACE_OFF + TPCI200_IO_SPACE_GAP*i; + tpci200->slots[i].io_phys.size = TPCI200_IO_SPACE_SIZE; + + tpci200->slots[i].id_phys.address = + (void *)ioidint_base + + TPCI200_ID_SPACE_OFF + TPCI200_ID_SPACE_GAP*i; + tpci200->slots[i].id_phys.size = TPCI200_ID_SPACE_SIZE; + + tpci200->slots[i].mem_phys.address = + (void *)mem_base + TPCI200_MEM8_GAP*i; + tpci200->slots[i].mem_phys.size = TPCI200_MEM8_SIZE; + + writew(slot_ctrl, + (unsigned short *)(tpci200->info->interface_regs + + control_reg[i])); + } + + res = request_irq(tpci200->info->pdev->irq, + tpci200_interrupt, IRQF_SHARED, + TPCI200_SHORTNAME, (void *) tpci200); + if (res) { + pr_err("(bn 0x%X, sn 0x%X) unable to register IRQ !", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); + tpci200_unregister(tpci200); + goto out_err; + } + + return 0; + +out_release_ioid_int_space: + pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); +out_release_ip_space: + pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR); +out_remove_sysfs: + tpci200_remove_sysfs_files(tpci200); +out_disable_pci: + pci_disable_device(tpci200->info->pdev); +out_err: + return res; +} + +static int __tpci200_request_irq(struct tpci200_board *tpci200, + struct ipack_device *dev) +{ + unsigned short slot_ctrl; + + /* Set the default parameters of the slot + * INT0 enabled, level sensitive + * INT1 enabled, level sensitive + * error interrupt disabled + * timeout interrupt disabled + * recover time disabled + * clock rate 8 MHz + */ + slot_ctrl = TPCI200_INT0_EN | TPCI200_INT1_EN; + writew(slot_ctrl, (unsigned short *)(tpci200->info->interface_regs + + control_reg[dev->slot])); + + return 0; +} + +static void __tpci200_free_irq(struct tpci200_board *tpci200, + struct ipack_device *dev) +{ + unsigned short slot_ctrl; + + /* Set the default parameters of the slot + * INT0 disabled, level sensitive + * INT1 disabled, level sensitive + * error interrupt disabled + * timeout interrupt disabled + * recover time disabled + * clock rate 8 MHz + */ + slot_ctrl = 0; + writew(slot_ctrl, (unsigned short *)(tpci200->info->interface_regs + + control_reg[dev->slot])); +} + +static int tpci200_free_irq(struct ipack_device *dev) +{ + int res; + struct slot_irq *slot_irq; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) { + res = -EINVAL; + goto out; + } + + if (mutex_lock_interruptible(&tpci200->mutex)) { + res = -ERESTARTSYS; + goto out; + } + + if (tpci200->slots[dev->slot].irq == NULL) { + res = -EINVAL; + goto out_unlock; + } + + __tpci200_free_irq(tpci200, dev); + slot_irq = tpci200->slots[dev->slot].irq; + tpci200->slots[dev->slot].irq = NULL; + kfree(slot_irq); + +out_unlock: + mutex_unlock(&tpci200->mutex); +out: + return res; +} + +static int tpci200_slot_unmap_space(struct ipack_device *dev, int space) +{ + int res; + struct ipack_addr_space *virt_addr_space; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) { + res = -EINVAL; + goto out; + } + + if (mutex_lock_interruptible(&tpci200->mutex)) { + res = -ERESTARTSYS; + goto out; + } + + switch (space) { + case IPACK_IO_SPACE: + if (dev->io_space.address == NULL) { + pr_info("Slot [%s %d:%d] IO space not mapped !\n", + TPCI200_SHORTNAME, dev->bus_nr, dev->slot); + goto out_unlock; + } + virt_addr_space = &dev->io_space; + break; + case IPACK_ID_SPACE: + if (dev->id_space.address == NULL) { + pr_info("Slot [%s %d:%d] ID space not mapped !\n", + TPCI200_SHORTNAME, dev->bus_nr, dev->slot); + goto out_unlock; + } + virt_addr_space = &dev->id_space; + break; + case IPACK_MEM_SPACE: + if (dev->mem_space.address == NULL) { + pr_info("Slot [%s %d:%d] MEM space not mapped !\n", + TPCI200_SHORTNAME, dev->bus_nr, dev->slot); + goto out_unlock; + } + virt_addr_space = &dev->mem_space; + break; + default: + pr_err("Slot [%s %d:%d] space number %d doesn't exist !\n", + TPCI200_SHORTNAME, dev->bus_nr, dev->slot, space); + res = -EINVAL; + goto out_unlock; + break; + } + + iounmap(virt_addr_space->address); + + virt_addr_space->address = NULL; + virt_addr_space->size = 0; +out_unlock: + mutex_unlock(&tpci200->mutex); +out: + return res; +} + +static int tpci200_slot_unregister(struct ipack_device *dev) +{ + struct tpci200_board *tpci200; + + if (dev == NULL) + return -ENODEV; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) + return -EINVAL; + + tpci200_free_irq(dev); + + if (mutex_lock_interruptible(&tpci200->mutex)) + return -ERESTARTSYS; + + ipack_device_unregister(dev); + kfree(dev); + tpci200->slots[dev->slot].dev = NULL; + mutex_unlock(&tpci200->mutex); + + return 0; +} + +static int tpci200_slot_map_space(struct ipack_device *dev, + unsigned int memory_size, int space) +{ + int res; + unsigned int size_to_map; + void *phys_address; + struct ipack_addr_space *virt_addr_space; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) { + res = -EINVAL; + goto out; + } + + if (mutex_lock_interruptible(&tpci200->mutex)) { + res = -ERESTARTSYS; + goto out; + } + + switch (space) { + case IPACK_IO_SPACE: + if (dev->io_space.address != NULL) { + pr_err("Slot [%s %d:%d] IO space already mapped !\n", + TPCI200_SHORTNAME, tpci200->number, dev->slot); + res = -EINVAL; + goto out_unlock; + } + virt_addr_space = &dev->io_space; + + phys_address = tpci200->slots[dev->slot].io_phys.address; + size_to_map = tpci200->slots[dev->slot].io_phys.size; + break; + case IPACK_ID_SPACE: + if (dev->id_space.address != NULL) { + pr_err("Slot [%s %d:%d] ID space already mapped !\n", + TPCI200_SHORTNAME, tpci200->number, dev->slot); + res = -EINVAL; + goto out_unlock; + } + virt_addr_space = &dev->id_space; + + phys_address = tpci200->slots[dev->slot].id_phys.address; + size_to_map = tpci200->slots[dev->slot].id_phys.size; + break; + case IPACK_MEM_SPACE: + if (dev->mem_space.address != NULL) { + pr_err("Slot [%s %d:%d] MEM space already mapped !\n", + TPCI200_SHORTNAME, + tpci200->number, dev->slot); + res = -EINVAL; + goto out_unlock; + } + virt_addr_space = &dev->mem_space; + + if (memory_size > tpci200->slots[dev->slot].mem_phys.size) { + pr_err("Slot [%s %d:%d] request is 0x%X memory, only 0x%X available !\n", + TPCI200_SHORTNAME, dev->bus_nr, dev->slot, + memory_size, tpci200->slots[dev->slot].mem_phys.size); + res = -EINVAL; + goto out_unlock; + } + + phys_address = tpci200->slots[dev->slot].mem_phys.address; + size_to_map = memory_size; + break; + default: + pr_err("Slot [%s %d:%d] space %d doesn't exist !\n", + TPCI200_SHORTNAME, + tpci200->number, dev->slot, space); + res = -EINVAL; + goto out_unlock; + break; + } + + virt_addr_space->size = size_to_map; + virt_addr_space->address = + ioremap((unsigned long)phys_address, size_to_map); + +out_unlock: + mutex_unlock(&tpci200->mutex); +out: + return res; +} + +static int tpci200_request_irq(struct ipack_device *dev, int vector, + int (*handler)(void *), void *arg) +{ + int res; + struct slot_irq *slot_irq; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) { + res = -EINVAL; + goto out; + } + + if (mutex_lock_interruptible(&tpci200->mutex)) { + res = -ERESTARTSYS; + goto out; + } + + if (tpci200->slots[dev->slot].irq != NULL) { + pr_err("Slot [%s %d:%d] IRQ already registered !\n", + TPCI200_SHORTNAME, dev->bus_nr, dev->slot); + res = -EINVAL; + goto out_unlock; + } + + slot_irq = kzalloc(sizeof(struct slot_irq), GFP_KERNEL); + if (slot_irq == NULL) { + pr_err("Slot [%s %d:%d] unable to allocate memory for IRQ !\n", + TPCI200_SHORTNAME, dev->bus_nr, dev->slot); + res = -ENOMEM; + goto out_unlock; + } + + /* + * WARNING: Setup Interrupt Vector in the IndustryPack device + * before an IRQ request. + * Read the User Manual of your IndustryPack device to know + * where to write the vector in memory. + */ + slot_irq->vector = vector; + slot_irq->handler = handler; + slot_irq->arg = arg; + if (dev->board_name) { + if (strlen(dev->board_name) > IPACK_IRQ_NAME_SIZE) { + pr_warning("Slot [%s %d:%d] IRQ name too long (%d char > %d char MAX). Will be truncated!\n", + TPCI200_SHORTNAME, dev->bus_nr, dev->slot, + (int)strlen(dev->board_name), + IPACK_IRQ_NAME_SIZE); + } + strncpy(slot_irq->name, dev->board_name, IPACK_IRQ_NAME_SIZE-1); + } else { + strcpy(slot_irq->name, "Unknown"); + } + + tpci200->slots[dev->slot].irq = slot_irq; + res = __tpci200_request_irq(tpci200, dev); + +out_unlock: + mutex_unlock(&tpci200->mutex); +out: + return res; +} + +static void tpci200_slot_remove(struct tpci200_slot *slot) +{ + if ((slot->dev == NULL) || + (slot->dev->driver->ops->remove == NULL)) + return; + + slot->dev->driver->ops->remove(slot->dev); +} + +static void tpci200_uninstall(struct tpci200_board *tpci200) +{ + int i; + + for (i = 0; i < TPCI200_NB_SLOT; i++) + tpci200_slot_remove(&tpci200->slots[i]); + + tpci200_unregister(tpci200); + kfree(tpci200->slots); +} + +struct ipack_bus_ops tpci200_bus_ops = { + .map_space = tpci200_slot_map_space, + .unmap_space = tpci200_slot_unmap_space, + .request_irq = tpci200_request_irq, + .free_irq = tpci200_free_irq, + .read8 = tpci200_read8, + .read16 = tpci200_read16, + .read32 = tpci200_read32, + .write8 = tpci200_write8, + .write16 = tpci200_write16, + .write32 = tpci200_write32, + .remove_device = tpci200_slot_unregister, +}; + +static int tpci200_install(struct tpci200_board *tpci200) +{ + int res; + + tpci200->slots = kzalloc( + TPCI200_NB_SLOT * sizeof(struct tpci200_slot), GFP_KERNEL); + if (tpci200->slots == NULL) { + res = -ENOMEM; + goto out_err; + } + + res = tpci200_register(tpci200); + if (res) + goto out_free; + + mutex_init(&tpci200->mutex); + return 0; + +out_free: + kfree(tpci200->slots); + tpci200->slots = NULL; +out_err: + return res; +} + +static int tpci200_pciprobe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + int ret; + struct tpci200_board *tpci200; + + tpci200 = kzalloc(sizeof(struct tpci200_board), GFP_KERNEL); + if (!tpci200) + return -ENOMEM; + + tpci200->info = kzalloc(sizeof(struct tpci200_infos), GFP_KERNEL); + if (!tpci200->info) { + kfree(tpci200); + return -ENOMEM; + } + + /* Save struct pci_dev pointer */ + tpci200->info->pdev = pdev; + tpci200->info->id_table = (struct pci_device_id *)id; + + /* register the device and initialize it */ + ret = tpci200_install(tpci200); + if (ret) { + pr_err("Error during tpci200 install !\n"); + kfree(tpci200->info); + kfree(tpci200); + return -ENODEV; + } + + tpci200->info->drv.dev = &pdev->dev; + tpci200->info->drv.slots = TPCI200_NB_SLOT; + + /* Register the bus in the industry pack driver */ + ret = ipack_bus_register(&tpci200->info->drv); + if (ret < 0) { + pr_err("error registering the carrier on ipack driver\n"); + tpci200_uninstall(tpci200); + kfree(tpci200->info); + kfree(tpci200); + return -EFAULT; + } + /* save the bus number given by ipack to logging purpose */ + tpci200->number = tpci200->info->drv.bus_nr; + dev_set_drvdata(&pdev->dev, tpci200); + /* add the registered device in an internal linked list */ + list_add_tail(&tpci200->list, &tpci200_list); + return ret; +} + +static void __tpci200_pci_remove(struct tpci200_board *tpci200) +{ + tpci200_uninstall(tpci200); + tpci200_remove_sysfs_files(tpci200); + list_del(&tpci200->list); + ipack_bus_unregister(&tpci200->info->drv); + kfree(tpci200); +} + +static void __devexit tpci200_pci_remove(struct pci_dev *dev) +{ + struct tpci200_board *tpci200, *next; + + /* Search the registered device to uninstall it */ + list_for_each_entry_safe(tpci200, next, &tpci200_list, list) { + if (tpci200->info->pdev == dev) { + __tpci200_pci_remove(tpci200); + break; + } + } +} + +static struct pci_device_id tpci200_idtable[2] = { + { TPCI200_VENDOR_ID, TPCI200_DEVICE_ID, TPCI200_SUBVENDOR_ID, + TPCI200_SUBDEVICE_ID }, + { 0, }, +}; + +static struct pci_driver tpci200_pci_drv = { + .name = "tpci200", + .id_table = tpci200_idtable, + .probe = tpci200_pciprobe, + .remove = __devexit_p(tpci200_pci_remove), +}; + +static int __init tpci200_drvr_init_module(void) +{ + return pci_register_driver(&tpci200_pci_drv); +} + +static void __exit tpci200_drvr_exit_module(void) +{ + struct tpci200_board *tpci200, *next; + + list_for_each_entry_safe(tpci200, next, &tpci200_list, list) + __tpci200_pci_remove(tpci200); + + pci_unregister_driver(&tpci200_pci_drv); +} + +MODULE_DESCRIPTION("TEWS TPCI-200 device driver"); +MODULE_LICENSE("GPL"); +module_init(tpci200_drvr_init_module); +module_exit(tpci200_drvr_exit_module); diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h new file mode 100644 index 0000000..e452da2 --- /dev/null +++ b/drivers/staging/ipack/bridges/tpci200.h @@ -0,0 +1,165 @@ +/** + * tpci200.h + * + * driver for the carrier TEWS TPCI-200 + * Copyright (c) 2009 Nicolas Serafini, EIC2 SA + * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez , CERN + * Copyright (c) 2012 Samuel Iglesias Gonsalvez , Igalia + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#ifndef _TPCI200_H_ +#define _TPCI200_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "../ipack.h" + +#define TPCI200_SHORTNAME "TPCI200" + +#define TPCI200_NB_SLOT 0x4 +#define TPCI200_NB_BAR 0x6 + +#define TPCI200_VENDOR_ID 0x1498 +#define TPCI200_DEVICE_ID 0x30C8 +#define TPCI200_SUBVENDOR_ID 0x1498 +#define TPCI200_SUBDEVICE_ID 0x300A + +#define TPCI200_IP_INTERFACE_BAR 2 +#define TPCI200_IO_ID_INT_SPACES_BAR 3 +#define TPCI200_MEM16_SPACE_BAR 4 +#define TPCI200_MEM8_SPACE_BAR 5 + +#define TPCI200_REVISION_REG 0x00 +#define TPCI200_CONTROL_A_REG 0x02 +#define TPCI200_CONTROL_B_REG 0x04 +#define TPCI200_CONTROL_C_REG 0x06 +#define TPCI200_CONTROL_D_REG 0x08 +#define TPCI200_RESET_REG 0x0A +#define TPCI200_STATUS_REG 0x0C + +#define TPCI200_IFACE_SIZE 0x100 + +#define TPCI200_IO_SPACE_OFF 0x0000 +#define TPCI200_IO_SPACE_GAP 0x0100 +#define TPCI200_IO_SPACE_SIZE 0x0080 +#define TPCI200_ID_SPACE_OFF 0x0080 +#define TPCI200_ID_SPACE_GAP 0x0100 +#define TPCI200_ID_SPACE_SIZE 0x0040 +#define TPCI200_INT_SPACE_OFF 0x00C0 +#define TPCI200_INT_SPACE_GAP 0x0100 +#define TPCI200_INT_SPACE_SIZE 0x0040 +#define TPCI200_IOIDINT_SIZE 0x0400 + +#define TPCI200_MEM8_GAP 0x00400000 +#define TPCI200_MEM8_SIZE 0x00400000 +#define TPCI200_MEM16_GAP 0x00800000 +#define TPCI200_MEM16_SIZE 0x00800000 + +#define TPCI200_INT0_EN 0x0040 +#define TPCI200_INT1_EN 0x0080 +#define TPCI200_INT0_EDGE 0x0010 +#define TPCI200_INT1_EDGE 0x0020 +#define TPCI200_ERR_INT_EN 0x0008 +#define TPCI200_TIME_INT_EN 0x0004 +#define TPCI200_RECOVER_EN 0x0002 +#define TPCI200_CLK32 0x0001 + +#define TPCI200_A_RESET 0x0001 +#define TPCI200_B_RESET 0x0002 +#define TPCI200_C_RESET 0x0004 +#define TPCI200_D_RESET 0x0008 + +#define TPCI200_A_TIMEOUT 0x1000 +#define TPCI200_B_TIMEOUT 0x2000 +#define TPCI200_C_TIMEOUT 0x4000 +#define TPCI200_D_TIMEOUT 0x8000 + +#define TPCI200_A_ERROR 0x0100 +#define TPCI200_B_ERROR 0x0200 +#define TPCI200_C_ERROR 0x0400 +#define TPCI200_D_ERROR 0x0800 + +#define TPCI200_A_INT0 0x0001 +#define TPCI200_A_INT1 0x0002 +#define TPCI200_B_INT0 0x0004 +#define TPCI200_B_INT1 0x0008 +#define TPCI200_C_INT0 0x0010 +#define TPCI200_C_INT1 0x0020 +#define TPCI200_D_INT0 0x0040 +#define TPCI200_D_INT1 0x0080 + +#define TPCI200_SLOT_INT_MASK 0x00FF + +#define VME_IOID_SPACE "IOID" +#define VME_MEM_SPACE "MEM" + +/** + * struct slot_irq - slot IRQ definition. + * @vector Vector number + * @handler Handler called when IRQ arrives + * @arg Handler argument + * @name IRQ name + * + */ +struct slot_irq { + int vector; + int (*handler)(void *); + void *arg; + char name[IPACK_IRQ_NAME_SIZE]; +}; + +/** + * struct tpci200_slot - data specific to the tpci200 slot. + * @slot_id Slot identification gived to external interface + * @irq Slot IRQ infos + * @io_phys IO physical base address register of the slot + * @id_phys ID physical base address register of the slot + * @mem_phys MEM physical base address register of the slot + * + */ +struct tpci200_slot { + struct ipack_device *dev; + struct slot_irq *irq; + struct ipack_addr_space io_phys; + struct ipack_addr_space id_phys; + struct ipack_addr_space mem_phys; +}; + +/** + * struct tpci200_infos - informations specific of the TPCI200 tpci200. + * @pci_dev PCI device + * @interface_regs Pointer to IP interface space (Bar 2) + * @ioidint_space Pointer to IP ID, IO and INT space (Bar 3) + * @mem8_space Pointer to MEM space (Bar 4) + * @access_lock Mutex lock for simultaneous access + * + */ +struct tpci200_infos { + struct pci_dev *pdev; + struct pci_device_id *id_table; + void *interface_regs; + void *ioidint_space; + void *mem8_space; + spinlock_t access_lock; + struct ipack_bus_device drv; +}; +struct tpci200_board { + struct list_head list; + unsigned int number; + struct mutex mutex; + struct tpci200_slot *slots; + struct tpci200_infos *info; +}; + +#endif /* _TPCI200_H_ */ -- cgit v0.10.2 From ba4dc61fe8c545a5d6a68b63616776556b771f51 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Wed, 9 May 2012 15:27:21 +0200 Subject: Staging: ipack: add support for IP-OCTAL mezzanine board IP-OCTAL is a 8-channels serial port device. There are several models one per each standard: RS-232, RS-422, RS-485. This driver can manage all of them. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/Kconfig b/drivers/staging/ipack/Kconfig index 30b28fe..619c149 100644 --- a/drivers/staging/ipack/Kconfig +++ b/drivers/staging/ipack/Kconfig @@ -9,6 +9,8 @@ menuconfig IPACK_BUS if IPACK_BUS +source "drivers/staging/ipack/devices/Kconfig" + source "drivers/staging/ipack/bridges/Kconfig" endif # IPACK diff --git a/drivers/staging/ipack/Makefile b/drivers/staging/ipack/Makefile index 59b8762..85ff223 100644 --- a/drivers/staging/ipack/Makefile +++ b/drivers/staging/ipack/Makefile @@ -2,4 +2,5 @@ # Makefile for the IPACK bridge device drivers. # obj-$(CONFIG_IPACK_BUS) += ipack.o +obj-y += devices/ obj-y += bridges/ diff --git a/drivers/staging/ipack/TODO b/drivers/staging/ipack/TODO index d5a5735..11828ed 100644 --- a/drivers/staging/ipack/TODO +++ b/drivers/staging/ipack/TODO @@ -22,6 +22,15 @@ TPCI-200 * It has a linked list with the tpci200 devices it is managing. Get rid of it and use driver_for_each_device() instead. +IP-OCTAL +-------- + +* It has a linked list which saves the devices it is currently + managing. It should use the driver_for_each_device() function. It is not there + due to the impossibility of using container_of macro to recover the + corresponding "struct ipoctal" because the attribute "struct ipack_device" is + a pointer. This code should be refactored. + Ipack ----- diff --git a/drivers/staging/ipack/devices/Kconfig b/drivers/staging/ipack/devices/Kconfig new file mode 100644 index 0000000..39f7188 --- /dev/null +++ b/drivers/staging/ipack/devices/Kconfig @@ -0,0 +1,7 @@ +config SERIAL_IPOCTAL + tristate "IndustryPack IP-OCTAL uart support" + depends on IPACK_BUS + help + This driver supports the IPOCTAL serial port device for the IndustryPack bus. + default n + diff --git a/drivers/staging/ipack/devices/Makefile b/drivers/staging/ipack/devices/Makefile new file mode 100644 index 0000000..6de18bd --- /dev/null +++ b/drivers/staging/ipack/devices/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_SERIAL_IPOCTAL) += ipoctal.o diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c new file mode 100644 index 0000000..15c0c6b --- /dev/null +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -0,0 +1,893 @@ +/** + * ipoctal.c + * + * driver for the GE IP-OCTAL boards + * Copyright (c) 2009 Nicolas Serafini, EIC2 SA + * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez , CERN + * Copyright (c) 2012 Samuel Iglesias Gonsalvez , Igalia + * + * 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. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../ipack.h" +#include "ipoctal.h" +#include "scc2698.h" + +#define IP_OCTAL_MANUFACTURER_ID 0xF0 +#define IP_OCTAL_232_ID 0x22 +#define IP_OCTAL_422_ID 0x2A +#define IP_OCTAL_485_ID 0x48 + +#define IP_OCTAL_ID_SPACE_VECTOR 0x41 +#define IP_OCTAL_NB_BLOCKS 4 + +static struct ipack_driver driver; +static const struct tty_operations ipoctal_fops; + +struct ipoctal { + struct list_head list; + struct ipack_device *dev; + unsigned int board_id; + struct scc2698_channel *chan_regs; + struct scc2698_block *block_regs; + struct ipoctal_stats chan_stats[NR_CHANNELS]; + char *buffer[NR_CHANNELS]; + unsigned int nb_bytes[NR_CHANNELS]; + unsigned int count_wr[NR_CHANNELS]; + struct ipoctal_config chan_config[NR_CHANNELS]; + wait_queue_head_t queue[NR_CHANNELS]; + unsigned short error_flag[NR_CHANNELS]; + spinlock_t lock[NR_CHANNELS]; + unsigned int pointer_read[NR_CHANNELS]; + unsigned int pointer_write[NR_CHANNELS]; + atomic_t open[NR_CHANNELS]; + unsigned char write; + struct tty_port tty_port[NR_CHANNELS]; + struct tty_driver *tty_drv; +}; + +/* Linked list to save the registered devices */ +static LIST_HEAD(ipoctal_list); + +static inline void ipoctal_write_io_reg(struct ipoctal *ipoctal, + unsigned char *dest, + unsigned char value) +{ + unsigned long offset; + + offset = ((void *) dest) - ipoctal->dev->io_space.address; + ipoctal->dev->ops->write8(ipoctal->dev, IPACK_IO_SPACE, offset, value); +} + +static inline void ipoctal_write_cr_cmd(struct ipoctal *ipoctal, + unsigned char *dest, + unsigned char value) +{ + ipoctal_write_io_reg(ipoctal, dest, value); +} + +static inline unsigned char ipoctal_read_io_reg(struct ipoctal *ipoctal, + unsigned char *src) +{ + unsigned long offset; + unsigned char value; + + offset = ((void *) src) - ipoctal->dev->io_space.address; + ipoctal->dev->ops->read8(ipoctal->dev, IPACK_IO_SPACE, offset, &value); + return value; +} + +static struct ipoctal *ipoctal_find_board(struct tty_struct *tty) +{ + struct ipoctal *p; + + list_for_each_entry(p, &ipoctal_list, list) { + if (tty->driver->major == p->tty_drv->major) + return p; + } + + return NULL; +} + +static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty) +{ + struct ipoctal *ipoctal; + int channel = tty->index; + + ipoctal = ipoctal_find_board(tty); + + if (ipoctal == NULL) { + pr_err("Device not found. Major %d\n", tty->driver->major); + return -ENODEV; + } + + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_ENABLE_RX); + tty->driver_data = ipoctal; + + return 0; +} + +static int ipoctal_open(struct tty_struct *tty, struct file *file) +{ + int channel = tty->index; + int res; + struct ipoctal *ipoctal; + + ipoctal = ipoctal_find_board(tty); + + if (ipoctal == NULL) { + pr_err("Device not found. Major %d\n", tty->driver->major); + return -ENODEV; + } + + if (atomic_read(&ipoctal->open[channel])) + return -EBUSY; + + res = tty_port_open(&ipoctal->tty_port[channel], tty, file); + if (res) + return res; + + atomic_inc(&ipoctal->open[channel]); + return 0; +} + +static void ipoctal_reset_stats(struct ipoctal_stats *stats) +{ + stats->tx = 0; + stats->rx = 0; + stats->rcv_break = 0; + stats->framing_err = 0; + stats->overrun_err = 0; + stats->parity_err = 0; +} + +static void ipoctal_free_channel(struct tty_struct *tty) +{ + int channel = tty->index; + struct ipoctal *ipoctal = tty->driver_data; + + if (ipoctal == NULL) + return; + + ipoctal_reset_stats(&ipoctal->chan_stats[channel]); + ipoctal->pointer_read[channel] = 0; + ipoctal->pointer_write[channel] = 0; + ipoctal->nb_bytes[channel] = 0; +} + +static void ipoctal_close(struct tty_struct *tty, struct file *filp) +{ + int channel = tty->index; + struct ipoctal *ipoctal = tty->driver_data; + + tty_port_close(&ipoctal->tty_port[channel], tty, filp); + + if (atomic_dec_and_test(&ipoctal->open[channel])) + ipoctal_free_channel(tty); +} + +static int ipoctal_get_icount(struct tty_struct *tty, + struct serial_icounter_struct *icount) +{ + struct ipoctal *ipoctal = tty->driver_data; + int channel = tty->index; + + icount->cts = 0; + icount->dsr = 0; + icount->rng = 0; + icount->dcd = 0; + icount->rx = ipoctal->chan_stats[channel].rx; + icount->tx = ipoctal->chan_stats[channel].tx; + icount->frame = ipoctal->chan_stats[channel].framing_err; + icount->parity = ipoctal->chan_stats[channel].parity_err; + icount->brk = ipoctal->chan_stats[channel].rcv_break; + return 0; +} + +static int ipoctal_irq_handler(void *arg) +{ + unsigned int channel; + unsigned int block; + unsigned char isr; + unsigned char sr; + unsigned char isr_tx_rdy, isr_rx_rdy; + unsigned char value; + unsigned char flag; + struct tty_struct *tty; + struct ipoctal *ipoctal = (struct ipoctal *) arg; + + /* Check all channels */ + for (channel = 0; channel < NR_CHANNELS; channel++) { + /* If there is no client, skip the check */ + if (!atomic_read(&ipoctal->open[channel])) + continue; + + tty = tty_port_tty_get(&ipoctal->tty_port[channel]); + if (!tty) + continue; + + /* + * The HW is organized in pair of channels. + * See which register we need to read from + */ + block = channel / 2; + isr = ipoctal_read_io_reg(ipoctal, + &ipoctal->block_regs[block].u.r.isr); + sr = ipoctal_read_io_reg(ipoctal, + &ipoctal->chan_regs[channel].u.r.sr); + + if ((channel % 2) == 1) { + isr_tx_rdy = isr & ISR_TxRDY_B; + isr_rx_rdy = isr & ISR_RxRDY_FFULL_B; + } else { + isr_tx_rdy = isr & ISR_TxRDY_A; + isr_rx_rdy = isr & ISR_RxRDY_FFULL_A; + } + + /* In case of RS-485, change from TX to RX when finishing TX. + * Half-duplex. + */ + if ((ipoctal->board_id == IP_OCTAL_485_ID) && + (sr & SR_TX_EMPTY) && + (ipoctal->nb_bytes[channel] == 0)) { + ipoctal_write_io_reg(ipoctal, + &ipoctal->chan_regs[channel].u.w.cr, + CR_DISABLE_TX); + ipoctal_write_cr_cmd(ipoctal, + &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_NEGATE_RTSN); + ipoctal_write_io_reg(ipoctal, + &ipoctal->chan_regs[channel].u.w.cr, + CR_ENABLE_RX); + ipoctal->write = 1; + wake_up_interruptible(&ipoctal->queue[channel]); + } + + /* RX data */ + if (isr_rx_rdy && (sr & SR_RX_READY)) { + value = ipoctal_read_io_reg(ipoctal, + &ipoctal->chan_regs[channel].u.r.rhr); + flag = TTY_NORMAL; + + /* Error: count statistics */ + if (sr & SR_ERROR) { + ipoctal_write_cr_cmd(ipoctal, + &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_RESET_ERR_STATUS); + + if (sr & SR_OVERRUN_ERROR) { + ipoctal->error_flag[channel] |= UART_OVERRUN; + ipoctal->chan_stats[channel].overrun_err++; + /* Overrun doesn't affect the current character*/ + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + } + if (sr & SR_PARITY_ERROR) { + ipoctal->error_flag[channel] |= UART_PARITY; + ipoctal->chan_stats[channel].parity_err++; + flag = TTY_PARITY; + } + if (sr & SR_FRAMING_ERROR) { + ipoctal->error_flag[channel] |= UART_FRAMING; + ipoctal->chan_stats[channel].framing_err++; + flag = TTY_FRAME; + } + if (sr & SR_RECEIVED_BREAK) { + ipoctal->error_flag[channel] |= UART_BREAK; + ipoctal->chan_stats[channel].rcv_break++; + flag = TTY_BREAK; + } + } + + tty_insert_flip_char(tty, value, flag); + } + + /* TX of each character */ + if (isr_tx_rdy && (sr & SR_TX_READY)) { + unsigned int *pointer_write = + &ipoctal->pointer_write[channel]; + + if (ipoctal->nb_bytes[channel] <= 0) { + ipoctal->nb_bytes[channel] = 0; + continue; + } + spin_lock(&ipoctal->lock[channel]); + value = ipoctal->buffer[channel][*pointer_write]; + ipoctal_write_io_reg(ipoctal, + &ipoctal->chan_regs[channel].u.w.thr, + value); + ipoctal->chan_stats[channel].tx++; + ipoctal->count_wr[channel]++; + (*pointer_write)++; + *pointer_write = *pointer_write % PAGE_SIZE; + ipoctal->nb_bytes[channel]--; + spin_unlock(&ipoctal->lock[channel]); + + if ((ipoctal->nb_bytes[channel] == 0) && + (waitqueue_active(&ipoctal->queue[channel]))) { + + if (ipoctal->board_id != IP_OCTAL_485_ID) { + ipoctal->write = 1; + wake_up_interruptible(&ipoctal->queue[channel]); + } + } + } + + tty_flip_buffer_push(tty); + tty_kref_put(tty); + } + return IRQ_HANDLED; +} + +static int ipoctal_check_model(struct ipack_device *dev, unsigned char *id) +{ + unsigned char manufacturerID; + unsigned char board_id; + + dev->ops->read8(dev, IPACK_ID_SPACE, + IPACK_IDPROM_OFFSET_MANUFACTURER_ID, &manufacturerID); + if (manufacturerID != IP_OCTAL_MANUFACTURER_ID) + return -ENODEV; + + dev->ops->read8(dev, IPACK_ID_SPACE, + IPACK_IDPROM_OFFSET_MODEL, (unsigned char *)&board_id); + + switch (board_id) { + case IP_OCTAL_232_ID: + case IP_OCTAL_422_ID: + case IP_OCTAL_485_ID: + *id = board_id; + break; + default: + return -ENODEV; + } + + return 0; +} + +static const struct tty_port_operations ipoctal_tty_port_ops = { + .dtr_rts = NULL, + .activate = ipoctal_port_activate, +}; + +static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, + unsigned int slot, unsigned int vector) +{ + int res = 0; + int i; + struct tty_driver *tty; + char name[20]; + unsigned char board_id; + + res = ipoctal->dev->ops->map_space(ipoctal->dev, 0, IPACK_ID_SPACE); + if (res) { + pr_err("Unable to map slot [%d:%d] ID space!\n", bus_nr, slot); + return res; + } + + res = ipoctal_check_model(ipoctal->dev, &board_id); + if (res) { + ipoctal->dev->ops->unmap_space(ipoctal->dev, IPACK_ID_SPACE); + goto out_unregister_id_space; + } + ipoctal->board_id = board_id; + + res = ipoctal->dev->ops->map_space(ipoctal->dev, 0, IPACK_IO_SPACE); + if (res) { + pr_err("Unable to map slot [%d:%d] IO space!\n", bus_nr, slot); + goto out_unregister_id_space; + } + + res = ipoctal->dev->ops->map_space(ipoctal->dev, + 0x8000, IPACK_MEM_SPACE); + if (res) { + pr_err("Unable to map slot [%d:%d] MEM space!\n", bus_nr, slot); + goto out_unregister_io_space; + } + + /* Save the virtual address to access the registers easily */ + ipoctal->chan_regs = + (struct scc2698_channel *) ipoctal->dev->io_space.address; + ipoctal->block_regs = + (struct scc2698_block *) ipoctal->dev->io_space.address; + + /* Disable RX and TX before touching anything */ + for (i = 0; i < NR_CHANNELS ; i++) { + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[i].u.w.cr, + CR_DISABLE_RX | CR_DISABLE_TX); + } + + for (i = 0; i < IP_OCTAL_NB_BLOCKS; i++) { + ipoctal_write_io_reg(ipoctal, + &ipoctal->block_regs[i].u.w.acr, + ACR_BRG_SET2); + ipoctal_write_io_reg(ipoctal, + &ipoctal->block_regs[i].u.w.opcr, + OPCR_MPP_OUTPUT | OPCR_MPOa_RTSN | + OPCR_MPOb_RTSN); + ipoctal_write_io_reg(ipoctal, + &ipoctal->block_regs[i].u.w.imr, + IMR_TxRDY_A | IMR_RxRDY_FFULL_A | + IMR_DELTA_BREAK_A | IMR_TxRDY_B | + IMR_RxRDY_FFULL_B | IMR_DELTA_BREAK_B); + } + + /* + * IP-OCTAL has different addresses to copy its IRQ vector. + * Depending of the carrier these addresses are accesible or not. + * More info in the datasheet. + */ + ipoctal->dev->ops->request_irq(ipoctal->dev, vector, + ipoctal_irq_handler, ipoctal); + ipoctal->dev->ops->write8(ipoctal->dev, IPACK_ID_SPACE, 0, vector); + + /* Register the TTY device */ + + /* Each IP-OCTAL channel is a TTY port */ + tty = alloc_tty_driver(NR_CHANNELS); + + if (!tty) { + res = -ENOMEM; + goto out_unregister_slot_unmap; + } + + /* Fill struct tty_driver with ipoctal data */ + tty->owner = THIS_MODULE; + tty->driver_name = "ipoctal"; + sprintf(name, "ipoctal.%d.%d.", bus_nr, slot); + tty->name = name; + tty->major = 0; + + tty->minor_start = 0; + tty->type = TTY_DRIVER_TYPE_SERIAL; + tty->subtype = SERIAL_TYPE_NORMAL; + tty->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; + tty->init_termios = tty_std_termios; + tty->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + tty->init_termios.c_ispeed = 9600; + tty->init_termios.c_ospeed = 9600; + + tty_set_operations(tty, &ipoctal_fops); + res = tty_register_driver(tty); + if (res) { + pr_err("Can't register tty driver.\n"); + put_tty_driver(tty); + goto out_unregister_slot_unmap; + } + + /* Save struct tty_driver for use it when uninstalling the device */ + ipoctal->tty_drv = tty; + + for (i = 0; i < NR_CHANNELS; i++) { + tty_port_init(&ipoctal->tty_port[i]); + tty_port_alloc_xmit_buf(&ipoctal->tty_port[i]); + ipoctal->tty_port[i].ops = &ipoctal_tty_port_ops; + + ipoctal_reset_stats(&ipoctal->chan_stats[i]); + ipoctal->nb_bytes[i] = 0; + init_waitqueue_head(&ipoctal->queue[i]); + ipoctal->error_flag[i] = UART_NOERROR; + + spin_lock_init(&ipoctal->lock[i]); + ipoctal->pointer_read[i] = 0; + ipoctal->pointer_write[i] = 0; + ipoctal->nb_bytes[i] = 0; + tty_register_device(tty, i, NULL); + + /* + * Enable again the RX. TX will be enabled when + * there is something to send + */ + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[i].u.w.cr, + CR_ENABLE_RX); + } + + return 0; + +out_unregister_slot_unmap: + ipoctal->dev->ops->unmap_space(ipoctal->dev, IPACK_ID_SPACE); +out_unregister_io_space: + ipoctal->dev->ops->unmap_space(ipoctal->dev, IPACK_IO_SPACE); +out_unregister_id_space: + ipoctal->dev->ops->unmap_space(ipoctal->dev, IPACK_MEM_SPACE); + return res; +} + +static inline int ipoctal_copy_write_buffer(struct ipoctal *ipoctal, + unsigned int channel, + const unsigned char *buf, + int count) +{ + unsigned long flags; + int i; + unsigned int *pointer_read = &ipoctal->pointer_read[channel]; + + /* Copy the bytes from the user buffer to the internal one */ + for (i = 0; i < count; i++) { + if (i <= (PAGE_SIZE - ipoctal->nb_bytes[channel])) { + spin_lock_irqsave(&ipoctal->lock[channel], flags); + ipoctal->tty_port[channel].xmit_buf[*pointer_read] = buf[i]; + *pointer_read = (*pointer_read + 1) % PAGE_SIZE; + ipoctal->nb_bytes[channel]++; + spin_unlock_irqrestore(&ipoctal->lock[channel], flags); + } else { + break; + } + } + return i; +} + +static int ipoctal_write(struct ipoctal *ipoctal, unsigned int channel, + const unsigned char *buf, int count) +{ + ipoctal->nb_bytes[channel] = 0; + ipoctal->count_wr[channel] = 0; + + ipoctal_copy_write_buffer(ipoctal, channel, buf, count); + + ipoctal->error_flag[channel] = UART_NOERROR; + + /* As the IP-OCTAL 485 only supports half duplex, do it manually */ + if (ipoctal->board_id == IP_OCTAL_485_ID) { + ipoctal_write_io_reg(ipoctal, + &ipoctal->chan_regs[channel].u.w.cr, + CR_DISABLE_RX); + ipoctal_write_cr_cmd(ipoctal, + &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_ASSERT_RTSN); + } + + /* + * Send a packet and then disable TX to avoid failure after several send + * operations + */ + ipoctal_write_io_reg(ipoctal, + &ipoctal->chan_regs[channel].u.w.cr, + CR_ENABLE_TX); + wait_event_interruptible(ipoctal->queue[channel], ipoctal->write); + ipoctal_write_io_reg(ipoctal, + &ipoctal->chan_regs[channel].u.w.cr, + CR_DISABLE_TX); + + ipoctal->write = 0; + return ipoctal->count_wr[channel]; +} + +static int ipoctal_write_tty(struct tty_struct *tty, + const unsigned char *buf, int count) +{ + unsigned int channel = tty->index; + struct ipoctal *ipoctal = tty->driver_data; + + return ipoctal_write(ipoctal, channel, buf, count); +} + +static int ipoctal_write_room(struct tty_struct *tty) +{ + int channel = tty->index; + struct ipoctal *ipoctal = tty->driver_data; + + return PAGE_SIZE - ipoctal->nb_bytes[channel]; +} + +static int ipoctal_chars_in_buffer(struct tty_struct *tty) +{ + int channel = tty->index; + struct ipoctal *ipoctal = tty->driver_data; + + return ipoctal->nb_bytes[channel]; +} + +static void ipoctal_set_termios(struct tty_struct *tty, + struct ktermios *old_termios) +{ + unsigned int cflag; + unsigned char mr1 = 0; + unsigned char mr2 = 0; + unsigned char csr = 0; + unsigned int channel = tty->index; + struct ipoctal *ipoctal = tty->driver_data; + speed_t baud; + + cflag = tty->termios->c_cflag; + + /* Disable and reset everything before change the setup */ + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_DISABLE_RX | CR_DISABLE_TX); + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_RESET_RX); + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_RESET_TX); + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_RESET_ERR_STATUS); + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_RESET_MR); + + /* Set Bits per chars */ + switch (cflag & CSIZE) { + case CS6: + mr1 |= MR1_CHRL_6_BITS; + break; + case CS7: + mr1 |= MR1_CHRL_7_BITS; + break; + case CS8: + default: + mr1 |= MR1_CHRL_8_BITS; + /* By default, select CS8 */ + tty->termios->c_cflag = (cflag & ~CSIZE) | CS8; + break; + } + + /* Set Parity */ + if (cflag & PARENB) + if (cflag & PARODD) + mr1 |= MR1_PARITY_ON | MR1_PARITY_ODD; + else + mr1 |= MR1_PARITY_ON | MR1_PARITY_EVEN; + else + mr1 |= MR1_PARITY_OFF; + + /* Mark or space parity is not supported */ + tty->termios->c_cflag &= ~CMSPAR; + + /* Set stop bits */ + if (cflag & CSTOPB) + mr2 |= MR2_STOP_BITS_LENGTH_2; + else + mr2 |= MR2_STOP_BITS_LENGTH_1; + + /* Set the flow control */ + switch (ipoctal->board_id) { + case IP_OCTAL_232_ID: + if (cflag & CRTSCTS) { + mr1 |= MR1_RxRTS_CONTROL_ON; + mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_ON; + ipoctal->chan_config[channel].flow_control = 1; + } else { + mr1 |= MR1_RxRTS_CONTROL_OFF; + mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF; + ipoctal->chan_config[channel].flow_control = 0; + } + break; + case IP_OCTAL_422_ID: + mr1 |= MR1_RxRTS_CONTROL_OFF; + mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF; + ipoctal->chan_config[channel].flow_control = 0; + break; + case IP_OCTAL_485_ID: + mr1 |= MR1_RxRTS_CONTROL_OFF; + mr2 |= MR2_TxRTS_CONTROL_ON | MR2_CTS_ENABLE_TX_OFF; + ipoctal->chan_config[channel].flow_control = 0; + break; + default: + return; + break; + } + + baud = tty_get_baud_rate(tty); + tty_termios_encode_baud_rate(tty->termios, baud, baud); + + /* Set baud rate */ + switch (tty->termios->c_ospeed) { + case 75: + csr |= TX_CLK_75 | RX_CLK_75; + break; + case 110: + csr |= TX_CLK_110 | RX_CLK_110; + break; + case 150: + csr |= TX_CLK_150 | RX_CLK_150; + break; + case 300: + csr |= TX_CLK_300 | RX_CLK_300; + break; + case 600: + csr |= TX_CLK_600 | RX_CLK_600; + break; + case 1200: + csr |= TX_CLK_1200 | RX_CLK_1200; + break; + case 1800: + csr |= TX_CLK_1800 | RX_CLK_1800; + break; + case 2000: + csr |= TX_CLK_2000 | RX_CLK_2000; + break; + case 2400: + csr |= TX_CLK_2400 | RX_CLK_2400; + break; + case 4800: + csr |= TX_CLK_4800 | RX_CLK_4800; + break; + case 9600: + csr |= TX_CLK_9600 | RX_CLK_9600; + break; + case 19200: + csr |= TX_CLK_19200 | RX_CLK_19200; + break; + case 38400: + default: + csr |= TX_CLK_38400 | RX_CLK_38400; + /* In case of default, we establish 38400 bps */ + tty_termios_encode_baud_rate(tty->termios, 38400, 38400); + break; + } + + mr1 |= MR1_ERROR_CHAR; + mr1 |= MR1_RxINT_RxRDY; + + /* Write the control registers */ + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.mr, mr1); + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.mr, mr2); + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.csr, csr); + + /* save the setup in the structure */ + ipoctal->chan_config[channel].baud = tty_get_baud_rate(tty); + ipoctal->chan_config[channel].bits_per_char = cflag & CSIZE; + ipoctal->chan_config[channel].parity = cflag & PARENB; + ipoctal->chan_config[channel].stop_bits = cflag & CSTOPB; + + /* Enable again the RX */ + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_ENABLE_RX); +} + +static void ipoctal_hangup(struct tty_struct *tty) +{ + unsigned long flags; + int channel = tty->index; + struct ipoctal *ipoctal = tty->driver_data; + + if (ipoctal == NULL) + return; + + spin_lock_irqsave(&ipoctal->lock[channel], flags); + ipoctal->nb_bytes[channel] = 0; + ipoctal->pointer_read[channel] = 0; + ipoctal->pointer_write[channel] = 0; + spin_unlock_irqrestore(&ipoctal->lock[channel], flags); + + tty_port_hangup(&ipoctal->tty_port[channel]); + + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_DISABLE_RX | CR_DISABLE_TX); + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_RESET_RX); + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_RESET_TX); + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_RESET_ERR_STATUS); + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_RESET_MR); + + clear_bit(ASYNCB_INITIALIZED, &ipoctal->tty_port[channel].flags); + wake_up_interruptible(&ipoctal->tty_port[channel].open_wait); +} + +static const struct tty_operations ipoctal_fops = { + .ioctl = NULL, + .open = ipoctal_open, + .close = ipoctal_close, + .write = ipoctal_write_tty, + .set_termios = ipoctal_set_termios, + .write_room = ipoctal_write_room, + .chars_in_buffer = ipoctal_chars_in_buffer, + .get_icount = ipoctal_get_icount, + .hangup = ipoctal_hangup, +}; + +static int ipoctal_match(struct ipack_device *dev) +{ + int res; + unsigned char board_id; + + res = dev->ops->map_space(dev, 0, IPACK_ID_SPACE); + if (res) + return res; + + res = ipoctal_check_model(dev, &board_id); + dev->ops->unmap_space(dev, IPACK_ID_SPACE); + return res; +} + +static int ipoctal_probe(struct ipack_device *dev) +{ + int res; + struct ipoctal *ipoctal; + + ipoctal = kzalloc(sizeof(struct ipoctal), GFP_KERNEL); + if (ipoctal == NULL) + return -ENOMEM; + + ipoctal->dev = dev; + res = ipoctal_inst_slot(ipoctal, dev->bus_nr, dev->slot, dev->irq); + if (res) + goto out_uninst; + + list_add_tail(&ipoctal->list, &ipoctal_list); + return 0; + +out_uninst: + kfree(ipoctal); + return res; +} + +static void __ipoctal_remove(struct ipoctal *ipoctal) +{ + int i; + + for (i = 0; i < NR_CHANNELS; i++) { + tty_unregister_device(ipoctal->tty_drv, i); + tty_port_free_xmit_buf(&ipoctal->tty_port[i]); + } + + tty_unregister_driver(ipoctal->tty_drv); + put_tty_driver(ipoctal->tty_drv); + + /* Tell the carrier board to free all the resources for this device */ + if (ipoctal->dev->ops->remove_device != NULL) + ipoctal->dev->ops->remove_device(ipoctal->dev); + + list_del(&ipoctal->list); + kfree(ipoctal); +} + +static void ipoctal_remove(struct ipack_device *device) +{ + struct ipoctal *ipoctal, *next; + + list_for_each_entry_safe(ipoctal, next, &ipoctal_list, list) { + if (ipoctal->dev == device) + __ipoctal_remove(ipoctal); + } +} + +static struct ipack_driver_ops ipoctal_drv_ops = { + .match = ipoctal_match, + .probe = ipoctal_probe, + .remove = ipoctal_remove, +}; + +static int __init ipoctal_init(void) +{ + driver.owner = THIS_MODULE; + driver.ops = &ipoctal_drv_ops; + driver.driver.name = KBUILD_MODNAME; + ipack_driver_register(&driver); + return 0; +} + +static void __exit ipoctal_exit(void) +{ + struct ipoctal *p, *next; + + list_for_each_entry_safe(p, next, &ipoctal_list, list) + __ipoctal_remove(p); + + ipack_driver_unregister(&driver); +} + +MODULE_DESCRIPTION("IP-Octal 232, 422 and 485 device driver"); +MODULE_LICENSE("GPL"); + +module_init(ipoctal_init); +module_exit(ipoctal_exit); diff --git a/drivers/staging/ipack/devices/ipoctal.h b/drivers/staging/ipack/devices/ipoctal.h new file mode 100644 index 0000000..7c5d211 --- /dev/null +++ b/drivers/staging/ipack/devices/ipoctal.h @@ -0,0 +1,81 @@ +/** + * ipoctal.h + * + * driver for the IPOCTAL boards + * Copyright (c) 2009 Nicolas Serafini, EIC2 SA + * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez , CERN + * Copyright (c) 2012 Samuel Iglesias Gonsalvez , Igalia + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#ifndef _IPOCTAL_H +#define _IPOCTAL_H_ + +#define NR_CHANNELS 8 +#define IPOCTAL_MAX_BOARDS 16 +#define MAX_DEVICES (NR_CHANNELS * IPOCTAL_MAX_BOARDS) +#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) + +/** + * enum uart_parity_e - UART supported parity. + */ +enum uart_parity_e { + UART_NONE = 0, + UART_ODD = 1, + UART_EVEN = 2, +}; + +/** + * enum uart_error - UART error type + * + */ +enum uart_error { + UART_NOERROR = 0, /* No error during transmission */ + UART_TIMEOUT = 1 << 0, /* Timeout error */ + UART_OVERRUN = 1 << 1, /* Overrun error */ + UART_PARITY = 1 << 2, /* Parity error */ + UART_FRAMING = 1 << 3, /* Framing error */ + UART_BREAK = 1 << 4, /* Received break */ +}; + +/** + * struct ipoctal_config - Serial configuration + * + * @baud: Baud rate + * @stop_bits: Stop bits (1 or 2) + * @bits_per_char: data size in bits + * @parity + * @flow_control: Flow control management (RTS/CTS) (0 disabled, 1 enabled) + */ +struct ipoctal_config { + unsigned int baud; + unsigned int stop_bits; + unsigned int bits_per_char; + unsigned short parity; + unsigned int flow_control; +}; + +/** + * struct ipoctal_stats -- Stats since last reset + * + * @tx: Number of transmitted bytes + * @rx: Number of received bytes + * @overrun: Number of overrun errors + * @parity_err: Number of parity errors + * @framing_err: Number of framing errors + * @rcv_break: Number of break received + */ +struct ipoctal_stats { + unsigned long tx; + unsigned long rx; + unsigned long overrun_err; + unsigned long parity_err; + unsigned long framing_err; + unsigned long rcv_break; +}; + +#endif /* _IPOCTAL_H_ */ diff --git a/drivers/staging/ipack/devices/scc2698.h b/drivers/staging/ipack/devices/scc2698.h new file mode 100644 index 0000000..e683019 --- /dev/null +++ b/drivers/staging/ipack/devices/scc2698.h @@ -0,0 +1,229 @@ +/* + * scc2698.h + * + * driver for the IPOCTAL boards + * Copyright (c) 2009 Nicolas Serafini, EIC2 SA + * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez , CERN + * Copyright (c) 2012 Samuel Iglesias Gonsalvez , Igalia + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#ifndef SCC2698_H_ +#define SCC2698_H_ + +/* + * struct scc2698_channel - Channel access to scc2698 IO + * + * dn value are only spacer. + * + */ +struct scc2698_channel { + union { + struct { + unsigned char d0, mr; /* Mode register 1/2*/ + unsigned char d1, sr; /* Status register */ + unsigned char d2, r1; /* reserved */ + unsigned char d3, rhr; /* Receive holding register (R) */ + unsigned char junk[8]; /* other crap for block control */ + } r; /* Read access */ + struct { + unsigned char d0, mr; /* Mode register 1/2 */ + unsigned char d1, csr; /* Clock select register */ + unsigned char d2, cr; /* Command register */ + unsigned char d3, thr; /* Transmit holding register */ + unsigned char junk[8]; /* other crap for block control */ + } w; /* Write access */ + } u; +}; + +/* + * struct scc2698_block - Block access to scc2698 IO + * + * The scc2698 contain 4 block. + * Each block containt two channel a and b. + * dn value are only spacer. + * + */ +struct scc2698_block { + union { + struct { + unsigned char d0, mra; /* Mode register 1/2 (a) */ + unsigned char d1, sra; /* Status register (a) */ + unsigned char d2, r1; /* reserved */ + unsigned char d3, rhra; /* Receive holding register (a) */ + unsigned char d4, ipcr; /* Input port change register of block */ + unsigned char d5, isr; /* Interrupt status register of block */ + unsigned char d6, ctur; /* Counter timer upper register of block */ + unsigned char d7, ctlr; /* Counter timer lower register of block */ + unsigned char d8, mrb; /* Mode register 1/2 (b) */ + unsigned char d9, srb; /* Status register (b) */ + unsigned char da, r2; /* reserved */ + unsigned char db, rhrb; /* Receive holding register (b) */ + unsigned char dc, r3; /* reserved */ + unsigned char dd, ip; /* Input port register of block */ + unsigned char de, ctg; /* Start counter timer of block */ + unsigned char df, cts; /* Stop counter timer of block */ + } r; /* Read access */ + struct { + unsigned char d0, mra; /* Mode register 1/2 (a) */ + unsigned char d1, csra; /* Clock select register (a) */ + unsigned char d2, cra; /* Command register (a) */ + unsigned char d3, thra; /* Transmit holding register (a) */ + unsigned char d4, acr; /* Auxiliary control register of block */ + unsigned char d5, imr; /* Interrupt mask register of block */ + unsigned char d6, ctu; /* Counter timer upper register of block */ + unsigned char d7, ctl; /* Counter timer lower register of block */ + unsigned char d8, mrb; /* Mode register 1/2 (b) */ + unsigned char d9, csrb; /* Clock select register (a) */ + unsigned char da, crb; /* Command register (b) */ + unsigned char db, thrb; /* Transmit holding register (b) */ + unsigned char dc, r1; /* reserved */ + unsigned char dd, opcr; /* Output port configuration register of block */ + unsigned char de, r2; /* reserved */ + unsigned char df, r3; /* reserved */ + } w; /* Write access */ + } u; +} ; + +#define MR1_CHRL_5_BITS (0x0 << 0) +#define MR1_CHRL_6_BITS (0x1 << 0) +#define MR1_CHRL_7_BITS (0x2 << 0) +#define MR1_CHRL_8_BITS (0x3 << 0) +#define MR1_PARITY_EVEN (0x1 << 2) +#define MR1_PARITY_ODD (0x0 << 2) +#define MR1_PARITY_ON (0x0 << 3) +#define MR1_PARITY_FORCE (0x1 << 3) +#define MR1_PARITY_OFF (0x2 << 3) +#define MR1_PARITY_SPECIAL (0x3 << 3) +#define MR1_ERROR_CHAR (0x0 << 5) +#define MR1_ERROR_BLOCK (0x1 << 5) +#define MR1_RxINT_RxRDY (0x0 << 6) +#define MR1_RxINT_FFULL (0x1 << 6) +#define MR1_RxRTS_CONTROL_ON (0x1 << 7) +#define MR1_RxRTS_CONTROL_OFF (0x0 << 7) + +#define MR2_STOP_BITS_LENGTH_1 (0x7 << 0) +#define MR2_STOP_BITS_LENGTH_2 (0xF << 0) +#define MR2_CTS_ENABLE_TX_ON (0x1 << 4) +#define MR2_CTS_ENABLE_TX_OFF (0x0 << 4) +#define MR2_TxRTS_CONTROL_ON (0x1 << 5) +#define MR2_TxRTS_CONTROL_OFF (0x0 << 5) +#define MR2_CH_MODE_NORMAL (0x0 << 6) +#define MR2_CH_MODE_ECHO (0x1 << 6) +#define MR2_CH_MODE_LOCAL (0x2 << 6) +#define MR2_CH_MODE_REMOTE (0x3 << 6) + +#define CR_ENABLE_RX (0x1 << 0) +#define CR_DISABLE_RX (0x1 << 1) +#define CR_ENABLE_TX (0x1 << 2) +#define CR_DISABLE_TX (0x1 << 3) +#define CR_CMD_RESET_MR (0x1 << 4) +#define CR_CMD_RESET_RX (0x2 << 4) +#define CR_CMD_RESET_TX (0x3 << 4) +#define CR_CMD_RESET_ERR_STATUS (0x4 << 4) +#define CR_CMD_RESET_BREAK_CHANGE (0x5 << 4) +#define CR_CMD_START_BREAK (0x6 << 4) +#define CR_CMD_STOP_BREAK (0x7 << 4) +#define CR_CMD_ASSERT_RTSN (0x8 << 4) +#define CR_CMD_NEGATE_RTSN (0x9 << 4) +#define CR_CMD_SET_TIMEOUT_MODE (0xA << 4) +#define CR_CMD_DISABLE_TIMEOUT_MODE (0xC << 4) + +#define SR_RX_READY (0x1 << 0) +#define SR_FIFO_FULL (0x1 << 1) +#define SR_TX_READY (0x1 << 2) +#define SR_TX_EMPTY (0x1 << 3) +#define SR_OVERRUN_ERROR (0x1 << 4) +#define SR_PARITY_ERROR (0x1 << 5) +#define SR_FRAMING_ERROR (0x1 << 6) +#define SR_RECEIVED_BREAK (0x1 << 7) + +#define SR_ERROR (0xF0) + +#define ACR_DELTA_IP0_IRQ_EN (0x1 << 0) +#define ACR_DELTA_IP1_IRQ_EN (0x1 << 1) +#define ACR_DELTA_IP2_IRQ_EN (0x1 << 2) +#define ACR_DELTA_IP3_IRQ_EN (0x1 << 3) +#define ACR_CT_Mask (0x7 << 4) +#define ACR_CExt (0x0 << 4) +#define ACR_CTxCA (0x1 << 4) +#define ACR_CTxCB (0x2 << 4) +#define ACR_CClk16 (0x3 << 4) +#define ACR_TExt (0x4 << 4) +#define ACR_TExt16 (0x5 << 4) +#define ACR_TClk (0x6 << 4) +#define ACR_TClk16 (0x7 << 4) +#define ACR_BRG_SET1 (0x0 << 7) +#define ACR_BRG_SET2 (0x1 << 7) + +#define TX_CLK_75 (0x0 << 0) +#define TX_CLK_110 (0x1 << 0) +#define TX_CLK_38400 (0x2 << 0) +#define TX_CLK_150 (0x3 << 0) +#define TX_CLK_300 (0x4 << 0) +#define TX_CLK_600 (0x5 << 0) +#define TX_CLK_1200 (0x6 << 0) +#define TX_CLK_2000 (0x7 << 0) +#define TX_CLK_2400 (0x8 << 0) +#define TX_CLK_4800 (0x9 << 0) +#define TX_CLK_1800 (0xA << 0) +#define TX_CLK_9600 (0xB << 0) +#define TX_CLK_19200 (0xC << 0) +#define RX_CLK_75 (0x0 << 4) +#define RX_CLK_110 (0x1 << 4) +#define RX_CLK_38400 (0x2 << 4) +#define RX_CLK_150 (0x3 << 4) +#define RX_CLK_300 (0x4 << 4) +#define RX_CLK_600 (0x5 << 4) +#define RX_CLK_1200 (0x6 << 4) +#define RX_CLK_2000 (0x7 << 4) +#define RX_CLK_2400 (0x8 << 4) +#define RX_CLK_4800 (0x9 << 4) +#define RX_CLK_1800 (0xA << 4) +#define RX_CLK_9600 (0xB << 4) +#define RX_CLK_19200 (0xC << 4) + +#define OPCR_MPOa_RTSN (0x0 << 0) +#define OPCR_MPOa_C_TO (0x1 << 0) +#define OPCR_MPOa_TxC1X (0x2 << 0) +#define OPCR_MPOa_TxC16X (0x3 << 0) +#define OPCR_MPOa_RxC1X (0x4 << 0) +#define OPCR_MPOa_RxC16X (0x5 << 0) +#define OPCR_MPOa_TxRDY (0x6 << 0) +#define OPCR_MPOa_RxRDY_FF (0x7 << 0) + +#define OPCR_MPOb_RTSN (0x0 << 4) +#define OPCR_MPOb_C_TO (0x1 << 4) +#define OPCR_MPOb_TxC1X (0x2 << 4) +#define OPCR_MPOb_TxC16X (0x3 << 4) +#define OPCR_MPOb_RxC1X (0x4 << 4) +#define OPCR_MPOb_RxC16X (0x5 << 4) +#define OPCR_MPOb_TxRDY (0x6 << 4) +#define OPCR_MPOb_RxRDY_FF (0x7 << 4) + +#define OPCR_MPP_INPUT (0x0 << 7) +#define OPCR_MPP_OUTPUT (0x1 << 7) + +#define IMR_TxRDY_A (0x1 << 0) +#define IMR_RxRDY_FFULL_A (0x1 << 1) +#define IMR_DELTA_BREAK_A (0x1 << 2) +#define IMR_COUNTER_READY (0x1 << 3) +#define IMR_TxRDY_B (0x1 << 4) +#define IMR_RxRDY_FFULL_B (0x1 << 5) +#define IMR_DELTA_BREAK_B (0x1 << 6) +#define IMR_INPUT_PORT_CHANGE (0x1 << 7) + +#define ISR_TxRDY_A (0x1 << 0) +#define ISR_RxRDY_FFULL_A (0x1 << 1) +#define ISR_DELTA_BREAK_A (0x1 << 2) +#define ISR_COUNTER_READY (0x1 << 3) +#define ISR_TxRDY_B (0x1 << 4) +#define ISR_RxRDY_FFULL_B (0x1 << 5) +#define ISR_DELTA_BREAK_B (0x1 << 6) +#define ISR_INPUT_PORT_CHANGE (0x1 << 7) + +#endif /* SCC2698_H_ */ -- cgit v0.10.2 From 8bdeeb26c57012ea19a3b8fe3aeaecff377ae07d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 10 May 2012 18:18:36 +0300 Subject: Staging: ipack: returning a freed pointer If ipack_device_register() returns an error, then we returned a freed pointer. The caller doesn't use it, but it means we return success to the user instead of returning an error code. I kind of rewrote the error handling in this function as a cleanup. Cc: Samuel Iglesias Gonsalvez Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 6aeb660..ab6ea0a 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -372,7 +372,7 @@ static struct ipack_device *tpci200_slot_register(const char *board_name, unsigned int slot_position) { int found = 0; - struct ipack_device *dev = NULL; + struct ipack_device *dev; struct tpci200_board *tpci200; list_for_each_entry(tpci200, &tpci200_list, list) { @@ -390,16 +390,16 @@ static struct ipack_device *tpci200_slot_register(const char *board_name, if (slot_position >= TPCI200_NB_SLOT) { pr_info("Slot [%s %d:%d] doesn't exist!\n", TPCI200_SHORTNAME, tpci200_number, slot_position); - goto out; + return NULL; } if (mutex_lock_interruptible(&tpci200->mutex)) - goto out; + return NULL; if (tpci200->slots[slot_position].dev != NULL) { pr_err("Slot [%s %d:%d] already installed !\n", TPCI200_SHORTNAME, tpci200_number, slot_position); - goto out_unlock; + goto err_unlock; } dev = kzalloc(sizeof(struct ipack_device), GFP_KERNEL); @@ -407,7 +407,7 @@ static struct ipack_device *tpci200_slot_register(const char *board_name, pr_info("Slot [%s %d:%d] Unable to allocate memory for new slot !\n", TPCI200_SHORTNAME, tpci200_number, slot_position); - goto out_unlock; + goto err_unlock; } if (size > IPACK_BOARD_NAME_SIZE) { @@ -440,15 +440,18 @@ static struct ipack_device *tpci200_slot_register(const char *board_name, dev->ops = &tpci200_bus_ops; tpci200->slots[slot_position].dev = dev; - if (ipack_device_register(dev) < 0) { - tpci200_slot_unregister(dev); - kfree(dev); - } + if (ipack_device_register(dev) < 0) + goto err_unregister; -out_unlock: mutex_unlock(&tpci200->mutex); -out: return dev; + +err_unregister: + tpci200_slot_unregister(dev); + kfree(dev); +err_unlock: + mutex_unlock(&tpci200->mutex); + return NULL; } static ssize_t tpci200_store_board(struct device *pdev, const char *buf, -- cgit v0.10.2 From 3a745b6f471dbd7e057b30e031e476c41c6a2bf8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 10 May 2012 18:19:04 +0300 Subject: Staging: ipack: dereferencing freed memory We free "dev" then dereference it on the next line. Cc: Samuel Iglesias Gonsalvez Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index ab6ea0a..08cd851 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -867,8 +867,8 @@ static int tpci200_slot_unregister(struct ipack_device *dev) return -ERESTARTSYS; ipack_device_unregister(dev); - kfree(dev); tpci200->slots[dev->slot].dev = NULL; + kfree(dev); mutex_unlock(&tpci200->mutex); return 0; -- cgit v0.10.2 From f04f107db843819f0aa1649c4b0340fead28c5c6 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 10 May 2012 09:59:20 +0200 Subject: staging: rts5139: make some functions static in rts51x_scsi.c Signed-off-by: Oleksij Rempel Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_scsi.c b/drivers/staging/rts5139/rts51x_scsi.c index 1591ad7..bf8245f 100644 --- a/drivers/staging/rts5139/rts51x_scsi.c +++ b/drivers/staging/rts5139/rts51x_scsi.c @@ -1465,7 +1465,7 @@ static int ms_format_cmnd(struct scsi_cmnd *srb, struct rts51x_chip *chip) } #ifdef SUPPORT_PCGL_1P18 -int get_ms_information(struct scsi_cmnd *srb, struct rts51x_chip *chip) +static int get_ms_information(struct scsi_cmnd *srb, struct rts51x_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); unsigned int lun = SCSI_LUN(srb); @@ -1626,7 +1626,7 @@ static int sd_extention_cmnd(struct scsi_cmnd *srb, struct rts51x_chip *chip) #endif #ifdef SUPPORT_MAGIC_GATE -int mg_report_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) +static int mg_report_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); unsigned int lun = SCSI_LUN(srb); @@ -1713,7 +1713,7 @@ int mg_report_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) return TRANSPORT_GOOD; } -int mg_send_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) +static int mg_send_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); unsigned int lun = SCSI_LUN(srb); -- cgit v0.10.2 From 12ed793e355726cf3a834c30c8ddd0ae1e8f7a94 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 10 May 2012 09:59:21 +0200 Subject: staging: rts5139: remove unsued *host_info in rts51x_scsi.c Signed-off-by: Oleksij Rempel Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_scsi.c b/drivers/staging/rts5139/rts51x_scsi.c index bf8245f..a5c7a06 100644 --- a/drivers/staging/rts5139/rts51x_scsi.c +++ b/drivers/staging/rts5139/rts51x_scsi.c @@ -1923,11 +1923,6 @@ int rts51x_scsi_handler(struct scsi_cmnd *srb, struct rts51x_chip *chip) * Host functions ***********************************************************************/ -const char *host_info(struct Scsi_Host *host) -{ - return "SCSI emulation for RTS51xx USB driver-based card reader"; -} - int slave_alloc(struct scsi_device *sdev) { /* diff --git a/drivers/staging/rts5139/rts51x_scsi.h b/drivers/staging/rts5139/rts51x_scsi.h index 6ba7273..060d2c2 100644 --- a/drivers/staging/rts5139/rts51x_scsi.h +++ b/drivers/staging/rts5139/rts51x_scsi.h @@ -145,7 +145,6 @@ struct Scsi_Host; struct scsi_device; struct scsi_cmnd; -const char *host_info(struct Scsi_Host *host); int slave_alloc(struct scsi_device *sdev); int slave_configure(struct scsi_device *sdev); int proc_info(struct Scsi_Host *host, char *buffer, -- cgit v0.10.2 From 5085d12749df87ee6df8ac5f60c9b59133a4bfae Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 10 May 2012 09:59:22 +0200 Subject: staging: rts5139: make some functions static in rts51x_transport.* Signed-off-by: Oleksij Rempel Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_transport.c b/drivers/staging/rts5139/rts51x_transport.c index e402a3c..56fba00 100644 --- a/drivers/staging/rts5139/rts51x_transport.c +++ b/drivers/staging/rts5139/rts51x_transport.c @@ -120,7 +120,7 @@ unsigned int rts51x_access_sglist(unsigned char *buffer, return cnt; } -unsigned int rts51x_access_xfer_buf(unsigned char *buffer, +static unsigned int rts51x_access_xfer_buf(unsigned char *buffer, unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **sgptr, unsigned int *offset, enum xfer_buf_dir dir) @@ -252,6 +252,8 @@ static int rts51x_msg_common(struct rts51x_chip *chip, struct urb *urb, return status; } +static int rts51x_clear_halt(struct rts51x_chip *chip, unsigned int pipe); + /* * Interpret the results of a URB transfer */ @@ -359,7 +361,7 @@ int rts51x_ctrl_transfer(struct rts51x_chip *chip, unsigned int pipe, rts51x->current_urb->actual_length); } -int rts51x_clear_halt(struct rts51x_chip *chip, unsigned int pipe) +static int rts51x_clear_halt(struct rts51x_chip *chip, unsigned int pipe) { int result; int endp = usb_pipeendpoint(pipe); @@ -394,14 +396,14 @@ static void rts51x_sg_clean(struct usb_sg_request *io) io->dev = NULL; } -int rts51x_sg_init(struct usb_sg_request *io, struct usb_device *dev, +static int rts51x_sg_init(struct usb_sg_request *io, struct usb_device *dev, unsigned pipe, unsigned period, struct scatterlist *sg, int nents, size_t length, gfp_t mem_flags) { return usb_sg_init(io, dev, pipe, period, sg, nents, length, mem_flags); } -int rts51x_sg_wait(struct usb_sg_request *io, int timeout) +static int rts51x_sg_wait(struct usb_sg_request *io, int timeout) { long timeleft; int i; @@ -532,7 +534,8 @@ static int rts51x_bulk_transfer_sglist(struct rts51x_chip *chip, chip->usb->current_sg.bytes); } -int rts51x_bulk_transfer_buf(struct rts51x_chip *chip, unsigned int pipe, +static int rts51x_bulk_transfer_buf(struct rts51x_chip *chip, + unsigned int pipe, void *buf, unsigned int length, unsigned int *act_len, int timeout) { diff --git a/drivers/staging/rts5139/rts51x_transport.h b/drivers/staging/rts5139/rts51x_transport.h index 9dd556e..ed6b8b2 100644 --- a/drivers/staging/rts5139/rts51x_transport.h +++ b/drivers/staging/rts5139/rts51x_transport.h @@ -40,11 +40,6 @@ unsigned int rts51x_access_sglist(unsigned char *buffer, unsigned int buflen, void *sglist, void **sgptr, unsigned int *offset, enum xfer_buf_dir dir); -unsigned int rts51x_access_xfer_buf(unsigned char *buffer, unsigned int buflen, - struct scsi_cmnd *srb, - struct scatterlist **sgptr, - unsigned int *offset, - enum xfer_buf_dir dir); void rts51x_set_xfer_buf(unsigned char *buffer, unsigned int buflen, struct scsi_cmnd *srb); void rts51x_get_xfer_buf(unsigned char *buffer, unsigned int buflen, @@ -53,7 +48,6 @@ void rts51x_get_xfer_buf(unsigned char *buffer, unsigned int buflen, int rts51x_ctrl_transfer(struct rts51x_chip *chip, unsigned int pipe, u8 request, u8 requesttype, u16 value, u16 index, void *data, u16 size, int timeout); -int rts51x_clear_halt(struct rts51x_chip *chip, unsigned int pipe); int rts51x_transfer_data(struct rts51x_chip *chip, unsigned int pipe, void *buf, unsigned int len, int use_sg, unsigned int *act_len, int timeout); -- cgit v0.10.2 From 231a1a25eb9ccf3ac57f1908500a8d08ba28a62c Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 10 May 2012 09:59:23 +0200 Subject: staging: rts5139: remove unused rts51x_reset_pipe in rts51x_transport.* Signed-off-by: Oleksij Rempel Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_transport.c b/drivers/staging/rts5139/rts51x_transport.c index 56fba00..70adff4 100644 --- a/drivers/staging/rts5139/rts51x_transport.c +++ b/drivers/staging/rts5139/rts51x_transport.c @@ -380,11 +380,6 @@ static int rts51x_clear_halt(struct rts51x_chip *chip, unsigned int pipe) return STATUS_SUCCESS; } -int rts51x_reset_pipe(struct rts51x_chip *chip, char pipe) -{ - return rts51x_clear_halt(chip, pipe); -} - static void rts51x_sg_clean(struct usb_sg_request *io) { if (io->urbs) { diff --git a/drivers/staging/rts5139/rts51x_transport.h b/drivers/staging/rts5139/rts51x_transport.h index ed6b8b2..024f115 100644 --- a/drivers/staging/rts5139/rts51x_transport.h +++ b/drivers/staging/rts5139/rts51x_transport.h @@ -56,12 +56,6 @@ int rts51x_transfer_data_partial(struct rts51x_chip *chip, unsigned int pipe, unsigned int len, int use_sg, unsigned int *act_len, int timeout); -/* whichPipe: - * 0: bulk in pipe - * 1: bulk out pipe - * 2: intr in pipe */ -int rts51x_reset_pipe(struct rts51x_chip *chip, char pipe); - #ifndef POLLING_IN_THREAD int rts51x_start_epc_transfer(struct rts51x_chip *chip); void rts51x_cancel_epc_transfer(struct rts51x_chip *chip); -- cgit v0.10.2 From 2ff4ff54a1d7f54ec587fe2eca737d5cbf32686b Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 10 May 2012 09:59:24 +0200 Subject: staging: rts5139: remove soft_reset_sd_card in sd_cprm.c Signed-off-by: Oleksij Rempel Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/sd_cprm.c b/drivers/staging/rts5139/sd_cprm.c index ba4d189..55e3286 100644 --- a/drivers/staging/rts5139/sd_cprm.c +++ b/drivers/staging/rts5139/sd_cprm.c @@ -77,11 +77,6 @@ static inline int get_rsp_type(u8 rsp_code, u8 *rsp_type, int *rsp_len) return STATUS_SUCCESS; } -int soft_reset_sd_card(struct rts51x_chip *chip) -{ - return reset_sd(chip); -} - int ext_sd_send_cmd_get_rsp(struct rts51x_chip *chip, u8 cmd_idx, u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, int special_check) @@ -1041,7 +1036,7 @@ int sd_hw_rst(struct scsi_cmnd *srb, struct rts51x_chip *chip) case 1: /* reset CMD(CMD0) and Initialization * (without SD Card Power Off -> ON) */ - retval = soft_reset_sd_card(chip); + retval = reset_sd(chip); if (retval != STATUS_SUCCESS) { set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); sd_card->pre_cmd_err = 1; -- cgit v0.10.2 From 6b7571799409a1b453787e9b3b3fddfd52fdae82 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 10 May 2012 09:59:25 +0200 Subject: staging: rts5139: make some functions static in sd.* Signed-off-by: Oleksij Rempel Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/sd.c b/drivers/staging/rts5139/sd.c index 0395bc3..68ad969 100644 --- a/drivers/staging/rts5139/sd.c +++ b/drivers/staging/rts5139/sd.c @@ -704,7 +704,7 @@ int sd_select_card(struct rts51x_chip *chip, int select) return STATUS_SUCCESS; } -int sd_wait_currentstate_dataready(struct rts51x_chip *chip, u8 statechk, +static int sd_wait_currentstate_dataready(struct rts51x_chip *chip, u8 statechk, u8 rdychk, u16 pollingcnt) { struct sd_info *sd_card = &(chip->sd_card); @@ -2885,7 +2885,7 @@ static int wait_data_buf_ready(struct rts51x_chip *chip) TRACE_RET(chip, STATUS_FAIL); } -void sd_stop_seq_mode(struct rts51x_chip *chip) +static void sd_stop_seq_mode(struct rts51x_chip *chip) { struct sd_info *sd_card = &(chip->sd_card); int retval; @@ -3179,7 +3179,7 @@ void sd_cleanup_work(struct rts51x_chip *chip) } } -inline void sd_fill_power_off_card3v3(struct rts51x_chip *chip) +static inline void sd_fill_power_off_card3v3(struct rts51x_chip *chip) { rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, SD_CLK_EN, 0); @@ -3201,7 +3201,7 @@ inline void sd_fill_power_off_card3v3(struct rts51x_chip *chip) } } -int sd_power_off_card3v3(struct rts51x_chip *chip) +static int sd_power_off_card3v3(struct rts51x_chip *chip) { int retval; diff --git a/drivers/staging/rts5139/sd.h b/drivers/staging/rts5139/sd.h index 44b6fc4..de155d8 100644 --- a/drivers/staging/rts5139/sd.h +++ b/drivers/staging/rts5139/sd.h @@ -259,11 +259,9 @@ struct timing_phase_path { int sd_select_card(struct rts51x_chip *chip, int select); int reset_sd_card(struct rts51x_chip *chip); int sd_switch_clock(struct rts51x_chip *chip); -void sd_stop_seq_mode(struct rts51x_chip *chip); int sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, u16 sector_cnt); void sd_cleanup_work(struct rts51x_chip *chip); -int sd_power_off_card3v3(struct rts51x_chip *chip); int release_sd_card(struct rts51x_chip *chip); #ifdef SUPPORT_CPRM -- cgit v0.10.2 From b9914e7d863fef232d95fafa8c8fc4393a32148a Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 10 May 2012 09:59:26 +0200 Subject: staging: rts5139: make some functions static in sd_cprm.c Signed-off-by: Oleksij Rempel Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/sd_cprm.c b/drivers/staging/rts5139/sd_cprm.c index 55e3286..f8c6071 100644 --- a/drivers/staging/rts5139/sd_cprm.c +++ b/drivers/staging/rts5139/sd_cprm.c @@ -77,7 +77,7 @@ static inline int get_rsp_type(u8 rsp_code, u8 *rsp_type, int *rsp_len) return STATUS_SUCCESS; } -int ext_sd_send_cmd_get_rsp(struct rts51x_chip *chip, u8 cmd_idx, +static int ext_sd_send_cmd_get_rsp(struct rts51x_chip *chip, u8 cmd_idx, u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, int special_check) { @@ -224,7 +224,7 @@ RTY_SEND_CMD: return STATUS_SUCCESS; } -int ext_sd_get_rsp(struct rts51x_chip *chip, int len, u8 *rsp, u8 rsp_type) +static int ext_sd_get_rsp(struct rts51x_chip *chip, int len, u8 *rsp, u8 rsp_type) { int retval, rsp_len; u16 reg_addr; -- cgit v0.10.2 From 1db67664dc9342aee79e5a88f104400d5be42410 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 10 May 2012 09:59:27 +0200 Subject: staging: rts5139: make some functions static in xd.c Signed-off-by: Oleksij Rempel Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/xd.c b/drivers/staging/rts5139/xd.c index 7f2748c..09f1b4c 100644 --- a/drivers/staging/rts5139/xd.c +++ b/drivers/staging/rts5139/xd.c @@ -862,6 +862,8 @@ static void xd_set_l2p_tbl(struct rts51x_chip *chip, int zone_no, u16 log_off, zone->l2p_table[log_off] = phy_off; } +static int xd_delay_write(struct rts51x_chip *chip); + static u32 xd_get_l2p_tbl(struct rts51x_chip *chip, int zone_no, u16 log_off) { struct xd_info *xd_card = &(chip->xd_card); @@ -1822,7 +1824,7 @@ Fail: TRACE_RET(chip, STATUS_FAIL); } -int xd_delay_write(struct rts51x_chip *chip) +static int xd_delay_write(struct rts51x_chip *chip) { struct xd_info *xd_card = &(chip->xd_card); struct xd_delay_write_tag *delay_write = &(xd_card->delay_write); @@ -2091,7 +2093,7 @@ void xd_cleanup_work(struct rts51x_chip *chip) } } -int xd_power_off_card3v3(struct rts51x_chip *chip) +static int xd_power_off_card3v3(struct rts51x_chip *chip) { int retval; diff --git a/drivers/staging/rts5139/xd.h b/drivers/staging/rts5139/xd.h index fa69590..55e4205 100644 --- a/drivers/staging/rts5139/xd.h +++ b/drivers/staging/rts5139/xd.h @@ -182,12 +182,10 @@ #define CIS1_9 (256 + 9) int reset_xd_card(struct rts51x_chip *chip); -int xd_delay_write(struct rts51x_chip *chip); int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, u16 sector_cnt); void xd_free_l2p_tbl(struct rts51x_chip *chip); void xd_cleanup_work(struct rts51x_chip *chip); -int xd_power_off_card3v3(struct rts51x_chip *chip); int release_xd_card(struct rts51x_chip *chip); #endif /* __RTS51X_XD_H */ -- cgit v0.10.2 From 29b11698765e3735ec56598a8dadb010850f2b9b Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 10 May 2012 09:59:28 +0200 Subject: staging: rts5139: remove unused xd_check_err_code in xd.c Signed-off-by: Oleksij Rempel Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/xd.c b/drivers/staging/rts5139/xd.c index 09f1b4c..ef8872d 100644 --- a/drivers/staging/rts5139/xd.c +++ b/drivers/staging/rts5139/xd.c @@ -47,13 +47,6 @@ static inline void xd_set_err_code(struct rts51x_chip *chip, u8 err_code) xd_card->err_code = err_code; } -static inline int xd_check_err_code(struct rts51x_chip *chip, u8 err_code) -{ - struct xd_info *xd_card = &(chip->xd_card); - - return (xd_card->err_code == err_code); -} - static int xd_set_init_para(struct rts51x_chip *chip) { struct xd_info *xd_card = &(chip->xd_card); -- cgit v0.10.2 From 8ce9002e0b02d655d4d69665a7be98848a4258b7 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 10 May 2012 09:59:29 +0200 Subject: staging: rts5139: make some functions static in ms.c and ms_mg.c Signed-off-by: Oleksij Rempel Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/ms.c b/drivers/staging/rts5139/ms.c index 02aad2d..b593e66 100644 --- a/drivers/staging/rts5139/ms.c +++ b/drivers/staging/rts5139/ms.c @@ -2680,7 +2680,7 @@ static int mspro_set_rw_cmd(struct rts51x_chip *chip, u32 start_sec, return STATUS_SUCCESS; } -void mspro_stop_seq_mode(struct rts51x_chip *chip) +static void mspro_stop_seq_mode(struct rts51x_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); int retval; @@ -4135,7 +4135,7 @@ void ms_cleanup_work(struct rts51x_chip *chip) } } -int ms_power_off_card3v3(struct rts51x_chip *chip) +static int ms_power_off_card3v3(struct rts51x_chip *chip) { int retval; diff --git a/drivers/staging/rts5139/ms.h b/drivers/staging/rts5139/ms.h index 3ce1dc9..0321d06 100644 --- a/drivers/staging/rts5139/ms.h +++ b/drivers/staging/rts5139/ms.h @@ -234,7 +234,6 @@ void mspro_polling_format_status(struct rts51x_chip *chip); void mspro_format_sense(struct rts51x_chip *chip, unsigned int lun); -void mspro_stop_seq_mode(struct rts51x_chip *chip); int reset_ms_card(struct rts51x_chip *chip); int ms_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, u16 sector_cnt); @@ -242,7 +241,6 @@ int mspro_format(struct scsi_cmnd *srb, struct rts51x_chip *chip, int short_data_len, int quick_format); void ms_free_l2p_tbl(struct rts51x_chip *chip); void ms_cleanup_work(struct rts51x_chip *chip); -int ms_power_off_card3v3(struct rts51x_chip *chip); int release_ms_card(struct rts51x_chip *chip); int ms_delay_write(struct rts51x_chip *chip); diff --git a/drivers/staging/rts5139/ms_mg.c b/drivers/staging/rts5139/ms_mg.c index 154b523..6b74aff 100644 --- a/drivers/staging/rts5139/ms_mg.c +++ b/drivers/staging/rts5139/ms_mg.c @@ -38,7 +38,7 @@ #ifdef SUPPORT_MAGIC_GATE -int mg_check_int_error(struct rts51x_chip *chip) +static int mg_check_int_error(struct rts51x_chip *chip) { u8 value; -- cgit v0.10.2 From 9002ebc2e8704f478c8816a458461cb325693f93 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 10 May 2012 09:59:30 +0200 Subject: staging: rts5139: remove disabled code in rts51x_card.c Signed-off-by: Oleksij Rempel Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_card.c b/drivers/staging/rts5139/rts51x_card.c index 73032ef..4192c3b 100644 --- a/drivers/staging/rts5139/rts51x_card.c +++ b/drivers/staging/rts5139/rts51x_card.c @@ -827,16 +827,7 @@ int card_power_on(struct rts51x_chip *chip, u8 card) if ((card == SD_CARD) || (card == XD_CARD)) { RTS51X_WRITE_REG(chip, CARD_PWR_CTL, mask | LDO3318_PWR_MASK, val1 | LDO_SUSPEND); - /* RTS51X_WRITE_REG(chip, CARD_PWR_CTL, - LDO3318_PWR_MASK, LDO_SUSPEND); */ } - /* else if(card==XD_CARD) - { - RTS51X_WRITE_REG(chip, CARD_PWR_CTL, - mask|LDO3318_PWR_MASK, val1|LDO_SUSPEND); - //RTS51X_WRITE_REG(chip, CARD_PWR_CTL, - // LDO3318_PWR_MASK, LDO_SUSPEND); - } */ else { #endif RTS51X_WRITE_REG(chip, CARD_PWR_CTL, mask, val1); -- cgit v0.10.2 From ecfbe1dc96827daa774569d186ae57abec6030da Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 10 May 2012 09:59:31 +0200 Subject: staging: rts5139: remove unused led_blink_speed variable Signed-off-by: Oleksij Rempel Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x.c b/drivers/staging/rts5139/rts51x.c index 7726a1a..97b3a2b 100644 --- a/drivers/staging/rts5139/rts51x.c +++ b/drivers/staging/rts5139/rts51x.c @@ -478,7 +478,6 @@ static void rts51x_init_options(struct rts51x_chip *chip) { struct rts51x_option *option = &(chip->option); - option->led_blink_speed = 7; option->mspro_formatter_enable = 1; option->fpga_sd_sdr104_clk = CLK_100; diff --git a/drivers/staging/rts5139/rts51x_chip.h b/drivers/staging/rts5139/rts51x_chip.h index 65c3ee9..b2a4b96 100644 --- a/drivers/staging/rts5139/rts51x_chip.h +++ b/drivers/staging/rts5139/rts51x_chip.h @@ -313,8 +313,6 @@ struct sense_data_t { #define SUPPORT_UHS50_MMC44 0x40 struct rts51x_option { - u8 led_blink_speed; - int mspro_formatter_enable; /* card clock expected by user for fpga platform */ -- cgit v0.10.2 From a61a85b11b1c66a0437a0a7014a58b6f9241ac78 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 10 May 2012 09:59:32 +0200 Subject: staging: rts5139: remove unused option->needs_remote_wakeup module parametr needs_remote_wakeup sets option->needs_remote_wakeup and rts51x->pusb_intf->needs_remote_wakeup the second may be used, the first one is never used Signed-off-by: Oleksij Rempel Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x.c b/drivers/staging/rts5139/rts51x.c index 97b3a2b..acf74bf 100644 --- a/drivers/staging/rts5139/rts51x.c +++ b/drivers/staging/rts5139/rts51x.c @@ -505,7 +505,6 @@ static void rts51x_init_options(struct rts51x_chip *chip) option->ss_en = ss_en; option->ss_delay = ss_delay; - option->needs_remote_wakeup = needs_remote_wakeup; option->auto_delink_en = auto_delink_en; diff --git a/drivers/staging/rts5139/rts51x_chip.h b/drivers/staging/rts5139/rts51x_chip.h index b2a4b96..d52ff26 100644 --- a/drivers/staging/rts5139/rts51x_chip.h +++ b/drivers/staging/rts5139/rts51x_chip.h @@ -356,7 +356,6 @@ struct rts51x_option { int ss_en; /* Interval to enter SS from IDLE state (second) */ int ss_delay; - int needs_remote_wakeup; u8 ww_enable; /* sangdy2010-08-03:add for remote wakeup */ /* Enable SSC clock */ -- cgit v0.10.2 From 205fefe32e0df582dcd33e02bbcf7ad58256156c Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 10 May 2012 09:59:33 +0200 Subject: staging: rts5139: remove unused rcc_fail_flag variable Signed-off-by: Oleksij Rempel Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x.c b/drivers/staging/rts5139/rts51x.c index acf74bf..1084997 100644 --- a/drivers/staging/rts5139/rts51x.c +++ b/drivers/staging/rts5139/rts51x.c @@ -516,7 +516,6 @@ static void rts51x_init_options(struct rts51x_chip *chip) option->rts5129_D3318_off_enable = 0; option->sd20_pad_drive = 0; option->reset_or_rw_fail_set_pad_drive = 1; - option->rcc_fail_flag = 0; option->rcc_bug_fix_en = 1; option->debounce_num = 2; option->polling_time = 100; diff --git a/drivers/staging/rts5139/rts51x_chip.h b/drivers/staging/rts5139/rts51x_chip.h index d52ff26..b3389aa 100644 --- a/drivers/staging/rts5139/rts51x_chip.h +++ b/drivers/staging/rts5139/rts51x_chip.h @@ -379,7 +379,6 @@ struct rts51x_option { /*if reset or rw fail,then set SD20 pad drive again */ u8 reset_or_rw_fail_set_pad_drive; - u8 rcc_fail_flag; /* add to indicate whether rcc bug happen */ u8 rcc_bug_fix_en; /* if set,then support fixing rcc bug */ u8 debounce_num; /* debounce number */ int polling_time; /* polling delay time */ -- cgit v0.10.2 From 711c273c07bba69fd85cf7bfc6565420ff2fc7b6 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 10 May 2012 09:59:34 +0200 Subject: staging: rts5139: remove unused rcc_bug_fix_en Signed-off-by: Oleksij Rempel Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x.c b/drivers/staging/rts5139/rts51x.c index 1084997..7d2c93c 100644 --- a/drivers/staging/rts5139/rts51x.c +++ b/drivers/staging/rts5139/rts51x.c @@ -516,7 +516,6 @@ static void rts51x_init_options(struct rts51x_chip *chip) option->rts5129_D3318_off_enable = 0; option->sd20_pad_drive = 0; option->reset_or_rw_fail_set_pad_drive = 1; - option->rcc_bug_fix_en = 1; option->debounce_num = 2; option->polling_time = 100; option->led_toggle_interval = 6; diff --git a/drivers/staging/rts5139/rts51x_chip.c b/drivers/staging/rts5139/rts51x_chip.c index 3a10310..a21f490 100644 --- a/drivers/staging/rts5139/rts51x_chip.c +++ b/drivers/staging/rts5139/rts51x_chip.c @@ -164,9 +164,6 @@ int rts51x_init_chip(struct rts51x_chip *chip) RTS51X_SET_STAT(chip, STAT_RUN); RTS51X_READ_REG(chip, HW_VERSION, &val); - if ((val & 0x0f) >= 2) - chip->option.rcc_bug_fix_en = 0; - RTS51X_DEBUGP("rcc bug fix enable:%d\n", chip->option.rcc_bug_fix_en); RTS51X_DEBUGP("HW_VERSION: 0x%x\n", val); if (val & FPGA_VER) { chip->asic_code = 0; diff --git a/drivers/staging/rts5139/rts51x_chip.h b/drivers/staging/rts5139/rts51x_chip.h index b3389aa..2cb7575 100644 --- a/drivers/staging/rts5139/rts51x_chip.h +++ b/drivers/staging/rts5139/rts51x_chip.h @@ -379,7 +379,6 @@ struct rts51x_option { /*if reset or rw fail,then set SD20 pad drive again */ u8 reset_or_rw_fail_set_pad_drive; - u8 rcc_bug_fix_en; /* if set,then support fixing rcc bug */ u8 debounce_num; /* debounce number */ int polling_time; /* polling delay time */ u8 led_toggle_interval; /* used to control led toggle speed */ -- cgit v0.10.2 From 19434aa179fe107831f436bbc8e21aa4c4fb0757 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 10 May 2012 09:59:35 +0200 Subject: staging: rts5139: remove unused polling_time variable Signed-off-by: Oleksij Rempel Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x.c b/drivers/staging/rts5139/rts51x.c index 7d2c93c..c3fe7dd 100644 --- a/drivers/staging/rts5139/rts51x.c +++ b/drivers/staging/rts5139/rts51x.c @@ -517,7 +517,6 @@ static void rts51x_init_options(struct rts51x_chip *chip) option->sd20_pad_drive = 0; option->reset_or_rw_fail_set_pad_drive = 1; option->debounce_num = 2; - option->polling_time = 100; option->led_toggle_interval = 6; option->xd_rwn_step = 0; option->sd_send_status_en = 0; diff --git a/drivers/staging/rts5139/rts51x_chip.h b/drivers/staging/rts5139/rts51x_chip.h index 2cb7575..175ea79 100644 --- a/drivers/staging/rts5139/rts51x_chip.h +++ b/drivers/staging/rts5139/rts51x_chip.h @@ -380,7 +380,6 @@ struct rts51x_option { u8 reset_or_rw_fail_set_pad_drive; u8 debounce_num; /* debounce number */ - int polling_time; /* polling delay time */ u8 led_toggle_interval; /* used to control led toggle speed */ int xd_rwn_step; u8 sd_send_status_en; -- cgit v0.10.2 From 0ed226100aa04eb01c816279ca34640794226e8a Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 10 May 2012 09:59:36 +0200 Subject: staging: rts5139: remove unused TUNE_SD18_* Signed-off-by: Oleksij Rempel Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_card.h b/drivers/staging/rts5139/rts51x_card.h index ef9cc89..c5c03cc 100644 --- a/drivers/staging/rts5139/rts51x_card.h +++ b/drivers/staging/rts5139/rts51x_card.h @@ -204,13 +204,7 @@ /* LDO_POWER_CFG */ #define TUNE_SD18_MASK 0x1C -#define TUNE_SD18_1V7 0x00 #define TUNE_SD18_1V8 (0x01 << 2) -#define TUNE_SD18_1V9 (0x02 << 2) -#define TUNE_SD18_2V0 (0x03 << 2) -#define TUNE_SD18_2V7 (0x04 << 2) -#define TUNE_SD18_2V8 (0x05 << 2) -#define TUNE_SD18_2V9 (0x06 << 2) #define TUNE_SD18_3V3 (0x07 << 2) /* XD_CP_WAITTIME */ -- cgit v0.10.2 From c76dde55f1978e34122030093d38e75375e1f66e Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 10 May 2012 09:59:37 +0200 Subject: staging: rts5139: remove unused variable in rts51x.h Signed-off-by: Oleksij Rempel Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x.h b/drivers/staging/rts5139/rts51x.h index 2d2b315..ecc0109 100644 --- a/drivers/staging/rts5139/rts51x.h +++ b/drivers/staging/rts5139/rts51x.h @@ -47,7 +47,6 @@ #define RTS51X_DESC "Realtek RTS5139/29 USB card reader driver" #define RTS51X_NAME "rts5139" #define RTS51X_CTL_THREAD "rts5139-control" -#define RTS51X_SCAN_THREAD "rts5139-scan" #define RTS51X_POLLING_THREAD "rts5139-polling" #define POLLING_IN_THREAD @@ -65,8 +64,6 @@ do { \ /* Size of the DMA-mapped I/O buffer */ #define RTS51X_IOBUF_SIZE 1024 -/* Size of the autosense data buffer */ -#define RTS51X_SENSE_SIZE 18 /* Dynamic bitflag definitions (dflags): used in set_bit() etc. */ #define FLIDX_URB_ACTIVE 0 /* current_urb is in use */ @@ -75,7 +72,6 @@ do { \ #define FLIDX_DISCONNECTING 3 /* disconnect in progress */ #define FLIDX_RESETTING 4 /* device reset in progress */ #define FLIDX_TIMED_OUT 5 /* SCSI midlayer timed out */ -#define FLIDX_DONT_SCAN 6 /* don't scan (disconnect) */ struct rts51x_chip; -- cgit v0.10.2 From 39d65739be5e9a45427d8d2871c0cd32394b8a9a Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 10 May 2012 09:59:38 +0200 Subject: staging: rts5139: remove unused variable in rts51x_chip.h the SENSE_TYPE_FORMAT_IN_PROGRESS was checked by rts51x_scsi.c but never set. Signed-off-by: Oleksij Rempel Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_chip.h b/drivers/staging/rts5139/rts51x_chip.h index 175ea79..6755816 100644 --- a/drivers/staging/rts5139/rts51x_chip.h +++ b/drivers/staging/rts5139/rts51x_chip.h @@ -75,7 +75,6 @@ #define MAX_ALLOWED_LUN_CNT 8 #define CMD_BUF_LEN 1024 -#define RSP_BUF_LEN 1024 #define POLLING_INTERVAL 50 /* 50ms */ #define XD_FREE_TABLE_CNT 1200 @@ -122,8 +121,6 @@ #endif #define STATUS_FAIL 1 -#define STATUS_READ_FAIL 2 -#define STATUS_WRITE_FAIL 3 #define STATUS_TIMEDOUT 4 #define STATUS_NOMEM 5 #define STATUS_TRANS_SHORT 6 @@ -133,8 +130,6 @@ #define IDLE_MAX_COUNT 10 #define POLLING_WAIT_CNT 1 -#define DELINK_DELAY 100 -#define LED_TOGGLE_INTERVAL 6 #define LED_GPIO 0 /* package */ @@ -151,8 +146,6 @@ #define TRANSPORT_GOOD 0 /* Transport good, command failed */ #define TRANSPORT_FAILED 1 -/* Command failed, no auto-sense */ -#define TRANSPORT_NO_SENSE 2 /* Transport bad (i.e. device dead) */ #define TRANSPORT_ERROR 3 @@ -189,7 +182,6 @@ struct trace_msg_t { #define SENSE_TYPE_MEDIA_INVALID_CMD_FIELD 6 #define SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR 7 #define SENSE_TYPE_MEDIA_WRITE_ERR 8 -#define SENSE_TYPE_FORMAT_IN_PROGRESS 9 #define SENSE_TYPE_FORMAT_CMD_FAILED 10 #ifdef SUPPORT_MAGIC_GATE /* COPY PROTECTION KEY EXCHANGE FAILURE - KEY NOT ESTABLISHED */ @@ -203,77 +195,25 @@ struct trace_msg_t { #endif /*---- sense key ----*/ -#define ILI 0x20 /* ILI bit is on */ - -#define NO_SENSE 0x00 /* not exist sense key */ -#define RECOVER_ERR 0x01 /* Target/Logical unit is recoverd */ -#define NOT_READY 0x02 /* Logical unit is not ready */ -#define MEDIA_ERR 0x03 /* medium/data error */ -#define HARDWARE_ERR 0x04 /* hardware error */ #define ILGAL_REQ 0x05 /* CDB/parameter/identify msg error */ -#define UNIT_ATTENTION 0x06 /* unit attention condition occur */ -#define DAT_PRTCT 0x07 /* read/write is desable */ -#define BLNC_CHK 0x08 /* find blank/DOF in read */ - /* write to unblank area */ -#define CPY_ABRT 0x0a /* Copy/Compare/Copy&Verify illgal */ -#define ABRT_CMD 0x0b /* Target make the command in error */ -#define EQUAL 0x0c /* Search Data end with Equal */ -#define VLM_OVRFLW 0x0d /* Some data are left in buffer */ -#define MISCMP 0x0e /* find inequality */ /*----------------------------------- SENSE_DATA -----------------------------------*/ -/*---- valid ----*/ -#define SENSE_VALID 0x80 /* Sense data is valid as SCSI2 */ -#define SENSE_INVALID 0x00 /* Sense data is invalid as SCSI2 */ /*---- error code ----*/ #define CUR_ERR 0x70 /* current error */ -#define DEF_ERR 0x71 /* specific command error */ -/*---- sense key Information ----*/ -#define SNSKEYINFO_LEN 3 /* length of sense key information */ +/*---- sense key Infomation ----*/ #define SKSV 0x80 #define CDB_ILLEGAL 0x40 -#define DAT_ILLEGAL 0x00 -#define BPV 0x08 -#define BIT_ILLEGAL0 0 /* bit0 is illegal */ -#define BIT_ILLEGAL1 1 /* bit1 is illegal */ -#define BIT_ILLEGAL2 2 /* bit2 is illegal */ -#define BIT_ILLEGAL3 3 /* bit3 is illegal */ -#define BIT_ILLEGAL4 4 /* bit4 is illegal */ -#define BIT_ILLEGAL5 5 /* bit5 is illegal */ -#define BIT_ILLEGAL6 6 /* bit6 is illegal */ -#define BIT_ILLEGAL7 7 /* bit7 is illegal */ /*---- ASC ----*/ -#define ASC_NO_INFO 0x00 -#define ASC_MISCMP 0x1d #define ASC_INVLD_CDB 0x24 -#define ASC_INVLD_PARA 0x26 -#define ASC_LU_NOT_READY 0x04 -#define ASC_WRITE_ERR 0x0c -#define ASC_READ_ERR 0x11 -#define ASC_LOAD_EJCT_ERR 0x53 -#define ASC_MEDIA_NOT_PRESENT 0x3A -#define ASC_MEDIA_CHANGED 0x28 -#define ASC_MEDIA_IN_PROCESS 0x04 -#define ASC_WRITE_PROTECT 0x27 -#define ASC_LUN_NOT_SUPPORTED 0x25 /*---- ASQC ----*/ -#define ASCQ_NO_INFO 0x00 -#define ASCQ_MEDIA_IN_PROCESS 0x01 -#define ASCQ_MISCMP 0x00 #define ASCQ_INVLD_CDB 0x00 -#define ASCQ_INVLD_PARA 0x02 -#define ASCQ_LU_NOT_READY 0x02 -#define ASCQ_WRITE_ERR 0x02 -#define ASCQ_READ_ERR 0x00 -#define ASCQ_LOAD_EJCT_ERR 0x00 -#define ASCQ_WRITE_PROTECT 0x00 struct sense_data_t { unsigned char err_code; /* error code */ diff --git a/drivers/staging/rts5139/rts51x_scsi.c b/drivers/staging/rts5139/rts51x_scsi.c index a5c7a06..e07a1f4 100644 --- a/drivers/staging/rts5139/rts51x_scsi.c +++ b/drivers/staging/rts5139/rts51x_scsi.c @@ -369,10 +369,6 @@ void set_sense_type(struct rts51x_chip *chip, unsigned int lun, int sense_type) ASC_INVLD_CDB, ASCQ_INVLD_CDB, CDB_ILLEGAL, 1); break; - case SENSE_TYPE_FORMAT_IN_PROGRESS: - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, 0, 0); - break; - case SENSE_TYPE_FORMAT_CMD_FAILED: set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x31, 0x01, 0, 0); break; -- cgit v0.10.2 From 0e545f6d165ad0180b0d04fe1291f6f6268047ff Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 10 May 2012 09:59:39 +0200 Subject: staging: rts5139: remove unused variable option.ww_enable Signed-off-by: Oleksij Rempel Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rts5139/rts51x_chip.c b/drivers/staging/rts5139/rts51x_chip.c index a21f490..db88d7a 100644 --- a/drivers/staging/rts5139/rts51x_chip.c +++ b/drivers/staging/rts5139/rts51x_chip.c @@ -78,20 +78,18 @@ int rts51x_reset_chip(struct rts51x_chip *chip) chip->option.sd20_pad_drive); if (chip->rts5179) rts51x_write_register(chip, CARD_PULL_CTL5, 0x03, 0x01); - if (!chip->option.ww_enable) { - if (CHECK_PKG(chip, LQFP48)) { - rts51x_write_register(chip, CARD_PULL_CTL3, - 0x80, 0x80); - rts51x_write_register(chip, CARD_PULL_CTL6, - 0xf0, 0xA0); - } else { - rts51x_write_register(chip, CARD_PULL_CTL1, - 0x30, 0x20); - rts51x_write_register(chip, CARD_PULL_CTL3, - 0x80, 0x80); - rts51x_write_register(chip, CARD_PULL_CTL6, - 0x0c, 0x08); - } + if (CHECK_PKG(chip, LQFP48)) { + rts51x_write_register(chip, CARD_PULL_CTL3, + 0x80, 0x80); + rts51x_write_register(chip, CARD_PULL_CTL6, + 0xf0, 0xA0); + } else { + rts51x_write_register(chip, CARD_PULL_CTL1, + 0x30, 0x20); + rts51x_write_register(chip, CARD_PULL_CTL3, + 0x80, 0x80); + rts51x_write_register(chip, CARD_PULL_CTL6, + 0x0c, 0x08); } } if (chip->option.sd_ctl & SUPPORT_UHS50_MMC44) { @@ -715,7 +713,7 @@ void rts51x_do_before_power_down(struct rts51x_chip *chip) chip->cur_clk = 0; chip->card_exist = 0; chip->cur_card = 0; - if (chip->asic_code && !chip->option.ww_enable) { + if (chip->asic_code) { if (CHECK_PKG(chip, LQFP48)) { rts51x_write_register(chip, CARD_PULL_CTL3, 0x80, 0x00); rts51x_write_register(chip, CARD_PULL_CTL6, 0xf0, 0x50); diff --git a/drivers/staging/rts5139/rts51x_chip.h b/drivers/staging/rts5139/rts51x_chip.h index 6755816..76e9c1b 100644 --- a/drivers/staging/rts5139/rts51x_chip.h +++ b/drivers/staging/rts5139/rts51x_chip.h @@ -296,7 +296,6 @@ struct rts51x_option { int ss_en; /* Interval to enter SS from IDLE state (second) */ int ss_delay; - u8 ww_enable; /* sangdy2010-08-03:add for remote wakeup */ /* Enable SSC clock */ int ssc_en; -- cgit v0.10.2 From be9a12040f6d1a29b9a7fdec89058edca0dc2c4d Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Wed, 9 May 2012 22:42:45 -0400 Subject: staging: wean rtl8712 off of its ancient duplicate of if_ether.h This driver should not be carrying around ancient copies of headers like for its own use. Mapping it onto the mainline one uncovers no build issues. Cc: Larry Finger Cc: Greg Kroah-Hartman Signed-off-by: Paul Gortmaker diff --git a/drivers/staging/rtl8712/if_ether.h b/drivers/staging/rtl8712/if_ether.h deleted file mode 100644 index 9916b6a..0000000 --- a/drivers/staging/rtl8712/if_ether.h +++ /dev/null @@ -1,141 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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, USA - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * Global definitions for the Ethernet IEEE 802.3 interface. - * - * Version: @(#)if_ether.h 1.0.1a 02/08/94 - * - * Author: Fred N. van Kempen, - * Donald Becker, - * Alan Cox, - * Steve Whitehouse, - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#ifndef _LINUX_IF_ETHER_H -#define _LINUX_IF_ETHER_H - -/* - * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble - * and FCS/CRC (frame check sequence). - */ - -#define ETH_ALEN 6 /* Octets in one ethernet addr */ -#define ETH_HLEN 14 /* Total octets in header. */ -#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */ -#define ETH_DATA_LEN 1500 /* Max. octets in payload */ -#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */ - -/* - * These are the defined Ethernet Protocol ID's. - */ - -#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */ -#define ETH_P_PUP 0x0200 /* Xerox PUP packet */ -#define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */ -#define ETH_P_IP 0x0800 /* Internet Protocol packet */ -#define ETH_P_X25 0x0805 /* CCITT X.25 */ -#define ETH_P_ARP 0x0806 /* Address Resolution packet */ -#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet - * [ NOT AN OFFICIAL ID ] */ -#define ETH_P_IEEEPUP 0x0a00 /* Xerox IEEE802.3 PUP packet */ -#define ETH_P_IEEEPUPAT 0x0a01 /* Xerox IEEE802.3 PUP Addr - * Trans packet */ -#define ETH_P_DEC 0x6000 /* DEC Assigned proto */ -#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */ -#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */ -#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */ -#define ETH_P_LAT 0x6004 /* DEC LAT */ -#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */ -#define ETH_P_CUST 0x6006 /* DEC Customer use */ -#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */ -#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */ -#define ETH_P_ATALK 0x809B /* Appletalk DDP */ -#define ETH_P_AARP 0x80F3 /* Appletalk AARP */ -#define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */ -#define ETH_P_IPX 0x8137 /* IPX over DIX */ -#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */ -#define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */ -#define ETH_P_PPP_SES 0x8864 /* PPPoE session messages */ -#define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */ -#define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport - * over Ethernet - */ - -/* - * Non DIX types. Won't clash for 1500 types. - */ - -#define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */ -#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */ -#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */ -#define ETH_P_802_2 0x0004 /* 802.2 frames */ -#define ETH_P_SNAP 0x0005 /* Internal only */ -#define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */ -#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/ -#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */ -#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */ -#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/ -#define ETH_P_TR_802_2 0x0011i /* 802.2 frames */ -#define ETH_P_MOBITEX 0x0015 /* Mobitex (kaz@cafe.net) */ -#define ETH_P_CONTROL 0x0016 /* Card specific control frames */ -#define ETH_P_IRDA 0x0017 /* Linux-IrDA */ -#define ETH_P_ECONET 0x0018 /* Acorn Econet */ - -/* - * This is an Ethernet frame header. - */ - -struct ethhdr { - unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ - unsigned char h_source[ETH_ALEN]; /* source ether addr */ - unsigned short h_proto; /* packet type ID field */ -}; - -struct _vlan { - unsigned short h_vlan_TCI; /* Encapsulates priority and VLAN ID*/ - unsigned short h_vlan_encapsulated_proto; -}; - - - -#define get_vlan_id(pvlan) ((ntohs((unsigned short)pvlan->h_vlan_TCI)) & 0xfff) -#define get_vlan_priority(pvlan) ((ntohs((unsigned short)\ - pvlan->h_vlan_TCI)) >> 13) -#define get_vlan_encap_proto(pvlan) (ntohs((unsigned short)\ - pvlan->h_vlan_encapsulated_proto)) - - -#endif /* _LINUX_IF_ETHER_H */ - diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c index 5d7217f..3eaaf31 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.c +++ b/drivers/staging/rtl8712/rtl8712_recv.c @@ -28,12 +28,13 @@ #define _RTL8712_RECV_C_ +#include + #include "osdep_service.h" #include "drv_types.h" #include "recv_osdep.h" #include "mlme_osdep.h" #include "ip.h" -#include "if_ether.h" #include "ethernet.h" #include "usb_ops.h" #include "wifi.h" diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c index 5b03b40..7376abb 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.c +++ b/drivers/staging/rtl8712/rtl871x_recv.c @@ -29,6 +29,7 @@ #define _RTL871X_RECV_C_ #include +#include #include #include "osdep_service.h" @@ -36,7 +37,6 @@ #include "recv_osdep.h" #include "mlme_osdep.h" #include "ip.h" -#include "if_ether.h" #include "ethernet.h" #include "usb_ops.h" #include "wifi.h" diff --git a/drivers/staging/rtl8712/xmit_linux.c b/drivers/staging/rtl8712/xmit_linux.c index c970362..d27f652 100644 --- a/drivers/staging/rtl8712/xmit_linux.c +++ b/drivers/staging/rtl8712/xmit_linux.c @@ -29,12 +29,12 @@ #define _XMIT_OSDEP_C_ #include +#include #include "osdep_service.h" #include "drv_types.h" -#include "if_ether.h" #include "ip.h" #include "rtl871x_byteorder.h" #include "wifi.h" -- cgit v0.10.2 From 2046782524aebe7a5683ec62868a0d26c7d889b3 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Wed, 9 May 2012 22:53:32 -0400 Subject: staging: wean rtl8712 off of its ancient duplicate of ip.h This driver should not be carrying around ancient copies of headers like for its own use. Mapping it onto the mainline one uncovers no build issues. Cc: Larry Finger Cc: Greg Kroah-Hartman Signed-off-by: Paul Gortmaker diff --git a/drivers/staging/rtl8712/ip.h b/drivers/staging/rtl8712/ip.h deleted file mode 100644 index f37b0f8..0000000 --- a/drivers/staging/rtl8712/ip.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * Definitions for the IP protocol. - * - * Version: @(#)ip.h 1.0.2 04/28/93 - * - * Authors: Fred N. van Kempen, - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#ifndef _LINUX_IP_H -#define _LINUX_IP_H - -#include "rtl871x_byteorder.h" - -/* SOL_IP socket options */ - -#define IPTOS_TOS_MASK 0x1E -#define IPTOS_TOS(tos) ((tos)&IPTOS_TOS_MASK) -#define IPTOS_LOWDELAY 0x10 -#define IPTOS_THROUGHPUT 0x08 -#define IPTOS_RELIABILITY 0x04 -#define IPTOS_MINCOST 0x02 - -#define IPTOS_PREC_MASK 0xE0 -#define IPTOS_PREC(tos) ((tos)&IPTOS_PREC_MASK) -#define IPTOS_PREC_NETCONTROL 0xe0 -#define IPTOS_PREC_INTERNETCONTROL 0xc0 -#define IPTOS_PREC_CRITIC_ECP 0xa0 -#define IPTOS_PREC_FLASHOVERRIDE 0x80 -#define IPTOS_PREC_FLASH 0x60 -#define IPTOS_PREC_IMMEDIATE 0x40 -#define IPTOS_PREC_PRIORITY 0x20 -#define IPTOS_PREC_ROUTINE 0x00 - -/* IP options */ -#define IPOPT_COPY 0x80 -#define IPOPT_CLASS_MASK 0x60 -#define IPOPT_NUMBER_MASK 0x1f - -#define IPOPT_COPIED(o) ((o)&IPOPT_COPY) -#define IPOPT_CLASS(o) ((o)&IPOPT_CLASS_MASK) -#define IPOPT_NUMBER(o) ((o)&IPOPT_NUMBER_MASK) - -#define IPOPT_CONTROL 0x00 -#define IPOPT_RESERVED1 0x20 -#define IPOPT_MEASUREMENT 0x40 -#define IPOPT_RESERVED2 0x60 - -#define IPOPT_END (0 | IPOPT_CONTROL) -#define IPOPT_NOOP (1 | IPOPT_CONTROL) -#define IPOPT_SEC (2 | IPOPT_CONTROL|IPOPT_COPY) -#define IPOPT_LSRR (3 | IPOPT_CONTROL|IPOPT_COPY) -#define IPOPT_TIMESTAMP (4 | IPOPT_MEASUREMENT) -#define IPOPT_RR (7 | IPOPT_CONTROL) -#define IPOPT_SID (8 | IPOPT_CONTROL | IPOPT_COPY) -#define IPOPT_SSRR (9 | IPOPT_CONTROL | IPOPT_COPY) -#define IPOPT_RA (20 | IPOPT_CONTROL | IPOPT_COPY) - -#define IPVERSION 4 -#define MAXTTL 255 -#define IPDEFTTL 64 - -/* struct timestamp, struct route and MAX_ROUTES are removed. - * - * REASONS: it is clear that nobody used them because: - * - MAX_ROUTES value was wrong. - * - "struct route" was wrong. - * - "struct timestamp" had fatally misaligned bitfields and was completely - * unusable. - */ - -#define IPOPT_OPTVAL 0 -#define IPOPT_OLEN 1 -#define IPOPT_OFFSET 2 -#define IPOPT_MINOFF 4 -#define MAX_IPOPTLEN 40 -#define IPOPT_NOP IPOPT_NOOP -#define IPOPT_EOL IPOPT_END -#define IPOPT_TS IPOPT_TIMESTAMP - -#define IPOPT_TS_TSONLY 0 /* timestamps only */ -#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ -#define IPOPT_TS_PRESPEC 3 /* specified modules only */ - -struct ip_options { - __u32 faddr; /* Saved first hop address */ - unsigned char optlen; - unsigned char srr; - unsigned char rr; - unsigned char ts; - unsigned char is_setbyuser:1, /* Set by setsockopt? */ - is_data:1, /* Options in __data, rather than skb */ - is_strictroute:1, /* Strict source route */ - srr_is_hit:1, /* Packet destination addr was our one*/ - is_changed:1, /* IP checksum more not valid */ - rr_needaddr:1, /* Need to record addr of outgoing dev*/ - ts_needtime:1, /* Need to record timestamp */ - ts_needaddr:1; /* Need to record addr of outgoing dev*/ - unsigned char router_alert; - unsigned char __pad1; - unsigned char __pad2; - unsigned char __data[0]; -}; - -#define optlength(opt) (sizeof(struct ip_options) + opt->optlen) - -struct iphdr { -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u8 ihl:4, - version:4; -#elif defined(__BIG_ENDIAN_BITFIELD) - __u8 version:4, - ihl:4; -#else -#error "Please fix " -#endif - __u8 tos; - __u16 tot_len; - __u16 id; - __u16 frag_off; - __u8 ttl; - __u8 protocol; - __u16 check; - __u32 saddr; - __u32 daddr; - /*The options start here. */ -}; - -#endif /* _LINUX_IP_H */ - diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c index 3eaaf31..8e82ce2 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.c +++ b/drivers/staging/rtl8712/rtl8712_recv.c @@ -29,12 +29,12 @@ #define _RTL8712_RECV_C_ #include +#include #include "osdep_service.h" #include "drv_types.h" #include "recv_osdep.h" #include "mlme_osdep.h" -#include "ip.h" #include "ethernet.h" #include "usb_ops.h" #include "wifi.h" diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c index 7376abb..c9d1743 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.c +++ b/drivers/staging/rtl8712/rtl871x_recv.c @@ -28,6 +28,7 @@ #define _RTL871X_RECV_C_ +#include #include #include #include @@ -36,7 +37,6 @@ #include "drv_types.h" #include "recv_osdep.h" #include "mlme_osdep.h" -#include "ip.h" #include "ethernet.h" #include "usb_ops.h" #include "wifi.h" diff --git a/drivers/staging/rtl8712/xmit_linux.c b/drivers/staging/rtl8712/xmit_linux.c index d27f652..c6943c5 100644 --- a/drivers/staging/rtl8712/xmit_linux.c +++ b/drivers/staging/rtl8712/xmit_linux.c @@ -29,13 +29,12 @@ #define _XMIT_OSDEP_C_ #include +#include #include #include "osdep_service.h" #include "drv_types.h" - -#include "ip.h" #include "rtl871x_byteorder.h" #include "wifi.h" #include "mlme_osdep.h" -- cgit v0.10.2 From 9a0fbbb52ab08017ac51aceef76514799837f4b0 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Wed, 9 May 2012 23:10:54 -0400 Subject: staging: delete all duplicated endian crap from rtl8712 driver This driver had headers like big_endian.h, little_endian.h, swab.h and yet we can throw them all in the trash can and the thing still builds on x86-64 and ppc, just by deleting the references to the deleted files. Cc: Larry Finger Cc: Greg Kroah-Hartman Signed-off-by: Paul Gortmaker diff --git a/drivers/staging/rtl8712/big_endian.h b/drivers/staging/rtl8712/big_endian.h deleted file mode 100644 index b16f8ec..0000000 --- a/drivers/staging/rtl8712/big_endian.h +++ /dev/null @@ -1,94 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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, USA - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _LINUX_BYTEORDER_BIG_ENDIAN_H -#define _LINUX_BYTEORDER_BIG_ENDIAN_H - -#ifndef __BIG_ENDIAN -#define __BIG_ENDIAN 4321 -#endif -#ifndef __BIG_ENDIAN_BITFIELD -#define __BIG_ENDIAN_BITFIELD -#endif - -#include "swab.h" - -#define __constant_htonl(x) ((__u32)(x)) -#define __constant_ntohl(x) ((__u32)(x)) -#define __constant_htons(x) ((__u16)(x)) -#define __constant_ntohs(x) ((__u16)(x)) -#define __constant_cpu_to_le64(x) ___constant_swab64((x)) -#define __constant_le64_to_cpu(x) ___constant_swab64((x)) -#define __constant_cpu_to_le32(x) ___constant_swab32((x)) -#define __constant_le32_to_cpu(x) ___constant_swab32((x)) -#define __constant_cpu_to_le16(x) ___constant_swab16((x)) -#define __constant_le16_to_cpu(x) ___constant_swab16((x)) -#define __constant_cpu_to_be64(x) ((__u64)(x)) -#define __constant_be64_to_cpu(x) ((__u64)(x)) -#define __constant_cpu_to_be32(x) ((__u32)(x)) -#define __constant_be32_to_cpu(x) ((__u32)(x)) -#define __constant_cpu_to_be16(x) ((__u16)(x)) -#define __constant_be16_to_cpu(x) ((__u16)(x)) -#define __cpu_to_le64(x) __swab64((x)) -#define __le64_to_cpu(x) __swab64((x)) -#define __cpu_to_le32(x) __swab32((x)) -#define __le32_to_cpu(x) __swab32((x)) -#define __cpu_to_le16(x) __swab16((x)) -#define __le16_to_cpu(x) __swab16((x)) -#define __cpu_to_be64(x) ((__u64)(x)) -#define __be64_to_cpu(x) ((__u64)(x)) -#define __cpu_to_be32(x) ((__u32)(x)) -#define __be32_to_cpu(x) ((__u32)(x)) -#define __cpu_to_be16(x) ((__u16)(x)) -#define __be16_to_cpu(x) ((__u16)(x)) -#define __cpu_to_le64p(x) __swab64p((x)) -#define __le64_to_cpup(x) __swab64p((x)) -#define __cpu_to_le32p(x) __swab32p((x)) -#define __le32_to_cpup(x) __swab32p((x)) -#define __cpu_to_le16p(x) __swab16p((x)) -#define __le16_to_cpup(x) __swab16p((x)) -#define __cpu_to_be64p(x) (*(__u64 *)(x)) -#define __be64_to_cpup(x) (*(__u64 *)(x)) -#define __cpu_to_be32p(x) (*(__u32 *)(x)) -#define __be32_to_cpup(x) (*(__u32 *)(x)) -#define __cpu_to_be16p(x) (*(__u16 *)(x)) -#define __be16_to_cpup(x) (*(__u16 *)(x)) -#define __cpu_to_le64s(x) __swab64s((x)) -#define __le64_to_cpus(x) __swab64s((x)) -#define __cpu_to_le32s(x) __swab32s((x)) -#define __le32_to_cpus(x) __swab32s((x)) -#define __cpu_to_le16s(x) __swab16s((x)) -#define __le16_to_cpus(x) __swab16s((x)) -#define __cpu_to_be64s(x) do {} while (0) -#define __be64_to_cpus(x) do {} while (0) -#define __cpu_to_be32s(x) do {} while (0) -#define __be32_to_cpus(x) do {} while (0) -#define __cpu_to_be16s(x) do {} while (0) -#define __be16_to_cpus(x) do {} while (0) - -#include "generic.h" - -#endif /* _LINUX_BYTEORDER_BIG_ENDIAN_H */ - diff --git a/drivers/staging/rtl8712/generic.h b/drivers/staging/rtl8712/generic.h deleted file mode 100644 index 8868c9f..0000000 --- a/drivers/staging/rtl8712/generic.h +++ /dev/null @@ -1,178 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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, USA - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _LINUX_BYTEORDER_GENERIC_H -#define _LINUX_BYTEORDER_GENERIC_H - -/* - * linux/byteorder_generic.h - * Generic Byte-reordering support - * - * Francois-Rene Rideau 19970707 - * gathered all the good ideas from all asm-foo/byteorder.h into one file, - * cleaned them up. - * I hope it is compliant with non-GCC compilers. - * I decided to put __BYTEORDER_HAS_U64__ in byteorder.h, - * because I wasn't sure it would be ok to put it in types.h - * Upgraded it to 2.1.43 - * Francois-Rene Rideau 19971012 - * Upgraded it to 2.1.57 - * to please Linus T., replaced huge #ifdef's between little/big endian - * by nestedly #include'd files. - * Francois-Rene Rideau 19971205 - * Made it to 2.1.71; now a facelift: - * Put files under include/linux/byteorder/ - * Split swab from generic support. - * - * TODO: - * = Regular kernel maintainers could also replace all these manual - * byteswap macros that remain, disseminated among drivers, - * after some grep or the sources... - * = Linus might want to rename all these macros and files to fit his taste, - * to fit his personal naming scheme. - * = it seems that a few drivers would also appreciate - * nybble swapping support... - * = every architecture could add their byteswap macro in asm/byteorder.h - * see how some architectures already do (i386, alpha, ppc, etc) - * = cpu_to_beXX and beXX_to_cpu might some day need to be well - * distinguished throughout the kernel. This is not the case currently, - * since little endian, big endian, and pdp endian machines needn't it. - * But this might be the case for, say, a port of Linux to 20/21 bit - * architectures (and F21 Linux addict around?). - */ - -/* - * The following macros are to be defined by : - * - * Conversion of long and short int between network and host format - * ntohl(__u32 x) - * ntohs(__u16 x) - * htonl(__u32 x) - * htons(__u16 x) - * It seems that some programs (which? where? or perhaps a standard? POSIX?) - * might like the above to be functions, not macros (why?). - * if that's true, then detect them, and take measures. - * Anyway, the measure is: define only ___ntohl as a macro instead, - * and in a separate file, have - * unsigned long inline ntohl(x){return ___ntohl(x);} - * - * The same for constant arguments - * __constant_ntohl(__u32 x) - * __constant_ntohs(__u16 x) - * __constant_htonl(__u32 x) - * __constant_htons(__u16 x) - * - * Conversion of XX-bit integers (16- 32- or 64-) - * between native CPU format and little/big endian format - * 64-bit stuff only defined for proper architectures - * cpu_to_[bl]eXX(__uXX x) - * [bl]eXX_to_cpu(__uXX x) - * - * The same, but takes a pointer to the value to convert - * cpu_to_[bl]eXXp(__uXX x) - * [bl]eXX_to_cpup(__uXX x) - * - * The same, but change in situ - * cpu_to_[bl]eXXs(__uXX x) - * [bl]eXX_to_cpus(__uXX x) - * - * See asm-foo/byteorder.h for examples of how to provide - * architecture-optimized versions - * - */ - - -/* - * inside the kernel, we can use nicknames; - * outside of it, we must avoid POSIX namespace pollution... - */ -#define cpu_to_le64 __cpu_to_le64 -#define le64_to_cpu __le64_to_cpu -#define cpu_to_le32 __cpu_to_le32 -#define le32_to_cpu __le32_to_cpu -#define cpu_to_le16 __cpu_to_le16 -#define le16_to_cpu __le16_to_cpu -#define cpu_to_be64 __cpu_to_be64 -#define be64_to_cpu __be64_to_cpu -#define cpu_to_be32 __cpu_to_be32 -#define be32_to_cpu __be32_to_cpu -#define cpu_to_be16 __cpu_to_be16 -#define be16_to_cpu __be16_to_cpu -#define cpu_to_le64p __cpu_to_le64p -#define le64_to_cpup __le64_to_cpup -#define cpu_to_le32p __cpu_to_le32p -#define le32_to_cpup __le32_to_cpup -#define cpu_to_le16p __cpu_to_le16p -#define le16_to_cpup __le16_to_cpup -#define cpu_to_be64p __cpu_to_be64p -#define be64_to_cpup __be64_to_cpup -#define cpu_to_be32p __cpu_to_be32p -#define be32_to_cpup __be32_to_cpup -#define cpu_to_be16p __cpu_to_be16p -#define be16_to_cpup __be16_to_cpup -#define cpu_to_le64s __cpu_to_le64s -#define le64_to_cpus __le64_to_cpus -#define cpu_to_le32s __cpu_to_le32s -#define le32_to_cpus __le32_to_cpus -#define cpu_to_le16s __cpu_to_le16s -#define le16_to_cpus __le16_to_cpus -#define cpu_to_be64s __cpu_to_be64s -#define be64_to_cpus __be64_to_cpus -#define cpu_to_be32s __cpu_to_be32s -#define be32_to_cpus __be32_to_cpus -#define cpu_to_be16s __cpu_to_be16s -#define be16_to_cpus __be16_to_cpus - - -/* - * Handle ntohl and suches. These have various compatibility - * issues - like we want to give the prototype even though we - * also have a macro for them in case some strange program - * wants to take the address of the thing or something.. - * - * Note that these used to return a "long" in libc5, even though - * long is often 64-bit these days.. Thus the casts. - * - * They have to be macros in order to do the constant folding - * correctly - if the argument passed into a inline function - * it is no longer constant according to gcc.. - */ - -#undef ntohl -#undef ntohs -#undef htonl -#undef htons - -/* - * Do the prototypes. Somebody might want to take the - * address or some such sick thing.. - */ -extern __u32 ntohl(__u32); -extern __u32 htonl(__u32); -extern unsigned short int ntohs(unsigned short int); -extern unsigned short int htons(unsigned short int); - -#endif /* _LINUX_BYTEORDER_GENERIC_H */ - diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c index cc893c0..cb9d4cf 100644 --- a/drivers/staging/rtl8712/hal_init.c +++ b/drivers/staging/rtl8712/hal_init.c @@ -36,7 +36,6 @@ #include "osdep_service.h" #include "drv_types.h" -#include "rtl871x_byteorder.h" #include "usb_osintf.h" #define FWBUFF_ALIGN_SZ 512 diff --git a/drivers/staging/rtl8712/little_endian.h b/drivers/staging/rtl8712/little_endian.h deleted file mode 100644 index cd57d6c..0000000 --- a/drivers/staging/rtl8712/little_endian.h +++ /dev/null @@ -1,94 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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, USA - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _LINUX_BYTEORDER_LITTLE_ENDIAN_H -#define _LINUX_BYTEORDER_LITTLE_ENDIAN_H - -#ifndef __LITTLE_ENDIAN -#define __LITTLE_ENDIAN 1234 -#endif -#ifndef __LITTLE_ENDIAN_BITFIELD -#define __LITTLE_ENDIAN_BITFIELD -#endif - -#include "swab.h" - -#define __constant_htonl(x) ___constant_swab32((x)) -#define __constant_ntohl(x) ___constant_swab32((x)) -#define __constant_htons(x) ___constant_swab16((x)) -#define __constant_ntohs(x) ___constant_swab16((x)) -#define __constant_cpu_to_le64(x) ((__u64)(x)) -#define __constant_le64_to_cpu(x) ((__u64)(x)) -#define __constant_cpu_to_le32(x) ((__u32)(x)) -#define __constant_le32_to_cpu(x) ((__u32)(x)) -#define __constant_cpu_to_le16(x) ((__u16)(x)) -#define __constant_le16_to_cpu(x) ((__u16)(x)) -#define __constant_cpu_to_be64(x) ___constant_swab64((x)) -#define __constant_be64_to_cpu(x) ___constant_swab64((x)) -#define __constant_cpu_to_be32(x) ___constant_swab32((x)) -#define __constant_be32_to_cpu(x) ___constant_swab32((x)) -#define __constant_cpu_to_be16(x) ___constant_swab16((x)) -#define __constant_be16_to_cpu(x) ___constant_swab16((x)) -#define __cpu_to_le64(x) ((__u64)(x)) -#define __le64_to_cpu(x) ((__u64)(x)) -#define __cpu_to_le32(x) ((__u32)(x)) -#define __le32_to_cpu(x) ((__u32)(x)) -#define __cpu_to_le16(x) ((__u16)(x)) -#define __le16_to_cpu(x) ((__u16)(x)) -#define __cpu_to_be64(x) __swab64((x)) -#define __be64_to_cpu(x) __swab64((x)) -#define __cpu_to_be32(x) __swab32((x)) -#define __be32_to_cpu(x) __swab32((x)) -#define __cpu_to_be16(x) __swab16((x)) -#define __be16_to_cpu(x) __swab16((x)) -#define __cpu_to_le64p(x) (*(__u64 *)(x)) -#define __le64_to_cpup(x) (*(__u64 *)(x)) -#define __cpu_to_le32p(x) (*(__u32 *)(x)) -#define __le32_to_cpup(x) (*(__u32 *)(x)) -#define __cpu_to_le16p(x) (*(__u16 *)(x)) -#define __le16_to_cpup(x) (*(__u16 *)(x)) -#define __cpu_to_be64p(x) __swab64p((x)) -#define __be64_to_cpup(x) __swab64p((x)) -#define __cpu_to_be32p(x) __swab32p((x)) -#define __be32_to_cpup(x) __swab32p((x)) -#define __cpu_to_be16p(x) __swab16p((x)) -#define __be16_to_cpup(x) __swab16p((x)) -#define __cpu_to_le64s(x) do {} while (0) -#define __le64_to_cpus(x) do {} while (0) -#define __cpu_to_le32s(x) do {} while (0) -#define __le32_to_cpus(x) do {} while (0) -#define __cpu_to_le16s(x) do {} while (0) -#define __le16_to_cpus(x) do {} while (0) -#define __cpu_to_be64s(x) __swab64s((x)) -#define __be64_to_cpus(x) __swab64s((x)) -#define __cpu_to_be32s(x) __swab32s((x)) -#define __be32_to_cpus(x) __swab32s((x)) -#define __cpu_to_be16s(x) __swab16s((x)) -#define __be16_to_cpus(x) __swab16s((x)) - -#include "generic.h" - -#endif /* _LINUX_BYTEORDER_LITTLE_ENDIAN_H */ - diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h index cabf774..f1ccc7e 100644 --- a/drivers/staging/rtl8712/osdep_service.h +++ b/drivers/staging/rtl8712/osdep_service.h @@ -106,8 +106,6 @@ static inline void _set_workitem(_workitem *pwork) schedule_work(pwork); } -#include "rtl871x_byteorder.h" - #ifndef BIT #define BIT(x) (1 << (x)) #endif diff --git a/drivers/staging/rtl8712/rtl8712_cmd.c b/drivers/staging/rtl8712/rtl8712_cmd.c index 6c4a94c..088647c 100644 --- a/drivers/staging/rtl8712/rtl8712_cmd.c +++ b/drivers/staging/rtl8712/rtl8712_cmd.c @@ -50,7 +50,6 @@ #include "drv_types.h" #include "recv_osdep.h" #include "mlme_osdep.h" -#include "rtl871x_byteorder.h" #include "rtl871x_ioctl_set.h" static void check_hw_pbc(struct _adapter *padapter) diff --git a/drivers/staging/rtl8712/rtl8712_xmit.c b/drivers/staging/rtl8712/rtl8712_xmit.c index 6933319..3d23514 100644 --- a/drivers/staging/rtl8712/rtl8712_xmit.c +++ b/drivers/staging/rtl8712/rtl8712_xmit.c @@ -30,7 +30,6 @@ #include "osdep_service.h" #include "drv_types.h" -#include "rtl871x_byteorder.h" #include "wifi.h" #include "osdep_intf.h" #include "usb_ops.h" diff --git a/drivers/staging/rtl8712/rtl871x_byteorder.h b/drivers/staging/rtl8712/rtl871x_byteorder.h deleted file mode 100644 index bd3703b..0000000 --- a/drivers/staging/rtl8712/rtl871x_byteorder.h +++ /dev/null @@ -1,32 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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, USA - * - * - ******************************************************************************/ -#ifndef _RTL871X_BYTEORDER_H_ -#define _RTL871X_BYTEORDER_H_ - -#if defined(__LITTLE_ENDIAN) -# include "little_endian.h" -#elif defined(__BIG_ENDIAN) -# include "big_endian.h" -#else -# error "Must be LITTLE/BIG Endian Host" -#endif - -#endif /* _RTL871X_BYTEORDER_H_ */ - diff --git a/drivers/staging/rtl8712/rtl871x_cmd.c b/drivers/staging/rtl8712/rtl871x_cmd.c index d77388b..659683e 100644 --- a/drivers/staging/rtl8712/rtl871x_cmd.c +++ b/drivers/staging/rtl8712/rtl871x_cmd.c @@ -50,7 +50,6 @@ #include "drv_types.h" #include "recv_osdep.h" #include "mlme_osdep.h" -#include "rtl871x_byteorder.h" /* Caller and the r8712_cmd_thread can protect cmd_q by spin_lock. diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c index 2ddb757..78f570b 100644 --- a/drivers/staging/rtl8712/rtl871x_xmit.c +++ b/drivers/staging/rtl8712/rtl871x_xmit.c @@ -30,7 +30,6 @@ #include "osdep_service.h" #include "drv_types.h" -#include "rtl871x_byteorder.h" #include "wifi.h" #include "osdep_intf.h" #include "usb_ops.h" diff --git a/drivers/staging/rtl8712/swab.h b/drivers/staging/rtl8712/swab.h deleted file mode 100644 index f127818..0000000 --- a/drivers/staging/rtl8712/swab.h +++ /dev/null @@ -1,131 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * 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, USA - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _LINUX_BYTEORDER_SWAB_H -#define _LINUX_BYTEORDER_SWAB_H - -#ifndef __u16 - #define __u16 unsigned short -#endif - -#ifndef __u32 - #define __u32 unsigned int -#endif - -#ifndef __u8 - #define __u8 unsigned char -#endif - -#ifndef __u64 - #define __u64 unsigned long long -#endif - - -static inline __u16 ___swab16(__u16 x) -{ - __u16 __x = x; - return (__u16)( - (((__u16)(__x) & (__u16)0x00ffU) << 8) | - (((__u16)(__x) & (__u16)0xff00U) >> 8)); - -} - -static inline __u32 ___swab32(__u32 x) -{ - __u32 __x = (x); - return (__u32)( - (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | - (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | - (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | - (((__u32)(__x) & (__u32)0xff000000UL) >> 24)); -} - -static inline __u64 ___swab64(__u64 x) -{ - __u64 __x = (x); - - return (__u64)( \ - (__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) | \ - (__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) | \ - (__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) | \ - (__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) << 8) | \ - (__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >> 8) | \ - (__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) | \ - (__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) | \ - (__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56)); -} - -#ifndef __arch__swab16 -static inline __u16 __arch__swab16(__u16 x) -{ - return ___swab16(x); -} - -#endif - -#ifndef __arch__swab32 -static inline __u32 __arch__swab32(__u32 x) -{ - __u32 __tmp = (x) ; - return ___swab32(__tmp); -} -#endif - -#ifndef __arch__swab64 - -static inline __u64 __arch__swab64(__u64 x) -{ - __u64 __tmp = (x) ; - return ___swab64(__tmp); -} - - -#endif - -#define __swab16(x) __fswab16(x) -#define __swab32(x) __fswab32(x) -#define __swab64(x) __fswab64(x) - -static inline const __u16 __fswab16(__u16 x) -{ - return __arch__swab16(x); -} -static inline const __u32 __fswab32(__u32 x) -{ - return __arch__swab32(x); -} - -#define swab16 __swab16 -#define swab32 __swab32 -#define swab64 __swab64 -#define swab16p __swab16p -#define swab32p __swab32p -#define swab64p __swab64p -#define swab16s __swab16s -#define swab32s __swab32s -#define swab64s __swab64s - -#endif /* _LINUX_BYTEORDER_SWAB_H */ - diff --git a/drivers/staging/rtl8712/usb_ops.c b/drivers/staging/rtl8712/usb_ops.c index 5a8b0eb..c03508d 100644 --- a/drivers/staging/rtl8712/usb_ops.c +++ b/drivers/staging/rtl8712/usb_ops.c @@ -33,7 +33,6 @@ #include "osdep_intf.h" #include "usb_ops.h" #include "recv_osdep.h" -#include "rtl871x_byteorder.h" static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr) { diff --git a/drivers/staging/rtl8712/wifi.h b/drivers/staging/rtl8712/wifi.h index 277398c..793443e 100644 --- a/drivers/staging/rtl8712/wifi.h +++ b/drivers/staging/rtl8712/wifi.h @@ -26,7 +26,6 @@ #ifndef _WIFI_H_ #define _WIFI_H_ -#include "rtl871x_byteorder.h" #include #ifdef BIT diff --git a/drivers/staging/rtl8712/xmit_linux.c b/drivers/staging/rtl8712/xmit_linux.c index c6943c5..65542cb 100644 --- a/drivers/staging/rtl8712/xmit_linux.c +++ b/drivers/staging/rtl8712/xmit_linux.c @@ -35,7 +35,6 @@ #include "osdep_service.h" #include "drv_types.h" -#include "rtl871x_byteorder.h" #include "wifi.h" #include "mlme_osdep.h" #include "xmit_osdep.h" -- cgit v0.10.2 From 10b241991fc10876b46ab7ca690f44281510d85b Mon Sep 17 00:00:00 2001 From: Tim Bird Date: Thu, 10 May 2012 15:11:36 -0700 Subject: staging: android: logger: Allocate logs dynamically at boot (v3) This changes the log initialization to be dynamic, but still at boot time. These changes are a predecessor to implementing runtime allocation and freeing of logs, to make the Android logger less hard-coded. Change from a fixed set of static log structures, to allocation at init time into a list. Return proper error numbers on log allocation failure. Cc: Brian Swetland Signed-off-by: Tim Bird Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c index ea69b6a..ed7e552 100644 --- a/drivers/staging/android/logger.c +++ b/drivers/staging/android/logger.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "logger.h" #include @@ -45,8 +46,12 @@ struct logger_log { size_t w_off; /* current write head offset */ size_t head; /* new readers start here */ size_t size; /* size of the log */ + struct list_head logs; /* list of log channels (myself)*/ }; +static LIST_HEAD(log_list); + + /* * struct logger_reader - a logging device open for reading * @@ -408,7 +413,15 @@ ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, return ret; } -static struct logger_log *get_log_from_minor(int); +static struct logger_log *get_log_from_minor(int minor) +{ + struct logger_log *log; + + list_for_each_entry(log, &log_list, logs) + if (log->misc.minor == minor) + return log; + return NULL; +} /* * logger_open - the log's open() file operation @@ -565,80 +578,84 @@ static const struct file_operations logger_fops = { }; /* - * Defines a log structure with name 'NAME' and a size of 'SIZE' bytes, which - * must be a power of two, greater than LOGGER_ENTRY_MAX_LEN, and less than - * LONG_MAX minus LOGGER_ENTRY_MAX_LEN. + * Log size must be a power of two, greater than LOGGER_ENTRY_MAX_LEN, + * and less than LONG_MAX minus LOGGER_ENTRY_MAX_LEN. */ -#define DEFINE_LOGGER_DEVICE(VAR, NAME, SIZE) \ -static unsigned char _buf_ ## VAR[SIZE]; \ -static struct logger_log VAR = { \ - .buffer = _buf_ ## VAR, \ - .misc = { \ - .minor = MISC_DYNAMIC_MINOR, \ - .name = NAME, \ - .fops = &logger_fops, \ - .parent = NULL, \ - }, \ - .wq = __WAIT_QUEUE_HEAD_INITIALIZER(VAR .wq), \ - .readers = LIST_HEAD_INIT(VAR .readers), \ - .mutex = __MUTEX_INITIALIZER(VAR .mutex), \ - .w_off = 0, \ - .head = 0, \ - .size = SIZE, \ -}; +static int __init create_log(char *log_name, int size) +{ + int ret = 0; + struct logger_log *log; + unsigned char *buffer; -DEFINE_LOGGER_DEVICE(log_main, LOGGER_LOG_MAIN, 256*1024) -DEFINE_LOGGER_DEVICE(log_events, LOGGER_LOG_EVENTS, 256*1024) -DEFINE_LOGGER_DEVICE(log_radio, LOGGER_LOG_RADIO, 256*1024) -DEFINE_LOGGER_DEVICE(log_system, LOGGER_LOG_SYSTEM, 256*1024) + buffer = vmalloc(size); + if (buffer == NULL) + return -ENOMEM; -static struct logger_log *get_log_from_minor(int minor) -{ - if (log_main.misc.minor == minor) - return &log_main; - if (log_events.misc.minor == minor) - return &log_events; - if (log_radio.misc.minor == minor) - return &log_radio; - if (log_system.misc.minor == minor) - return &log_system; - return NULL; -} + log = kzalloc(sizeof(struct logger_log), GFP_KERNEL); + if (log == NULL) { + ret = -ENOMEM; + goto out_free_buffer; + } + log->buffer = buffer; -static int __init init_log(struct logger_log *log) -{ - int ret; + log->misc.minor = MISC_DYNAMIC_MINOR; + log->misc.name = kstrdup(log_name, GFP_KERNEL); + if (log->misc.name == NULL) { + ret = -ENOMEM; + goto out_free_log; + } + + log->misc.fops = &logger_fops; + log->misc.parent = NULL; + init_waitqueue_head(&log->wq); + INIT_LIST_HEAD(&log->readers); + mutex_init(&log->mutex); + log->w_off = 0; + log->head = 0; + log->size = size; + + INIT_LIST_HEAD(&log->logs); + list_add_tail(&log->logs, &log_list); + + /* finally, initialize the misc device for this log */ ret = misc_register(&log->misc); if (unlikely(ret)) { printk(KERN_ERR "logger: failed to register misc " "device for log '%s'!\n", log->misc.name); - return ret; + goto out_free_log; } printk(KERN_INFO "logger: created %luK log '%s'\n", (unsigned long) log->size >> 10, log->misc.name); return 0; + +out_free_log: + kfree(log); + +out_free_buffer: + vfree(buffer); + return ret; } static int __init logger_init(void) { int ret; - ret = init_log(&log_main); + ret = create_log(LOGGER_LOG_MAIN, 256*1024); if (unlikely(ret)) goto out; - ret = init_log(&log_events); + ret = create_log(LOGGER_LOG_EVENTS, 256*1024); if (unlikely(ret)) goto out; - ret = init_log(&log_radio); + ret = create_log(LOGGER_LOG_RADIO, 256*1024); if (unlikely(ret)) goto out; - ret = init_log(&log_system); + ret = create_log(LOGGER_LOG_SYSTEM, 256*1024); if (unlikely(ret)) goto out; -- cgit v0.10.2 From e7f3eb0c912ca334fa67429a060389cbea6e815d Mon Sep 17 00:00:00 2001 From: Tim Bird Date: Thu, 10 May 2012 14:22:59 -0700 Subject: staging: android: logger: Fix some sparse and whitespace issues Fix a few sparse warnings, and improve whitespace. Cc: Brian Swetland Signed-off-by: Tim Bird Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c index ed7e552..b2e71c6 100644 --- a/drivers/staging/android/logger.c +++ b/drivers/staging/android/logger.c @@ -65,9 +65,9 @@ struct logger_reader { }; /* logger_offset - returns index 'n' into the log via (optimized) modulus */ -size_t logger_offset(struct logger_log *log, size_t n) +static size_t logger_offset(struct logger_log *log, size_t n) { - return n & (log->size-1); + return n & (log->size - 1); } @@ -353,7 +353,7 @@ static ssize_t do_write_log_from_user(struct logger_log *log, * writev(), and aio_write(). Writes are our fast path, and we try to optimize * them above all else. */ -ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, +static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t ppos) { struct logger_log *log = file_get_log(iocb->ki_filp); -- cgit v0.10.2 From 06f3d3bdee9bac871c556c34ea80303033c474b3 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 11 May 2012 17:17:06 -0700 Subject: persistent_ram: Remove prz->node The 'node' struct member is unused, so remove it. Signed-off-by: Anton Vorontsov Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/persistent_ram.c b/drivers/staging/android/persistent_ram.c index 8407112..12444fd 100644 --- a/drivers/staging/android/persistent_ram.c +++ b/drivers/staging/android/persistent_ram.c @@ -407,8 +407,6 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) goto err; } - INIT_LIST_HEAD(&prz->node); - ret = persistent_ram_buffer_init(dev_name(dev), prz); if (ret) { pr_err("persistent_ram: failed to initialize buffer\n"); diff --git a/drivers/staging/android/persistent_ram.h b/drivers/staging/android/persistent_ram.h index f41e208..5635355 100644 --- a/drivers/staging/android/persistent_ram.h +++ b/drivers/staging/android/persistent_ram.h @@ -38,7 +38,6 @@ struct persistent_ram { }; struct persistent_ram_zone { - struct list_head node; void *vaddr; struct persistent_ram_buffer *buffer; size_t buffer_size; -- cgit v0.10.2 From 484dd30e016eb425b0de871357fff2c9bb93be45 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 11 May 2012 17:17:17 -0700 Subject: persistent_ram: Fix buffer size clamping during writes This is a longstanding bug, almost unnoticeable when calling persistent_ram_write() for small buffers. But when called for large data buffers, the write routine behaves incorrectly, as the size may never update: instead of clamping the size to the maximum buffer size, buffer_size_add_clamp() returns an error (which is never checked by the write routine, btw). To fix this, we now use buffer_size_add() that actually clamps the size to the max value. Also remove buffer_size_add_clamp(), it is no longer needed. Signed-off-by: Anton Vorontsov Acked-by: Colin Cross Cc: stable Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/persistent_ram.c b/drivers/staging/android/persistent_ram.c index 12444fd..13a12bc 100644 --- a/drivers/staging/android/persistent_ram.c +++ b/drivers/staging/android/persistent_ram.c @@ -79,23 +79,6 @@ static inline void buffer_size_add(struct persistent_ram_zone *prz, size_t a) } while (atomic_cmpxchg(&prz->buffer->size, old, new) != old); } -/* increase the size counter, retuning an error if it hits the max size */ -static inline ssize_t buffer_size_add_clamp(struct persistent_ram_zone *prz, - size_t a) -{ - size_t old; - size_t new; - - do { - old = atomic_read(&prz->buffer->size); - new = old + a; - if (new > prz->buffer_size) - return -ENOMEM; - } while (atomic_cmpxchg(&prz->buffer->size, old, new) != old); - - return 0; -} - static void notrace persistent_ram_encode_rs8(struct persistent_ram_zone *prz, uint8_t *data, size_t len, uint8_t *ecc) { @@ -300,7 +283,7 @@ int notrace persistent_ram_write(struct persistent_ram_zone *prz, c = prz->buffer_size; } - buffer_size_add_clamp(prz, c); + buffer_size_add(prz, c); start = buffer_start_add(prz, c); -- cgit v0.10.2 From bb4206f2042d950a7af1560200af81aa59172a84 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 11 May 2012 17:17:25 -0700 Subject: staging: android: persistent_ram: Introduce persistent_ram_post_init() Factor post init logic out of __persistent_ram_init(), we'll need it for the new persistent_ram_new() routine. Signed-off-by: Anton Vorontsov Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/persistent_ram.c b/drivers/staging/android/persistent_ram.c index 13a12bc..ec23822 100644 --- a/drivers/staging/android/persistent_ram.c +++ b/drivers/staging/android/persistent_ram.c @@ -378,28 +378,15 @@ static int __init persistent_ram_buffer_init(const char *name, return -EINVAL; } -static __init -struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) +static int __init persistent_ram_post_init(struct persistent_ram_zone *prz, bool ecc) { - struct persistent_ram_zone *prz; - int ret = -ENOMEM; - - prz = kzalloc(sizeof(struct persistent_ram_zone), GFP_KERNEL); - if (!prz) { - pr_err("persistent_ram: failed to allocate persistent ram zone\n"); - goto err; - } - - ret = persistent_ram_buffer_init(dev_name(dev), prz); - if (ret) { - pr_err("persistent_ram: failed to initialize buffer\n"); - goto err; - } + int ret; prz->ecc = ecc; + ret = persistent_ram_init_ecc(prz, prz->buffer_size); if (ret) - goto err; + return ret; if (prz->buffer->sig == PERSISTENT_RAM_SIG) { if (buffer_size(prz) > prz->buffer_size || @@ -422,6 +409,29 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) atomic_set(&prz->buffer->start, 0); atomic_set(&prz->buffer->size, 0); + return 0; +} + +static __init +struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) +{ + struct persistent_ram_zone *prz; + int ret = -ENOMEM; + + prz = kzalloc(sizeof(struct persistent_ram_zone), GFP_KERNEL); + if (!prz) { + pr_err("persistent_ram: failed to allocate persistent ram zone\n"); + goto err; + } + + ret = persistent_ram_buffer_init(dev_name(dev), prz); + if (ret) { + pr_err("persistent_ram: failed to initialize buffer\n"); + goto err; + } + + persistent_ram_post_init(prz, ecc); + return prz; err: kfree(prz); -- cgit v0.10.2 From 8cf5aff89e5991aa4bec903b6dbab7d248047d98 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 11 May 2012 17:17:34 -0700 Subject: staging: android: persistent_ram: Introduce persistent_ram_new() The routine just creates a persistent ram zone at a specified address. For persistent_ram_init_ringbuffer() we'd need to add a 'struct persistent_ram' to the global list, and associate it with a device. We don't need all this complexity in pstore_ram, so we introduce the simple function. Signed-off-by: Anton Vorontsov Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/persistent_ram.c b/drivers/staging/android/persistent_ram.c index ec23822..c0c3d32 100644 --- a/drivers/staging/android/persistent_ram.c +++ b/drivers/staging/android/persistent_ram.c @@ -412,6 +412,32 @@ static int __init persistent_ram_post_init(struct persistent_ram_zone *prz, bool return 0; } +struct persistent_ram_zone * __init persistent_ram_new(phys_addr_t start, + size_t size, + bool ecc) +{ + struct persistent_ram_zone *prz; + int ret = -ENOMEM; + + prz = kzalloc(sizeof(struct persistent_ram_zone), GFP_KERNEL); + if (!prz) { + pr_err("persistent_ram: failed to allocate persistent ram zone\n"); + goto err; + } + + ret = persistent_ram_buffer_map(start, size, prz); + if (ret) + goto err; + + persistent_ram_post_init(prz, ecc); + persistent_ram_update_header_ecc(prz); + + return prz; +err: + kfree(prz); + return ERR_PTR(ret); +} + static __init struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) { diff --git a/drivers/staging/android/persistent_ram.h b/drivers/staging/android/persistent_ram.h index 5635355..8154d15 100644 --- a/drivers/staging/android/persistent_ram.h +++ b/drivers/staging/android/persistent_ram.h @@ -19,6 +19,7 @@ #include #include #include +#include struct persistent_ram_buffer; @@ -62,6 +63,9 @@ struct persistent_ram_zone { int persistent_ram_early_init(struct persistent_ram *ram); +struct persistent_ram_zone * __init persistent_ram_new(phys_addr_t start, + size_t size, + bool ecc); struct persistent_ram_zone *persistent_ram_init_ringbuffer(struct device *dev, bool ecc); -- cgit v0.10.2 From 2b1321e4714cc03d298e1b06c1457f8786c083ed Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 11 May 2012 17:17:43 -0700 Subject: staging: android: persistent_ram: Introduce persistent_ram_vmap() Factor out vmap logic out of persistent_ram_buffer_map(), this will make the code a bit more understandable when we'll add support for non-bootmem memory. Signed-off-by: Anton Vorontsov Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/persistent_ram.c b/drivers/staging/android/persistent_ram.c index c0c3d32..ab8bff1 100644 --- a/drivers/staging/android/persistent_ram.c +++ b/drivers/staging/android/persistent_ram.c @@ -318,14 +318,14 @@ void persistent_ram_free_old(struct persistent_ram_zone *prz) prz->old_log_size = 0; } -static int persistent_ram_buffer_map(phys_addr_t start, phys_addr_t size, - struct persistent_ram_zone *prz) +static void *persistent_ram_vmap(phys_addr_t start, size_t size) { struct page **pages; phys_addr_t page_start; unsigned int page_count; pgprot_t prot; unsigned int i; + void *vaddr; page_start = start - offset_in_page(start); page_count = DIV_ROUND_UP(size + offset_in_page(start), PAGE_SIZE); @@ -336,17 +336,26 @@ static int persistent_ram_buffer_map(phys_addr_t start, phys_addr_t size, if (!pages) { pr_err("%s: Failed to allocate array for %u pages\n", __func__, page_count); - return -ENOMEM; + return NULL; } for (i = 0; i < page_count; i++) { phys_addr_t addr = page_start + i * PAGE_SIZE; pages[i] = pfn_to_page(addr >> PAGE_SHIFT); } - prz->vaddr = vmap(pages, page_count, VM_MAP, prot); + vaddr = vmap(pages, page_count, VM_MAP, prot); kfree(pages); + + return vaddr; +} + +static int persistent_ram_buffer_map(phys_addr_t start, phys_addr_t size, + struct persistent_ram_zone *prz) +{ + prz->vaddr = persistent_ram_vmap(start, size); if (!prz->vaddr) { - pr_err("%s: Failed to map %u pages\n", __func__, page_count); + pr_err("%s: Failed to map 0x%llx pages at 0x%llx\n", __func__, + (unsigned long long)size, (unsigned long long)start); return -ENOMEM; } -- cgit v0.10.2 From 24c3d2f342edbc10fee9f8ab9e0a033393686543 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 11 May 2012 17:17:54 -0700 Subject: staging: android: persistent_ram: Make it possible to use memory outside of bootmem This includes devices' memory (e.g. framebuffers or memory mapped EEPROMs on a local bus), as well as the normal RAM that we don't use for the main memory. For the normal (but unused) ram we could use kmaps, but this assumes highmem support, so we don't bother and just use the memory via ioremap. As a side effect, the following hack is possible: when used together with pstore_ram (new ramoops) module, we can limit the normal RAM region with mem= and then point ramoops to use the rest of the memory, e.g. mem=128M ramoops.mem_address=0x8000000 Sure, we could just reserve the region with memblock_reserve() early in the arch/ code, and then register a pstore_ram platform device pointing to the reserved region. It's still a viable option if platform wants to do so. Also, we might want to use IO accessors in case of a real device, but for now we don't bother (the old ramoops wasn't using it either, so at least we don't make things worse). Signed-off-by: Anton Vorontsov Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/persistent_ram.c b/drivers/staging/android/persistent_ram.c index ab8bff1..c16d7c2 100644 --- a/drivers/staging/android/persistent_ram.c +++ b/drivers/staging/android/persistent_ram.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "persistent_ram.h" struct persistent_ram_buffer { @@ -349,10 +350,25 @@ static void *persistent_ram_vmap(phys_addr_t start, size_t size) return vaddr; } +static void *persistent_ram_iomap(phys_addr_t start, size_t size) +{ + if (!request_mem_region(start, size, "persistent_ram")) { + pr_err("request mem region (0x%llx@0x%llx) failed\n", + (unsigned long long)size, (unsigned long long)start); + return NULL; + } + + return ioremap(start, size); +} + static int persistent_ram_buffer_map(phys_addr_t start, phys_addr_t size, struct persistent_ram_zone *prz) { - prz->vaddr = persistent_ram_vmap(start, size); + if (pfn_valid(start >> PAGE_SHIFT)) + prz->vaddr = persistent_ram_vmap(start, size); + else + prz->vaddr = persistent_ram_iomap(start, size); + if (!prz->vaddr) { pr_err("%s: Failed to map 0x%llx pages at 0x%llx\n", __func__, (unsigned long long)size, (unsigned long long)start); -- cgit v0.10.2 From d3b487695120b5342067244253697eabb121436d Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 11 May 2012 17:18:05 -0700 Subject: staging: android: persistent_ram: Introduce persistent_ram_free() A corresponding function to persistent_ram_new(). Signed-off-by: Anton Vorontsov Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/android/persistent_ram.c b/drivers/staging/android/persistent_ram.c index c16d7c2..63481da 100644 --- a/drivers/staging/android/persistent_ram.c +++ b/drivers/staging/android/persistent_ram.c @@ -364,6 +364,9 @@ static void *persistent_ram_iomap(phys_addr_t start, size_t size) static int persistent_ram_buffer_map(phys_addr_t start, phys_addr_t size, struct persistent_ram_zone *prz) { + prz->paddr = start; + prz->size = size; + if (pfn_valid(start >> PAGE_SHIFT)) prz->vaddr = persistent_ram_vmap(start, size); else @@ -437,6 +440,18 @@ static int __init persistent_ram_post_init(struct persistent_ram_zone *prz, bool return 0; } +void persistent_ram_free(struct persistent_ram_zone *prz) +{ + if (pfn_valid(prz->paddr >> PAGE_SHIFT)) { + vunmap(prz->vaddr); + } else { + iounmap(prz->vaddr); + release_mem_region(prz->paddr, prz->size); + } + persistent_ram_free_old(prz); + kfree(prz); +} + struct persistent_ram_zone * __init persistent_ram_new(phys_addr_t start, size_t size, bool ecc) diff --git a/drivers/staging/android/persistent_ram.h b/drivers/staging/android/persistent_ram.h index 8154d15..d3b2b45 100644 --- a/drivers/staging/android/persistent_ram.h +++ b/drivers/staging/android/persistent_ram.h @@ -39,6 +39,8 @@ struct persistent_ram { }; struct persistent_ram_zone { + phys_addr_t paddr; + size_t size; void *vaddr; struct persistent_ram_buffer *buffer; size_t buffer_size; @@ -66,6 +68,7 @@ int persistent_ram_early_init(struct persistent_ram *ram); struct persistent_ram_zone * __init persistent_ram_new(phys_addr_t start, size_t size, bool ecc); +void persistent_ram_free(struct persistent_ram_zone *prz); struct persistent_ram_zone *persistent_ram_init_ringbuffer(struct device *dev, bool ecc); -- cgit v0.10.2 From fb60367d5dff0e2ee3032f7daf212e5ed9863552 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 10 May 2012 18:05:28 -0700 Subject: staging: comedi: register sysfs device attributes with driver core Currently the sysfs device attributes are created by the comedi core after each comedi device is created. This can lead to a race condition where userspace gets an add event before the files are created. Register the device attributes with the comedi class so that the driver core handles creating them and we avoid the race. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 44ca1fe..7677657 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -227,9 +227,6 @@ static ssize_t store_max_read_buffer_kb(struct device *dev, return count; } -static DEVICE_ATTR(max_read_buffer_kb, S_IRUGO | S_IWUSR, - show_max_read_buffer_kb, store_max_read_buffer_kb); - static ssize_t show_read_buffer_kb(struct device *dev, struct device_attribute *attr, char *buf) { @@ -287,9 +284,6 @@ static ssize_t store_read_buffer_kb(struct device *dev, return count; } -static DEVICE_ATTR(read_buffer_kb, S_IRUGO | S_IWUSR | S_IWGRP, - show_read_buffer_kb, store_read_buffer_kb); - static ssize_t show_max_write_buffer_kb(struct device *dev, struct device_attribute *attr, char *buf) @@ -344,9 +338,6 @@ static ssize_t store_max_write_buffer_kb(struct device *dev, return count; } -static DEVICE_ATTR(max_write_buffer_kb, S_IRUGO | S_IWUSR, - show_max_write_buffer_kb, store_max_write_buffer_kb); - static ssize_t show_write_buffer_kb(struct device *dev, struct device_attribute *attr, char *buf) { @@ -404,19 +395,16 @@ static ssize_t store_write_buffer_kb(struct device *dev, return count; } -static DEVICE_ATTR(write_buffer_kb, S_IRUGO | S_IWUSR | S_IWGRP, - show_write_buffer_kb, store_write_buffer_kb); - -static struct attribute *comedi_attrs[] = { - &dev_attr_max_read_buffer_kb.attr, - &dev_attr_read_buffer_kb.attr, - &dev_attr_max_write_buffer_kb.attr, - &dev_attr_write_buffer_kb.attr, - NULL -}; - -static const struct attribute_group comedi_sysfs_files = { - .attrs = comedi_attrs, +static struct device_attribute comedi_dev_attrs[] = { + __ATTR(max_read_buffer_kb, S_IRUGO | S_IWUSR, + show_max_read_buffer_kb, store_max_read_buffer_kb), + __ATTR(read_buffer_kb, S_IRUGO | S_IWUSR | S_IWGRP, + show_read_buffer_kb, store_read_buffer_kb), + __ATTR(max_write_buffer_kb, S_IRUGO | S_IWUSR, + show_max_write_buffer_kb, store_max_write_buffer_kb), + __ATTR(write_buffer_kb, S_IRUGO | S_IWUSR | S_IWGRP, + show_write_buffer_kb, store_write_buffer_kb), + __ATTR_NULL }; static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, @@ -2355,6 +2343,8 @@ static int __init comedi_init(void) return PTR_ERR(comedi_class); } + comedi_class->dev_attrs = comedi_dev_attrs; + /* XXX requires /proc interface */ comedi_proc_init(); @@ -2496,7 +2486,6 @@ int comedi_alloc_board_minor(struct device *hardware_device) struct comedi_device_file_info *info; struct device *csdev; unsigned i; - int retval; info = kzalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL); if (info == NULL) @@ -2532,14 +2521,6 @@ int comedi_alloc_board_minor(struct device *hardware_device) info->device->class_dev = csdev; dev_set_drvdata(csdev, info); - retval = sysfs_create_group(&csdev->kobj, &comedi_sysfs_files); - if (retval) { - printk(KERN_ERR - "comedi: failed to create sysfs attribute files\n"); - comedi_free_board_minor(i); - return retval; - } - return i; } @@ -2590,7 +2571,6 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_device_file_info *info; struct device *csdev; unsigned i; - int retval; info = kmalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL); if (info == NULL) @@ -2621,14 +2601,6 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev, s->class_dev = csdev; dev_set_drvdata(csdev, info); - retval = sysfs_create_group(&csdev->kobj, &comedi_sysfs_files); - if (retval) { - printk(KERN_ERR - "comedi: failed to create sysfs attribute files\n"); - comedi_free_subdevice_minor(s); - return retval; - } - return i; } -- cgit v0.10.2 From c15974ef1f2d858795f7f63280fb53bcab6064f9 Mon Sep 17 00:00:00 2001 From: Johannes Thumshirn Date: Thu, 10 May 2012 19:12:02 +0200 Subject: staging: line6/config.h: Remove CHECKPOINT macro Kill unused debugging macro CHECKPOINT Signed-off-by: Johannes Thumshirn Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/line6/config.h b/drivers/staging/line6/config.h index f8a5149..2493491 100644 --- a/drivers/staging/line6/config.h +++ b/drivers/staging/line6/config.h @@ -34,11 +34,6 @@ #define CREATE_RAW_FILE 0 #if DO_DEBUG_MESSAGES -#define CHECKPOINT printk(KERN_INFO "line6usb: %s (%s:%d)\n", \ - __func__, __FILE__, __LINE__) -#endif - -#if DO_DEBUG_MESSAGES #define DEBUG_MESSAGES(x) (x) #else #define DEBUG_MESSAGES(x) -- cgit v0.10.2 From 49b81a3c7415d9b02169f37b8559d468fd17686a Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Thu, 10 May 2012 12:06:21 -0700 Subject: ramster: switch over to zsmalloc and crypto interface RAMster does many zcache-like things. In order to avoid major merge conflicts at 3.4, ramster used lzo1x directly for compression and retained a local copy of xvmalloc, while zcache moved to the new zsmalloc allocator and the crypto API. This patch moves ramster forward to use zsmalloc and crypto. Signed-off-by: Dan Magenheimer Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ramster/Kconfig b/drivers/staging/ramster/Kconfig index 8349887..98df39c 100644 --- a/drivers/staging/ramster/Kconfig +++ b/drivers/staging/ramster/Kconfig @@ -1,8 +1,8 @@ config RAMSTER bool "Cross-machine RAM capacity sharing, aka peer-to-peer tmem" - depends on (CLEANCACHE || FRONTSWAP) && CONFIGFS_FS=y && !ZCACHE && !XVMALLOC && !HIGHMEM && NET - select LZO_COMPRESS - select LZO_DECOMPRESS + depends on (CLEANCACHE || FRONTSWAP) && CONFIGFS_FS=y && !ZCACHE && CRYPTO=y && !HIGHMEM && NET + select ZSMALLOC + select CRYPTO_LZO default n help RAMster allows RAM on other machines in a cluster to be utilized diff --git a/drivers/staging/ramster/Makefile b/drivers/staging/ramster/Makefile index bcc13c8..07ffd75 100644 --- a/drivers/staging/ramster/Makefile +++ b/drivers/staging/ramster/Makefile @@ -1 +1 @@ -obj-$(CONFIG_RAMSTER) += zcache-main.o tmem.o r2net.o xvmalloc.o cluster/ +obj-$(CONFIG_RAMSTER) += zcache-main.o tmem.o r2net.o cluster/ diff --git a/drivers/staging/ramster/TODO b/drivers/staging/ramster/TODO index 46fcf0c..4688233 100644 --- a/drivers/staging/ramster/TODO +++ b/drivers/staging/ramster/TODO @@ -1,7 +1,5 @@ For this staging driver, RAMster duplicates code from drivers/staging/zcache -then incorporates changes to the local copy of the code. For V5, it also -directly incorporates the soon-to-be-removed drivers/staging/zram/xvmalloc.[ch] -as all testing has been done with xvmalloc rather than the new zsmalloc. +then incorporates changes to the local copy of the code. Before RAMster can be promoted from staging, the zcache and RAMster drivers should be either merged or reorganized to separate out common code. diff --git a/drivers/staging/ramster/xvmalloc.c b/drivers/staging/ramster/xvmalloc.c deleted file mode 100644 index 44ceb0b..0000000 --- a/drivers/staging/ramster/xvmalloc.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - * xvmalloc memory allocator - * - * Copyright (C) 2008, 2009, 2010 Nitin Gupta - * - * This code is released using a dual license strategy: BSD/GPL - * You can choose the licence that better fits your requirements. - * - * Released under the terms of 3-clause BSD License - * Released under the terms of GNU General Public License Version 2.0 - */ - -#ifdef CONFIG_ZRAM_DEBUG -#define DEBUG -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "xvmalloc.h" -#include "xvmalloc_int.h" - -static void stat_inc(u64 *value) -{ - *value = *value + 1; -} - -static void stat_dec(u64 *value) -{ - *value = *value - 1; -} - -static int test_flag(struct block_header *block, enum blockflags flag) -{ - return block->prev & BIT(flag); -} - -static void set_flag(struct block_header *block, enum blockflags flag) -{ - block->prev |= BIT(flag); -} - -static void clear_flag(struct block_header *block, enum blockflags flag) -{ - block->prev &= ~BIT(flag); -} - -/* - * Given pair, provide a dereferencable pointer. - * This is called from xv_malloc/xv_free path, so it - * needs to be fast. - */ -static void *get_ptr_atomic(struct page *page, u16 offset) -{ - unsigned char *base; - - base = kmap_atomic(page); - return base + offset; -} - -static void put_ptr_atomic(void *ptr) -{ - kunmap_atomic(ptr); -} - -static u32 get_blockprev(struct block_header *block) -{ - return block->prev & PREV_MASK; -} - -static void set_blockprev(struct block_header *block, u16 new_offset) -{ - block->prev = new_offset | (block->prev & FLAGS_MASK); -} - -static struct block_header *BLOCK_NEXT(struct block_header *block) -{ - return (struct block_header *) - ((char *)block + block->size + XV_ALIGN); -} - -/* - * Get index of free list containing blocks of maximum size - * which is less than or equal to given size. - */ -static u32 get_index_for_insert(u32 size) -{ - if (unlikely(size > XV_MAX_ALLOC_SIZE)) - size = XV_MAX_ALLOC_SIZE; - size &= ~FL_DELTA_MASK; - return (size - XV_MIN_ALLOC_SIZE) >> FL_DELTA_SHIFT; -} - -/* - * Get index of free list having blocks of size greater than - * or equal to requested size. - */ -static u32 get_index(u32 size) -{ - if (unlikely(size < XV_MIN_ALLOC_SIZE)) - size = XV_MIN_ALLOC_SIZE; - size = ALIGN(size, FL_DELTA); - return (size - XV_MIN_ALLOC_SIZE) >> FL_DELTA_SHIFT; -} - -/** - * find_block - find block of at least given size - * @pool: memory pool to search from - * @size: size of block required - * @page: page containing required block - * @offset: offset within the page where block is located. - * - * Searches two level bitmap to locate block of at least - * the given size. If such a block is found, it provides - * to identify this block and returns index - * in freelist where we found this block. - * Otherwise, returns 0 and params are not touched. - */ -static u32 find_block(struct xv_pool *pool, u32 size, - struct page **page, u32 *offset) -{ - ulong flbitmap, slbitmap; - u32 flindex, slindex, slbitstart; - - /* There are no free blocks in this pool */ - if (!pool->flbitmap) - return 0; - - /* Get freelist index corresponding to this size */ - slindex = get_index(size); - slbitmap = pool->slbitmap[slindex / BITS_PER_LONG]; - slbitstart = slindex % BITS_PER_LONG; - - /* - * If freelist is not empty at this index, we found the - * block - head of this list. This is approximate best-fit match. - */ - if (test_bit(slbitstart, &slbitmap)) { - *page = pool->freelist[slindex].page; - *offset = pool->freelist[slindex].offset; - return slindex; - } - - /* - * No best-fit found. Search a bit further in bitmap for a free block. - * Second level bitmap consists of series of 32-bit chunks. Search - * further in the chunk where we expected a best-fit, starting from - * index location found above. - */ - slbitstart++; - slbitmap >>= slbitstart; - - /* Skip this search if we were already at end of this bitmap chunk */ - if ((slbitstart != BITS_PER_LONG) && slbitmap) { - slindex += __ffs(slbitmap) + 1; - *page = pool->freelist[slindex].page; - *offset = pool->freelist[slindex].offset; - return slindex; - } - - /* Now do a full two-level bitmap search to find next nearest fit */ - flindex = slindex / BITS_PER_LONG; - - flbitmap = (pool->flbitmap) >> (flindex + 1); - if (!flbitmap) - return 0; - - flindex += __ffs(flbitmap) + 1; - slbitmap = pool->slbitmap[flindex]; - slindex = (flindex * BITS_PER_LONG) + __ffs(slbitmap); - *page = pool->freelist[slindex].page; - *offset = pool->freelist[slindex].offset; - - return slindex; -} - -/* - * Insert block at in freelist of given pool. - * freelist used depends on block size. - */ -static void insert_block(struct xv_pool *pool, struct page *page, u32 offset, - struct block_header *block) -{ - u32 flindex, slindex; - struct block_header *nextblock; - - slindex = get_index_for_insert(block->size); - flindex = slindex / BITS_PER_LONG; - - block->link.prev_page = NULL; - block->link.prev_offset = 0; - block->link.next_page = pool->freelist[slindex].page; - block->link.next_offset = pool->freelist[slindex].offset; - pool->freelist[slindex].page = page; - pool->freelist[slindex].offset = offset; - - if (block->link.next_page) { - nextblock = get_ptr_atomic(block->link.next_page, - block->link.next_offset); - nextblock->link.prev_page = page; - nextblock->link.prev_offset = offset; - put_ptr_atomic(nextblock); - /* If there was a next page then the free bits are set. */ - return; - } - - __set_bit(slindex % BITS_PER_LONG, &pool->slbitmap[flindex]); - __set_bit(flindex, &pool->flbitmap); -} - -/* - * Remove block from freelist. Index 'slindex' identifies the freelist. - */ -static void remove_block(struct xv_pool *pool, struct page *page, u32 offset, - struct block_header *block, u32 slindex) -{ - u32 flindex = slindex / BITS_PER_LONG; - struct block_header *tmpblock; - - if (block->link.prev_page) { - tmpblock = get_ptr_atomic(block->link.prev_page, - block->link.prev_offset); - tmpblock->link.next_page = block->link.next_page; - tmpblock->link.next_offset = block->link.next_offset; - put_ptr_atomic(tmpblock); - } - - if (block->link.next_page) { - tmpblock = get_ptr_atomic(block->link.next_page, - block->link.next_offset); - tmpblock->link.prev_page = block->link.prev_page; - tmpblock->link.prev_offset = block->link.prev_offset; - put_ptr_atomic(tmpblock); - } - - /* Is this block is at the head of the freelist? */ - if (pool->freelist[slindex].page == page - && pool->freelist[slindex].offset == offset) { - - pool->freelist[slindex].page = block->link.next_page; - pool->freelist[slindex].offset = block->link.next_offset; - - if (pool->freelist[slindex].page) { - struct block_header *tmpblock; - tmpblock = get_ptr_atomic(pool->freelist[slindex].page, - pool->freelist[slindex].offset); - tmpblock->link.prev_page = NULL; - tmpblock->link.prev_offset = 0; - put_ptr_atomic(tmpblock); - } else { - /* This freelist bucket is empty */ - __clear_bit(slindex % BITS_PER_LONG, - &pool->slbitmap[flindex]); - if (!pool->slbitmap[flindex]) - __clear_bit(flindex, &pool->flbitmap); - } - } - - block->link.prev_page = NULL; - block->link.prev_offset = 0; - block->link.next_page = NULL; - block->link.next_offset = 0; -} - -/* - * Allocate a page and add it to freelist of given pool. - */ -static int grow_pool(struct xv_pool *pool, gfp_t flags) -{ - struct page *page; - struct block_header *block; - - page = alloc_page(flags); - if (unlikely(!page)) - return -ENOMEM; - - stat_inc(&pool->total_pages); - - spin_lock(&pool->lock); - block = get_ptr_atomic(page, 0); - - block->size = PAGE_SIZE - XV_ALIGN; - set_flag(block, BLOCK_FREE); - clear_flag(block, PREV_FREE); - set_blockprev(block, 0); - - insert_block(pool, page, 0, block); - - put_ptr_atomic(block); - spin_unlock(&pool->lock); - - return 0; -} - -/* - * Create a memory pool. Allocates freelist, bitmaps and other - * per-pool metadata. - */ -struct xv_pool *xv_create_pool(void) -{ - u32 ovhd_size; - struct xv_pool *pool; - - ovhd_size = roundup(sizeof(*pool), PAGE_SIZE); - pool = kzalloc(ovhd_size, GFP_KERNEL); - if (!pool) - return NULL; - - spin_lock_init(&pool->lock); - - return pool; -} -EXPORT_SYMBOL_GPL(xv_create_pool); - -void xv_destroy_pool(struct xv_pool *pool) -{ - kfree(pool); -} -EXPORT_SYMBOL_GPL(xv_destroy_pool); - -/** - * xv_malloc - Allocate block of given size from pool. - * @pool: pool to allocate from - * @size: size of block to allocate - * @page: page no. that holds the object - * @offset: location of object within page - * - * On success, identifies block allocated - * and 0 is returned. On failure, is set to - * 0 and -ENOMEM is returned. - * - * Allocation requests with size > XV_MAX_ALLOC_SIZE will fail. - */ -int xv_malloc(struct xv_pool *pool, u32 size, struct page **page, - u32 *offset, gfp_t flags) -{ - int error; - u32 index, tmpsize, origsize, tmpoffset; - struct block_header *block, *tmpblock; - - *page = NULL; - *offset = 0; - origsize = size; - - if (unlikely(!size || size > XV_MAX_ALLOC_SIZE)) - return -ENOMEM; - - size = ALIGN(size, XV_ALIGN); - - spin_lock(&pool->lock); - - index = find_block(pool, size, page, offset); - - if (!*page) { - spin_unlock(&pool->lock); - if (flags & GFP_NOWAIT) - return -ENOMEM; - error = grow_pool(pool, flags); - if (unlikely(error)) - return error; - - spin_lock(&pool->lock); - index = find_block(pool, size, page, offset); - } - - if (!*page) { - spin_unlock(&pool->lock); - return -ENOMEM; - } - - block = get_ptr_atomic(*page, *offset); - - remove_block(pool, *page, *offset, block, index); - - /* Split the block if required */ - tmpoffset = *offset + size + XV_ALIGN; - tmpsize = block->size - size; - tmpblock = (struct block_header *)((char *)block + size + XV_ALIGN); - if (tmpsize) { - tmpblock->size = tmpsize - XV_ALIGN; - set_flag(tmpblock, BLOCK_FREE); - clear_flag(tmpblock, PREV_FREE); - - set_blockprev(tmpblock, *offset); - if (tmpblock->size >= XV_MIN_ALLOC_SIZE) - insert_block(pool, *page, tmpoffset, tmpblock); - - if (tmpoffset + XV_ALIGN + tmpblock->size != PAGE_SIZE) { - tmpblock = BLOCK_NEXT(tmpblock); - set_blockprev(tmpblock, tmpoffset); - } - } else { - /* This block is exact fit */ - if (tmpoffset != PAGE_SIZE) - clear_flag(tmpblock, PREV_FREE); - } - - block->size = origsize; - clear_flag(block, BLOCK_FREE); - - put_ptr_atomic(block); - spin_unlock(&pool->lock); - - *offset += XV_ALIGN; - - return 0; -} -EXPORT_SYMBOL_GPL(xv_malloc); - -/* - * Free block identified with - */ -void xv_free(struct xv_pool *pool, struct page *page, u32 offset) -{ - void *page_start; - struct block_header *block, *tmpblock; - - offset -= XV_ALIGN; - - spin_lock(&pool->lock); - - page_start = get_ptr_atomic(page, 0); - block = (struct block_header *)((char *)page_start + offset); - - /* Catch double free bugs */ - BUG_ON(test_flag(block, BLOCK_FREE)); - - block->size = ALIGN(block->size, XV_ALIGN); - - tmpblock = BLOCK_NEXT(block); - if (offset + block->size + XV_ALIGN == PAGE_SIZE) - tmpblock = NULL; - - /* Merge next block if its free */ - if (tmpblock && test_flag(tmpblock, BLOCK_FREE)) { - /* - * Blocks smaller than XV_MIN_ALLOC_SIZE - * are not inserted in any free list. - */ - if (tmpblock->size >= XV_MIN_ALLOC_SIZE) { - remove_block(pool, page, - offset + block->size + XV_ALIGN, tmpblock, - get_index_for_insert(tmpblock->size)); - } - block->size += tmpblock->size + XV_ALIGN; - } - - /* Merge previous block if its free */ - if (test_flag(block, PREV_FREE)) { - tmpblock = (struct block_header *)((char *)(page_start) + - get_blockprev(block)); - offset = offset - tmpblock->size - XV_ALIGN; - - if (tmpblock->size >= XV_MIN_ALLOC_SIZE) - remove_block(pool, page, offset, tmpblock, - get_index_for_insert(tmpblock->size)); - - tmpblock->size += block->size + XV_ALIGN; - block = tmpblock; - } - - /* No used objects in this page. Free it. */ - if (block->size == PAGE_SIZE - XV_ALIGN) { - put_ptr_atomic(page_start); - spin_unlock(&pool->lock); - - __free_page(page); - stat_dec(&pool->total_pages); - return; - } - - set_flag(block, BLOCK_FREE); - if (block->size >= XV_MIN_ALLOC_SIZE) - insert_block(pool, page, offset, block); - - if (offset + block->size + XV_ALIGN != PAGE_SIZE) { - tmpblock = BLOCK_NEXT(block); - set_flag(tmpblock, PREV_FREE); - set_blockprev(tmpblock, offset); - } - - put_ptr_atomic(page_start); - spin_unlock(&pool->lock); -} -EXPORT_SYMBOL_GPL(xv_free); - -u32 xv_get_object_size(void *obj) -{ - struct block_header *blk; - - blk = (struct block_header *)((char *)(obj) - XV_ALIGN); - return blk->size; -} -EXPORT_SYMBOL_GPL(xv_get_object_size); - -/* - * Returns total memory used by allocator (userdata + metadata) - */ -u64 xv_get_total_size_bytes(struct xv_pool *pool) -{ - return pool->total_pages << PAGE_SHIFT; -} -EXPORT_SYMBOL_GPL(xv_get_total_size_bytes); diff --git a/drivers/staging/ramster/xvmalloc.h b/drivers/staging/ramster/xvmalloc.h deleted file mode 100644 index 5b1a81a..0000000 --- a/drivers/staging/ramster/xvmalloc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * xvmalloc memory allocator - * - * Copyright (C) 2008, 2009, 2010 Nitin Gupta - * - * This code is released using a dual license strategy: BSD/GPL - * You can choose the licence that better fits your requirements. - * - * Released under the terms of 3-clause BSD License - * Released under the terms of GNU General Public License Version 2.0 - */ - -#ifndef _XV_MALLOC_H_ -#define _XV_MALLOC_H_ - -#include - -struct xv_pool; - -struct xv_pool *xv_create_pool(void); -void xv_destroy_pool(struct xv_pool *pool); - -int xv_malloc(struct xv_pool *pool, u32 size, struct page **page, - u32 *offset, gfp_t flags); -void xv_free(struct xv_pool *pool, struct page *page, u32 offset); - -u32 xv_get_object_size(void *obj); -u64 xv_get_total_size_bytes(struct xv_pool *pool); - -#endif diff --git a/drivers/staging/ramster/xvmalloc_int.h b/drivers/staging/ramster/xvmalloc_int.h deleted file mode 100644 index b5f1f7f..0000000 --- a/drivers/staging/ramster/xvmalloc_int.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * xvmalloc memory allocator - * - * Copyright (C) 2008, 2009, 2010 Nitin Gupta - * - * This code is released using a dual license strategy: BSD/GPL - * You can choose the licence that better fits your requirements. - * - * Released under the terms of 3-clause BSD License - * Released under the terms of GNU General Public License Version 2.0 - */ - -#ifndef _XV_MALLOC_INT_H_ -#define _XV_MALLOC_INT_H_ - -#include -#include - -/* User configurable params */ - -/* Must be power of two */ -#ifdef CONFIG_64BIT -#define XV_ALIGN_SHIFT 3 -#else -#define XV_ALIGN_SHIFT 2 -#endif -#define XV_ALIGN (1 << XV_ALIGN_SHIFT) -#define XV_ALIGN_MASK (XV_ALIGN - 1) - -/* This must be greater than sizeof(link_free) */ -#define XV_MIN_ALLOC_SIZE 32 -#define XV_MAX_ALLOC_SIZE (PAGE_SIZE - XV_ALIGN) - -/* - * Free lists are separated by FL_DELTA bytes - * This value is 3 for 4k pages and 4 for 64k pages, for any - * other page size, a conservative (PAGE_SHIFT - 9) is used. - */ -#if PAGE_SHIFT == 16 -#define FL_DELTA_SHIFT 4 -#else -#define FL_DELTA_SHIFT (PAGE_SHIFT - 9) -#endif -#define FL_DELTA (1 << FL_DELTA_SHIFT) -#define FL_DELTA_MASK (FL_DELTA - 1) -#define NUM_FREE_LISTS ((XV_MAX_ALLOC_SIZE - XV_MIN_ALLOC_SIZE) \ - / FL_DELTA + 1) - -#define MAX_FLI DIV_ROUND_UP(NUM_FREE_LISTS, BITS_PER_LONG) - -/* End of user params */ - -enum blockflags { - BLOCK_FREE, - PREV_FREE, - __NR_BLOCKFLAGS, -}; - -#define FLAGS_MASK XV_ALIGN_MASK -#define PREV_MASK (~FLAGS_MASK) - -struct freelist_entry { - struct page *page; - u16 offset; - u16 pad; -}; - -struct link_free { - struct page *prev_page; - struct page *next_page; - u16 prev_offset; - u16 next_offset; -}; - -struct block_header { - union { - /* This common header must be XV_ALIGN bytes */ - u8 common[XV_ALIGN]; - struct { - u16 size; - u16 prev; - }; - }; - struct link_free link; -}; - -struct xv_pool { - ulong flbitmap; - ulong slbitmap[MAX_FLI]; - u64 total_pages; /* stats */ - struct freelist_entry freelist[NUM_FREE_LISTS]; - spinlock_t lock; -}; - -#endif diff --git a/drivers/staging/ramster/zcache-main.c b/drivers/staging/ramster/zcache-main.c index 4e7ef0e..225e3b3 100644 --- a/drivers/staging/ramster/zcache-main.c +++ b/drivers/staging/ramster/zcache-main.c @@ -6,9 +6,10 @@ * * Zcache provides an in-kernel "host implementation" for transcendent memory * and, thus indirectly, for cleancache and frontswap. Zcache includes two - * page-accessible memory [1] interfaces, both utilizing lzo1x compression: + * page-accessible memory [1] interfaces, both utilizing the crypto compression + * API: * 1) "compression buddies" ("zbud") is used for ephemeral pages - * 2) xvmalloc is used for persistent pages. + * 2) zsmalloc is used for persistent pages. * Xvmalloc (based on the TLSF allocator) has very low fragmentation * so maximizes space efficiency, while zbud allows pairs (and potentially, * in the future, more than a pair of) compressed pages to be closely linked @@ -26,18 +27,19 @@ #include #include #include -#include #include #include #include #include #include +#include +#include #include "tmem.h" #include "zcache.h" #include "ramster.h" #include "cluster/tcp.h" -#include "xvmalloc.h" /* temporary until change to zsmalloc */ +#include "../zsmalloc/zsmalloc.h" #define RAMSTER_TESTING @@ -88,6 +90,7 @@ struct zv_hdr { uint16_t pool_id; struct tmem_oid oid; uint32_t index; + size_t size; DECL_SENTINEL }; @@ -123,7 +126,7 @@ MODULE_LICENSE("GPL"); struct zcache_client { struct tmem_pool *tmem_pools[MAX_POOLS_PER_CLIENT]; - struct xv_pool *xvpool; + struct zs_pool *zspool; bool allocated; atomic_t refcount; }; @@ -144,6 +147,38 @@ static inline bool is_local_client(struct zcache_client *cli) return cli == &zcache_host; } +/* crypto API for zcache */ +#define ZCACHE_COMP_NAME_SZ CRYPTO_MAX_ALG_NAME +static char zcache_comp_name[ZCACHE_COMP_NAME_SZ]; +static struct crypto_comp * __percpu *zcache_comp_pcpu_tfms; + +enum comp_op { + ZCACHE_COMPOP_COMPRESS, + ZCACHE_COMPOP_DECOMPRESS +}; + +static inline int zcache_comp_op(enum comp_op op, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) +{ + struct crypto_comp *tfm; + int ret; + + BUG_ON(!zcache_comp_pcpu_tfms); + tfm = *per_cpu_ptr(zcache_comp_pcpu_tfms, get_cpu()); + BUG_ON(!tfm); + switch (op) { + case ZCACHE_COMPOP_COMPRESS: + ret = crypto_comp_compress(tfm, src, slen, dst, dlen); + break; + case ZCACHE_COMPOP_DECOMPRESS: + ret = crypto_comp_decompress(tfm, src, slen, dst, dlen); + break; + } + put_cpu(); + return ret; +} + /********** * Compression buddies ("zbud") provides for packing two (or, possibly * in the future, more) compressed ephemeral pages into a single "raw" @@ -374,11 +409,13 @@ static void zbud_free_and_delist(struct zbud_hdr *zh) /* FIXME, should be BUG_ON, pool destruction path doesn't disable * interrupts tmem_destroy_pool()->tmem_pampd_destroy_all_in_obj()-> * tmem_objnode_node_destroy()-> zcache_pampd_free() */ - WARN_ON(!irqs_disabled()); + /* WARN_ON(!irqs_disabled()); FIXME for now, just avoid spew */ + spin_lock(&zbud_budlists_spinlock); spin_lock(&zbpg->lock); if (list_empty(&zbpg->bud_list)) { /* ignore zombie page... see zbud_evict_pages() */ spin_unlock(&zbpg->lock); + spin_unlock(&zbud_budlists_spinlock); return; } size = zbud_free(zh); @@ -386,7 +423,6 @@ static void zbud_free_and_delist(struct zbud_hdr *zh) zh_other = &zbpg->buddy[(budnum == 0) ? 1 : 0]; if (zh_other->size == 0) { /* was unbuddied: unlist and free */ chunks = zbud_size_to_chunks(size) ; - spin_lock(&zbud_budlists_spinlock); BUG_ON(list_empty(&zbud_unbuddied[chunks].list)); list_del_init(&zbpg->bud_list); zbud_unbuddied[chunks].count--; @@ -394,13 +430,12 @@ static void zbud_free_and_delist(struct zbud_hdr *zh) zbud_free_raw_page(zbpg); } else { /* was buddied: move remaining buddy to unbuddied list */ chunks = zbud_size_to_chunks(zh_other->size) ; - spin_lock(&zbud_budlists_spinlock); list_del_init(&zbpg->bud_list); zcache_zbud_buddied_count--; list_add_tail(&zbpg->bud_list, &zbud_unbuddied[chunks].list); zbud_unbuddied[chunks].count++; - spin_unlock(&zbud_budlists_spinlock); spin_unlock(&zbpg->lock); + spin_unlock(&zbud_budlists_spinlock); } } @@ -469,6 +504,7 @@ init_zh: memcpy(to, cdata, size); spin_unlock(&zbpg->lock); spin_unlock(&zbud_budlists_spinlock); + zbud_cumul_chunk_counts[nchunks]++; atomic_inc(&zcache_zbud_curr_zpages); zcache_zbud_cumul_zpages++; @@ -482,7 +518,7 @@ static int zbud_decompress(struct page *page, struct zbud_hdr *zh) { struct zbud_page *zbpg; unsigned budnum = zbud_budnum(zh); - size_t out_len = PAGE_SIZE; + unsigned int out_len = PAGE_SIZE; char *to_va, *from_va; unsigned size; int ret = 0; @@ -499,8 +535,9 @@ static int zbud_decompress(struct page *page, struct zbud_hdr *zh) to_va = kmap_atomic(page); size = zh->size; from_va = zbud_data(zh, size); - ret = lzo1x_decompress_safe(from_va, size, to_va, &out_len); - BUG_ON(ret != LZO_E_OK); + ret = zcache_comp_op(ZCACHE_COMPOP_DECOMPRESS, from_va, size, + to_va, &out_len); + BUG_ON(ret); BUG_ON(out_len != PAGE_SIZE); kunmap_atomic(to_va); out: @@ -861,7 +898,7 @@ static void zcache_remote_pers_put(struct zv_hdr *zv) xh.pool_id = zv->pool_id; xh.oid = zv->oid; xh.index = zv->index; - size = xv_get_object_size(zv) - sizeof(*zv); + size = zv->size; BUG_ON(size == 0 || size > zv_max_page_size); data = (char *)zv + sizeof(*zv); for (p = data, cksum = 0, i = 0; i < size; i++) @@ -1063,8 +1100,8 @@ static int zbud_show_cumul_chunk_counts(char *buf) #endif /********** - * This "zv" PAM implementation combines the TLSF-based xvMalloc - * with lzo1x compression to maximize the amount of data that can + * This "zv" PAM implementation combines the slab-based zsmalloc + * with the crypto compression API to maximize the amount of data that can * be packed into a physical page. * * Zv represents a PAM page with the index and object (plus a "size" value @@ -1094,26 +1131,23 @@ static struct zv_hdr *zv_create(struct zcache_client *cli, uint32_t pool_id, struct tmem_oid *oid, uint32_t index, void *cdata, unsigned clen) { - struct page *page; - struct zv_hdr *zv = NULL; - uint32_t offset; - int alloc_size = clen + sizeof(struct zv_hdr); - int chunks = (alloc_size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT; - int ret; + struct zv_hdr *zv; + int size = clen + sizeof(struct zv_hdr); + int chunks = (size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT; + void *handle = NULL; BUG_ON(!irqs_disabled()); BUG_ON(chunks >= NCHUNKS); - ret = xv_malloc(cli->xvpool, clen + sizeof(struct zv_hdr), - &page, &offset, ZCACHE_GFP_MASK); - if (unlikely(ret)) + handle = zs_malloc(cli->zspool, size); + if (!handle) goto out; atomic_inc(&zv_curr_dist_counts[chunks]); atomic_inc(&zv_cumul_dist_counts[chunks]); - zv = kmap_atomic(page) + offset; + zv = zs_map_object(cli->zspool, handle); zv->index = index; zv->oid = *oid; zv->pool_id = pool_id; - SET_SENTINEL(zv, ZVH); + zv->size = clen; INIT_LIST_HEAD(&zv->rem_op.list); zv->client_id = get_client_id_from_client(cli); zv->rem_op.op = RAMSTER_REMOTIFY_PERS_PUT; @@ -1122,10 +1156,11 @@ static struct zv_hdr *zv_create(struct zcache_client *cli, uint32_t pool_id, list_add_tail(&zv->rem_op.list, &zcache_rem_op_list); spin_unlock(&zcache_rem_op_list_lock); } + SET_SENTINEL(zv, ZVH); memcpy((char *)zv + sizeof(struct zv_hdr), cdata, clen); - kunmap_atomic(zv); + zs_unmap_object(cli->zspool, handle); out: - return zv; + return handle; } /* similar to zv_create, but just reserve space, no data yet */ @@ -1134,71 +1169,74 @@ static struct zv_hdr *zv_alloc(struct tmem_pool *pool, unsigned clen) { struct zcache_client *cli = pool->client; - struct page *page; - struct zv_hdr *zv = NULL; - uint32_t offset; - int ret; + struct zv_hdr *zv; + int size = clen + sizeof(struct zv_hdr); + void *handle = NULL; BUG_ON(!irqs_disabled()); BUG_ON(!is_local_client(pool->client)); - ret = xv_malloc(cli->xvpool, clen + sizeof(struct zv_hdr), - &page, &offset, ZCACHE_GFP_MASK); - if (unlikely(ret)) + handle = zs_malloc(cli->zspool, size); + if (!handle) goto out; - zv = kmap_atomic(page) + offset; - SET_SENTINEL(zv, ZVH); + zv = zs_map_object(cli->zspool, handle); INIT_LIST_HEAD(&zv->rem_op.list); zv->client_id = LOCAL_CLIENT; zv->rem_op.op = RAMSTER_INTRANSIT_PERS; zv->index = index; zv->oid = *oid; zv->pool_id = pool->pool_id; - kunmap_atomic(zv); + zv->size = clen; + SET_SENTINEL(zv, ZVH); + zs_unmap_object(cli->zspool, handle); out: - return zv; + return handle; } -static void zv_free(struct xv_pool *xvpool, struct zv_hdr *zv) +static void zv_free(struct zs_pool *pool, void *handle) { unsigned long flags; - struct page *page; - uint32_t offset; - uint16_t size = xv_get_object_size(zv); - int chunks = (size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT; + struct zv_hdr *zv; + uint16_t size; + int chunks; + zv = zs_map_object(pool, handle); ASSERT_SENTINEL(zv, ZVH); + size = zv->size + sizeof(struct zv_hdr); + INVERT_SENTINEL(zv, ZVH); + + chunks = (size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT; BUG_ON(chunks >= NCHUNKS); atomic_dec(&zv_curr_dist_counts[chunks]); - size -= sizeof(*zv); spin_lock(&zcache_rem_op_list_lock); - size = xv_get_object_size(zv) - sizeof(*zv); BUG_ON(size == 0); - INVERT_SENTINEL(zv, ZVH); if (!list_empty(&zv->rem_op.list)) list_del_init(&zv->rem_op.list); spin_unlock(&zcache_rem_op_list_lock); - page = virt_to_page(zv); - offset = (unsigned long)zv & ~PAGE_MASK; + zs_unmap_object(pool, handle); + local_irq_save(flags); - xv_free(xvpool, page, offset); + zs_free(pool, handle); local_irq_restore(flags); } -static void zv_decompress(struct page *page, struct zv_hdr *zv) +static void zv_decompress(struct tmem_pool *pool, + struct page *page, void *handle) { - size_t clen = PAGE_SIZE; + unsigned int clen = PAGE_SIZE; char *to_va; - unsigned size; int ret; + struct zv_hdr *zv; + struct zcache_client *cli = pool->client; + zv = zs_map_object(cli->zspool, handle); + BUG_ON(zv->size == 0); ASSERT_SENTINEL(zv, ZVH); - size = xv_get_object_size(zv) - sizeof(*zv); - BUG_ON(size == 0); to_va = kmap_atomic(page); - ret = lzo1x_decompress_safe((char *)zv + sizeof(*zv), - size, to_va, &clen); + ret = zcache_comp_op(ZCACHE_COMPOP_DECOMPRESS, (char *)zv + sizeof(*zv), + zv->size, to_va, &clen); kunmap_atomic(to_va); - BUG_ON(ret != LZO_E_OK); + zs_unmap_object(cli->zspool, handle); + BUG_ON(ret); BUG_ON(clen != PAGE_SIZE); } @@ -1207,7 +1245,7 @@ static void zv_copy_from_pampd(char *data, size_t *bufsize, struct zv_hdr *zv) unsigned size; ASSERT_SENTINEL(zv, ZVH); - size = xv_get_object_size(zv) - sizeof(*zv); + size = zv->size; BUG_ON(size == 0 || size > zv_max_page_size); BUG_ON(size > *bufsize); memcpy(data, (char *)zv + sizeof(*zv), size); @@ -1219,7 +1257,7 @@ static void zv_copy_to_pampd(struct zv_hdr *zv, char *data, size_t size) unsigned zv_size; ASSERT_SENTINEL(zv, ZVH); - zv_size = xv_get_object_size(zv) - sizeof(*zv); + zv_size = zv->size; BUG_ON(zv_size != size); BUG_ON(zv_size == 0 || zv_size > zv_max_page_size); memcpy((char *)zv + sizeof(*zv), data, size); @@ -1448,8 +1486,8 @@ int zcache_new_client(uint16_t cli_id) goto out; cli->allocated = 1; #ifdef CONFIG_FRONTSWAP - cli->xvpool = xv_create_pool(); - if (cli->xvpool == NULL) + cli->zspool = zs_create_pool("zcache", ZCACHE_GFP_MASK); + if (cli->zspool == NULL) goto out; #endif ret = 0; @@ -1701,7 +1739,7 @@ static atomic_t zcache_curr_pers_pampd_count = ATOMIC_INIT(0); static unsigned long zcache_curr_pers_pampd_count_max; /* forward reference */ -static int zcache_compress(struct page *from, void **out_va, size_t *out_len); +static int zcache_compress(struct page *from, void **out_va, unsigned *out_len); static int zcache_pampd_eph_create(char *data, size_t size, bool raw, struct tmem_pool *pool, struct tmem_oid *oid, @@ -1709,7 +1747,7 @@ static int zcache_pampd_eph_create(char *data, size_t size, bool raw, { int ret = -1; void *cdata = data; - size_t clen = size; + unsigned int clen = size; struct zcache_client *cli = pool->client; uint16_t client_id = get_client_id_from_client(cli); struct page *page = NULL; @@ -1750,7 +1788,7 @@ static int zcache_pampd_pers_create(char *data, size_t size, bool raw, { int ret = -1; void *cdata = data; - size_t clen = size; + unsigned int clen = size; struct zcache_client *cli = pool->client; struct page *page; unsigned long count; @@ -1788,7 +1826,7 @@ static int zcache_pampd_pers_create(char *data, size_t size, bool raw, } /* reject if mean compression is too poor */ if ((clen > zv_max_mean_zsize) && (curr_pers_pampd_count > 0)) { - total_zsize = xv_get_total_size_bytes(cli->xvpool); + total_zsize = zs_get_total_size_bytes(cli->zspool); zv_mean_zsize = div_u64(total_zsize, curr_pers_pampd_count); if (zv_mean_zsize > zv_max_mean_zsize) { zcache_mean_compress_poor++; @@ -1851,7 +1889,7 @@ static int zcache_pampd_get_data(char *data, size_t *bufsize, bool raw, if (raw) zv_copy_from_pampd(data, bufsize, pampd); else - zv_decompress(virt_to_page(data), pampd); + zv_decompress(pool, virt_to_page(data), pampd); return ret; } @@ -1882,8 +1920,8 @@ static int zcache_pampd_get_data_and_free(char *data, size_t *bufsize, bool raw, if (raw) zv_copy_from_pampd(data, bufsize, pampd); else - zv_decompress(virt_to_page(data), pampd); - zv_free(cli->xvpool, pampd); + zv_decompress(pool, virt_to_page(data), pampd); + zv_free(cli->zspool, pampd); if (!is_local_client(cli)) dec_and_check(&ramster_foreign_pers_pampd_count); dec_and_check(&zcache_curr_pers_pampd_count); @@ -1951,7 +1989,7 @@ local_pers: zv = (struct zv_hdr *)pampd; if (!is_local_client(pool->client)) dec_and_check(&ramster_foreign_pers_pampd_count); - zv_free(cli->xvpool, zv); + zv_free(cli->zspool, zv); if (acct) /* FIXME get these working properly again */ dec_and_check(&zcache_curr_pers_pampd_count); @@ -2019,7 +2057,7 @@ int zcache_localify(int pool_id, struct tmem_oid *oidp, unsigned long flags; struct tmem_pool *pool; bool ephemeral, delete = false; - size_t clen = PAGE_SIZE; + unsigned int clen = PAGE_SIZE; void *pampd, *saved_hb; struct tmem_obj *obj; @@ -2074,9 +2112,9 @@ int zcache_localify(int pool_id, struct tmem_oid *oidp, } if (extra != NULL) { /* decompress direct-to-memory to complete remotify */ - ret = lzo1x_decompress_safe((char *)data, size, - (char *)extra, &clen); - BUG_ON(ret != LZO_E_OK); + ret = zcache_comp_op(ZCACHE_COMPOP_DECOMPRESS, (char *)data, + size, (char *)extra, &clen); + BUG_ON(ret); BUG_ON(clen != PAGE_SIZE); } if (ephemeral) @@ -2188,25 +2226,24 @@ static struct tmem_pamops zcache_pamops = { * zcache compression/decompression and related per-cpu stuff */ -#define LZO_WORKMEM_BYTES LZO1X_1_MEM_COMPRESS -#define LZO_DSTMEM_PAGE_ORDER 1 -static DEFINE_PER_CPU(unsigned char *, zcache_workmem); static DEFINE_PER_CPU(unsigned char *, zcache_dstmem); +#define ZCACHE_DSTMEM_ORDER 1 -static int zcache_compress(struct page *from, void **out_va, size_t *out_len) +static int zcache_compress(struct page *from, void **out_va, unsigned *out_len) { int ret = 0; unsigned char *dmem = __get_cpu_var(zcache_dstmem); - unsigned char *wmem = __get_cpu_var(zcache_workmem); char *from_va; BUG_ON(!irqs_disabled()); - if (unlikely(dmem == NULL || wmem == NULL)) - goto out; /* no buffer, so can't compress */ + if (unlikely(dmem == NULL)) + goto out; /* no buffer or no compressor so can't compress */ + *out_len = PAGE_SIZE << ZCACHE_DSTMEM_ORDER; from_va = kmap_atomic(from); mb(); - ret = lzo1x_1_compress(from_va, PAGE_SIZE, dmem, out_len, wmem); - BUG_ON(ret != LZO_E_OK); + ret = zcache_comp_op(ZCACHE_COMPOP_COMPRESS, from_va, PAGE_SIZE, dmem, + out_len); + BUG_ON(ret); *out_va = dmem; kunmap_atomic(from_va); ret = 1; @@ -2214,33 +2251,52 @@ out: return ret; } +static int zcache_comp_cpu_up(int cpu) +{ + struct crypto_comp *tfm; + + tfm = crypto_alloc_comp(zcache_comp_name, 0, 0); + if (IS_ERR(tfm)) + return NOTIFY_BAD; + *per_cpu_ptr(zcache_comp_pcpu_tfms, cpu) = tfm; + return NOTIFY_OK; +} + +static void zcache_comp_cpu_down(int cpu) +{ + struct crypto_comp *tfm; + + tfm = *per_cpu_ptr(zcache_comp_pcpu_tfms, cpu); + crypto_free_comp(tfm); + *per_cpu_ptr(zcache_comp_pcpu_tfms, cpu) = NULL; +} static int zcache_cpu_notifier(struct notifier_block *nb, unsigned long action, void *pcpu) { - int cpu = (long)pcpu; + int ret, cpu = (long)pcpu; struct zcache_preload *kp; switch (action) { case CPU_UP_PREPARE: + ret = zcache_comp_cpu_up(cpu); + if (ret != NOTIFY_OK) { + pr_err("zcache: can't allocate compressor transform\n"); + return ret; + } per_cpu(zcache_dstmem, cpu) = (void *)__get_free_pages( - GFP_KERNEL | __GFP_REPEAT, - LZO_DSTMEM_PAGE_ORDER), - per_cpu(zcache_workmem, cpu) = - kzalloc(LZO1X_MEM_COMPRESS, - GFP_KERNEL | __GFP_REPEAT); + GFP_KERNEL | __GFP_REPEAT, ZCACHE_DSTMEM_ORDER), per_cpu(zcache_remoteputmem, cpu) = kzalloc(PAGE_SIZE, GFP_KERNEL | __GFP_REPEAT); break; case CPU_DEAD: case CPU_UP_CANCELED: + zcache_comp_cpu_down(cpu); kfree(per_cpu(zcache_remoteputmem, cpu)); per_cpu(zcache_remoteputmem, cpu) = NULL; free_pages((unsigned long)per_cpu(zcache_dstmem, cpu), - LZO_DSTMEM_PAGE_ORDER); + ZCACHE_DSTMEM_ORDER); per_cpu(zcache_dstmem, cpu) = NULL; - kfree(per_cpu(zcache_workmem, cpu)); - per_cpu(zcache_workmem, cpu) = NULL; kp = &per_cpu(zcache_preloads, cpu); while (kp->nr) { kmem_cache_free(zcache_objnode_cache, @@ -2752,7 +2808,8 @@ int zcache_client_destroy_pool(int cli_id, int pool_id) ret = tmem_destroy_pool(pool); local_bh_enable(); kfree(pool); - pr_info("ramster: destroyed pool id=%d cli_id=%d\n", pool_id, cli_id); + pr_info("ramster: destroyed pool id=%d cli_id=%d\n", + pool_id, cli_id); out: return ret; } @@ -3245,6 +3302,44 @@ static int __init no_frontswap(char *s) __setup("nofrontswap", no_frontswap); +static int __init enable_zcache_compressor(char *s) +{ + strncpy(zcache_comp_name, s, ZCACHE_COMP_NAME_SZ); + ramster_enabled = 1; + return 1; +} +__setup("zcache=", enable_zcache_compressor); + + +static int zcache_comp_init(void) +{ + int ret = 0; + + /* check crypto algorithm */ + if (*zcache_comp_name != '\0') { + ret = crypto_has_comp(zcache_comp_name, 0, 0); + if (!ret) + pr_info("zcache: %s not supported\n", + zcache_comp_name); + } + if (!ret) + strcpy(zcache_comp_name, "lzo"); + ret = crypto_has_comp(zcache_comp_name, 0, 0); + if (!ret) { + ret = 1; + goto out; + } + pr_info("zcache: using %s compressor\n", zcache_comp_name); + + /* alloc percpu transforms */ + ret = 0; + zcache_comp_pcpu_tfms = alloc_percpu(struct crypto_comp *); + if (!zcache_comp_pcpu_tfms) + ret = 1; +out: + return ret; +} + static int __init zcache_init(void) { int ret = 0; @@ -3269,6 +3364,11 @@ static int __init zcache_init(void) pr_err("ramster: can't register cpu notifier\n"); goto out; } + ret = zcache_comp_init(); + if (ret) { + pr_err("zcache: compressor initialization failed\n"); + goto out; + } for_each_online_cpu(cpu) { void *pcpu = (void *)(long)cpu; zcache_cpu_notifier(&zcache_cpu_notifier_block, @@ -3306,7 +3406,7 @@ static int __init zcache_init(void) zcache_new_client(LOCAL_CLIENT); old_ops = zcache_frontswap_register_ops(); pr_info("ramster: frontswap enabled using kernel " - "transcendent memory and xvmalloc\n"); + "transcendent memory and zsmalloc\n"); if (old_ops.init != NULL) pr_warning("ramster: frontswap_ops overridden"); } -- cgit v0.10.2 From 67eedba39ed1ac29908453647652c02fbbeeca1b Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 11 May 2012 11:36:52 +0200 Subject: iio: core: introduce dB scle: IIO_VAL_INT_PLUS_MICRO_DB Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index b39a587..425cd4c 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -295,26 +295,33 @@ static ssize_t iio_read_channel_info(struct device *dev, struct iio_dev *indio_dev = dev_get_drvdata(dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int val, val2; + bool scale_db = false; int ret = indio_dev->info->read_raw(indio_dev, this_attr->c, &val, &val2, this_attr->address); if (ret < 0) return ret; - if (ret == IIO_VAL_INT) + switch (ret) { + case IIO_VAL_INT: return sprintf(buf, "%d\n", val); - else if (ret == IIO_VAL_INT_PLUS_MICRO) { + case IIO_VAL_INT_PLUS_MICRO_DB: + scale_db = true; + case IIO_VAL_INT_PLUS_MICRO: if (val2 < 0) - return sprintf(buf, "-%d.%06u\n", val, -val2); + return sprintf(buf, "-%d.%06u%s\n", val, -val2, + scale_db ? " dB" : ""); else - return sprintf(buf, "%d.%06u\n", val, val2); - } else if (ret == IIO_VAL_INT_PLUS_NANO) { + return sprintf(buf, "%d.%06u%s\n", val, val2, + scale_db ? " dB" : ""); + case IIO_VAL_INT_PLUS_NANO: if (val2 < 0) return sprintf(buf, "-%d.%09u\n", val, -val2); else return sprintf(buf, "%d.%09u\n", val, val2); - } else + default: return 0; + } } static ssize_t iio_write_channel_info(struct device *dev, diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h index a471fd5..1b073b1 100644 --- a/include/linux/iio/types.h +++ b/include/linux/iio/types.h @@ -50,5 +50,6 @@ enum iio_modifier { #define IIO_VAL_INT 1 #define IIO_VAL_INT_PLUS_MICRO 2 #define IIO_VAL_INT_PLUS_NANO 3 +#define IIO_VAL_INT_PLUS_MICRO_DB 4 #endif /* _IIO_TYPES_H_ */ -- cgit v0.10.2 From b65d62122fa57035fae06a78e0b65622a1e1bc34 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 11 May 2012 11:36:53 +0200 Subject: iio: core: introduce IIO_CHAN_INFO_HARDWAREGAIN Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 2ce4dad..5bc8a47 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -280,6 +280,13 @@ Description: If a discrete set of scale values are available, they are listed in this attribute. +What /sys/bus/iio/devices/iio:deviceX/out_voltageY_hardwaregain +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Hardware applied gain factor. If shared across all channels, + _hardwaregain is used. + What: /sys/.../in_accel_filter_low_pass_3db_frequency What: /sys/.../in_magn_filter_low_pass_3db_frequency What: /sys/.../in_anglvel_filter_low_pass_3db_frequency diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 425cd4c..86f3460 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -91,6 +91,7 @@ static const char * const iio_chan_info_postfix[] = { [IIO_CHAN_INFO_SAMP_FREQ] = "sampling_frequency", [IIO_CHAN_INFO_FREQUENCY] = "frequency", [IIO_CHAN_INFO_PHASE] = "phase", + [IIO_CHAN_INFO_HARDWAREGAIN] = "hardwaregain", }; const struct iio_chan_spec diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 6fdbdb8..897c6b01 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -34,6 +34,7 @@ enum iio_chan_info_enum { IIO_CHAN_INFO_SAMP_FREQ, IIO_CHAN_INFO_FREQUENCY, IIO_CHAN_INFO_PHASE, + IIO_CHAN_INFO_HARDWAREGAIN, }; #define IIO_CHAN_INFO_SHARED_BIT(type) BIT(type*2) @@ -95,6 +96,10 @@ enum iio_chan_info_enum { IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_PHASE) #define IIO_CHAN_INFO_PHASE_SHARED_BIT \ IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_PHASE) +#define IIO_CHAN_INFO_HARDWAREGAIN_SEPARATE_BIT \ + IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_HARDWAREGAIN) +#define IIO_CHAN_INFO_HARDWAREGAIN_SHARED_BIT \ + IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_HARDWAREGAIN) enum iio_endian { IIO_CPU, -- cgit v0.10.2 From e71d42e03c60d215bde295d2b986bbc96878c7d6 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 11 May 2012 11:36:54 +0200 Subject: iio: amplifiers: New driver for AD8366 Dual-Digital Variable Gain Amplifier Changes since V1: Apply review feedback: Introduce and use IIO_CHAN_INFO_HARDWAREGAIN Introduce and use Use IIO_VAL_INT_PLUS_MICRO_DB Modify out of staging include paths. Convert to new iio core API naming. Changes since V2: more sanity checking in write_raw Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index 3ab7d48..bb1e35c 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -48,4 +48,6 @@ config IIO_CONSUMERS_PER_TRIGGER This value controls the maximum number of consumers that a given trigger may handle. Default is 2. +source "drivers/iio/amplifiers/Kconfig" + endif # IIO diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index d5fc57d..5552491 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -8,3 +8,5 @@ industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o + +obj-y += amplifiers/ diff --git a/drivers/iio/amplifiers/Kconfig b/drivers/iio/amplifiers/Kconfig new file mode 100644 index 0000000..05d707e --- /dev/null +++ b/drivers/iio/amplifiers/Kconfig @@ -0,0 +1,17 @@ +# +# Gain Amplifiers, etc. +# +menu "Amplifiers" + +config AD8366 + tristate "Analog Devices AD8366 VGA" + depends on SPI + select BITREVERSE + help + Say yes here to build support for Analog Devices AD8366 + SPI Dual-Digital Variable Gain Amplifier (VGA). + + To compile this driver as a module, choose M here: the + module will be called ad8366. + +endmenu diff --git a/drivers/iio/amplifiers/Makefile b/drivers/iio/amplifiers/Makefile new file mode 100644 index 0000000..a6ca366 --- /dev/null +++ b/drivers/iio/amplifiers/Makefile @@ -0,0 +1,5 @@ +# +# Makefile iio/amplifiers +# + +obj-$(CONFIG_AD8366) += ad8366.o diff --git a/drivers/iio/amplifiers/ad8366.c b/drivers/iio/amplifiers/ad8366.c new file mode 100644 index 0000000..d8281cd --- /dev/null +++ b/drivers/iio/amplifiers/ad8366.c @@ -0,0 +1,222 @@ +/* + * AD8366 SPI Dual-Digital Variable Gain Amplifier (VGA) + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +struct ad8366_state { + struct spi_device *spi; + struct regulator *reg; + unsigned char ch[2]; + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + unsigned char data[2] ____cacheline_aligned; +}; + +static int ad8366_write(struct iio_dev *indio_dev, + unsigned char ch_a, char unsigned ch_b) +{ + struct ad8366_state *st = iio_priv(indio_dev); + int ret; + + ch_a = bitrev8(ch_a & 0x3F); + ch_b = bitrev8(ch_b & 0x3F); + + st->data[0] = ch_b >> 4; + st->data[1] = (ch_b << 4) | (ch_a >> 2); + + ret = spi_write(st->spi, st->data, ARRAY_SIZE(st->data)); + if (ret < 0) + dev_err(&indio_dev->dev, "write failed (%d)", ret); + + return ret; +} + +static int ad8366_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + struct ad8366_state *st = iio_priv(indio_dev); + int ret; + unsigned code; + + mutex_lock(&indio_dev->mlock); + switch (m) { + case IIO_CHAN_INFO_HARDWAREGAIN: + code = st->ch[chan->channel]; + + /* Values in dB */ + code = code * 253 + 4500; + *val = code / 1000; + *val2 = (code % 1000) * 1000; + + ret = IIO_VAL_INT_PLUS_MICRO_DB; + break; + default: + ret = -EINVAL; + } + mutex_unlock(&indio_dev->mlock); + + return ret; +}; + +static int ad8366_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct ad8366_state *st = iio_priv(indio_dev); + unsigned code; + int ret; + + if (val < 0 || val2 < 0) + return -EINVAL; + + /* Values in dB */ + code = (((u8)val * 1000) + ((u32)val2 / 1000)); + + if (code > 20500 || code < 4500) + return -EINVAL; + + code = (code - 4500) / 253; + + mutex_lock(&indio_dev->mlock); + switch (mask) { + case IIO_CHAN_INFO_HARDWAREGAIN: + st->ch[chan->channel] = code; + ret = ad8366_write(indio_dev, st->ch[0], st->ch[1]); + break; + default: + ret = -EINVAL; + } + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static const struct iio_info ad8366_info = { + .read_raw = &ad8366_read_raw, + .write_raw = &ad8366_write_raw, + .driver_module = THIS_MODULE, +}; + +#define AD8366_CHAN(_channel) { \ + .type = IIO_VOLTAGE, \ + .output = 1, \ + .indexed = 1, \ + .channel = _channel, \ + .info_mask = IIO_CHAN_INFO_HARDWAREGAIN_SEPARATE_BIT,\ +} + +static const struct iio_chan_spec ad8366_channels[] = { + AD8366_CHAN(0), + AD8366_CHAN(1), +}; + +static int __devinit ad8366_probe(struct spi_device *spi) +{ + struct iio_dev *indio_dev; + struct ad8366_state *st; + int ret; + + indio_dev = iio_device_alloc(sizeof(*st)); + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + + st->reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + } + + spi_set_drvdata(spi, indio_dev); + st->spi = spi; + + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->info = &ad8366_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = ad8366_channels; + indio_dev->num_channels = ARRAY_SIZE(ad8366_channels); + + ret = iio_device_register(indio_dev); + if (ret) + goto error_disable_reg; + + ad8366_write(indio_dev, 0 , 0); + + return 0; + +error_disable_reg: + if (!IS_ERR(st->reg)) + regulator_disable(st->reg); +error_put_reg: + if (!IS_ERR(st->reg)) + regulator_put(st->reg); + + iio_device_free(indio_dev); + + return ret; +} + +static int __devexit ad8366_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad8366_state *st = iio_priv(indio_dev); + struct regulator *reg = st->reg; + + iio_device_unregister(indio_dev); + + if (!IS_ERR(reg)) { + regulator_disable(reg); + regulator_put(reg); + } + + iio_device_free(indio_dev); + + return 0; +} + +static const struct spi_device_id ad8366_id[] = { + {"ad8366", 0}, + {} +}; + +static struct spi_driver ad8366_driver = { + .driver = { + .name = KBUILD_MODNAME, + .owner = THIS_MODULE, + }, + .probe = ad8366_probe, + .remove = __devexit_p(ad8366_remove), + .id_table = ad8366_id, +}; + +module_spi_driver(ad8366_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD8366 VGA"); +MODULE_LICENSE("GPL v2"); -- cgit v0.10.2 From aaeb6dfff02f9c1077c2a09c45b99f6255ef9159 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Fri, 11 May 2012 15:35:32 +0200 Subject: ARM: AT91: Add platform data for the AT91 ADCs The AT91 SoCs often embeds an ADC. This patch adds the needed platform data to specify the informations required by the driver to work properly. For now, we only need the reference voltage and which channels are available on the board. Signed-off-by: Maxime Ripard Acked-by: Nicolas Ferre Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/include/linux/platform_data/at91_adc.h b/include/linux/platform_data/at91_adc.h new file mode 100644 index 0000000..e15745b --- /dev/null +++ b/include/linux/platform_data/at91_adc.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2011 Free Electrons + * + * Licensed under the GPLv2 or later. + */ + +#ifndef _AT91_ADC_H_ +#define _AT91_ADC_H_ + +/** + * struct at91_adc_reg_desc - Various informations relative to registers + * @channel_base: Base offset for the channel data registers + * @drdy_mask: Mask of the DRDY field in the relevant registers + (Interruptions registers mostly) + * @status_register: Offset of the Interrupt Status Register + * @trigger_register: Offset of the Trigger setup register + */ +struct at91_adc_reg_desc { + u8 channel_base; + u32 drdy_mask; + u8 status_register; + u8 trigger_register; +}; + +/** + * struct at91_adc_trigger - description of triggers + * @name: name of the trigger advertised to the user + * @value: value to set in the ADC's trigger setup register + to enable the trigger + * @is_external: Does the trigger rely on an external pin? + */ +struct at91_adc_trigger { + const char *name; + u8 value; + bool is_external; +}; + +/** + * struct at91_adc_data - platform data for ADC driver + * @channels_used: channels in use on the board as a bitmask + * @num_channels: global number of channels available on the board + * @registers: Registers definition on the board + * @startup_time: startup time of the ADC in microseconds + * @trigger_list: Triggers available in the ADC + * @trigger_number: Number of triggers available in the ADC + * @use_external_triggers: does the board has external triggers availables + * @vref: Reference voltage for the ADC in millivolts + */ +struct at91_adc_data { + unsigned long channels_used; + u8 num_channels; + struct at91_adc_reg_desc *registers; + u8 startup_time; + struct at91_adc_trigger *trigger_list; + u8 trigger_number; + bool use_external_triggers; + u16 vref; +}; + +extern void __init at91_add_device_adc(struct at91_adc_data *data); +#endif -- cgit v0.10.2 From 0e589d5fb3172b0dde7fdad3a4829ce5352dd30d Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Fri, 11 May 2012 15:35:33 +0200 Subject: ARM: AT91: IIO: Add AT91 ADC driver. Add the ADC driver for Atmel's AT91SAM9G20-EK, AT91SAM9M10G45-EK and AT91SAM9X5 family boards. It has support for both software and hardware triggers. Signed-off-by: Maxime Ripard Acked-by: Nicolas Ferre Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index bb1e35c..56eecef 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -48,6 +48,7 @@ config IIO_CONSUMERS_PER_TRIGGER This value controls the maximum number of consumers that a given trigger may handle. Default is 2. +source "drivers/iio/adc/Kconfig" source "drivers/iio/amplifiers/Kconfig" endif # IIO diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index 5552491..e425afd 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -9,4 +9,5 @@ industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o +obj-y += adc/ obj-y += amplifiers/ diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig new file mode 100644 index 0000000..9a0df81 --- /dev/null +++ b/drivers/iio/adc/Kconfig @@ -0,0 +1,16 @@ +# +# ADC drivers +# +menu "Analog to digital converters" + +config AT91_ADC + tristate "Atmel AT91 ADC" + depends on ARCH_AT91 + select IIO_BUFFER + select IIO_KFIFO_BUF + select IIO_TRIGGER + select SYSFS + help + Say yes here to build support for Atmel AT91 ADC. + +endmenu diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile new file mode 100644 index 0000000..175c8d4 --- /dev/null +++ b/drivers/iio/adc/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for IIO ADC drivers +# + +obj-$(CONFIG_AT91_ADC) += at91_adc.o diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c new file mode 100644 index 0000000..e2eb613 --- /dev/null +++ b/drivers/iio/adc/at91_adc.c @@ -0,0 +1,672 @@ +/* + * Driver for the ADC present in the Atmel AT91 evaluation boards. + * + * Copyright 2011 Free Electrons + * + * Licensed under the GPLv2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#define AT91_ADC_CHAN(st, ch) \ + (st->registers->channel_base + (ch * 4)) +#define at91_adc_readl(st, reg) \ + (readl_relaxed(st->reg_base + reg)) +#define at91_adc_writel(st, reg, val) \ + (writel_relaxed(val, st->reg_base + reg)) + +struct at91_adc_state { + struct clk *adc_clk; + u16 *buffer; + unsigned long channels_mask; + struct clk *clk; + bool done; + int irq; + bool irq_enabled; + u16 last_value; + struct mutex lock; + u8 num_channels; + void __iomem *reg_base; + struct at91_adc_reg_desc *registers; + u8 startup_time; + struct iio_trigger **trig; + struct at91_adc_trigger *trigger_list; + u32 trigger_number; + bool use_external; + u32 vref_mv; + wait_queue_head_t wq_data_avail; +}; + +static irqreturn_t at91_adc_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *idev = pf->indio_dev; + struct at91_adc_state *st = iio_priv(idev); + struct iio_buffer *buffer = idev->buffer; + int i, j = 0; + + for (i = 0; i < idev->masklength; i++) { + if (!test_bit(i, idev->active_scan_mask)) + continue; + st->buffer[j] = at91_adc_readl(st, AT91_ADC_CHAN(st, i)); + j++; + } + + if (idev->scan_timestamp) { + s64 *timestamp = (s64 *)((u8 *)st->buffer + + ALIGN(j, sizeof(s64))); + *timestamp = pf->timestamp; + } + + buffer->access->store_to(buffer, (u8 *)st->buffer, pf->timestamp); + + iio_trigger_notify_done(idev->trig); + st->irq_enabled = true; + + /* Needed to ACK the DRDY interruption */ + at91_adc_readl(st, AT91_ADC_LCDR); + + enable_irq(st->irq); + + return IRQ_HANDLED; +} + +static irqreturn_t at91_adc_eoc_trigger(int irq, void *private) +{ + struct iio_dev *idev = private; + struct at91_adc_state *st = iio_priv(idev); + u32 status = at91_adc_readl(st, st->registers->status_register); + + if (!(status & st->registers->drdy_mask)) + return IRQ_HANDLED; + + if (iio_buffer_enabled(idev)) { + disable_irq_nosync(irq); + st->irq_enabled = false; + iio_trigger_poll(idev->trig, iio_get_time_ns()); + } else { + st->last_value = at91_adc_readl(st, AT91_ADC_LCDR); + st->done = true; + wake_up_interruptible(&st->wq_data_avail); + } + + return IRQ_HANDLED; +} + +static int at91_adc_channel_init(struct iio_dev *idev) +{ + struct at91_adc_state *st = iio_priv(idev); + struct iio_chan_spec *chan_array, *timestamp; + int bit, idx = 0; + + idev->num_channels = bitmap_weight(&st->channels_mask, + st->num_channels) + 1; + + chan_array = devm_kzalloc(&idev->dev, + ((idev->num_channels + 1) * + sizeof(struct iio_chan_spec)), + GFP_KERNEL); + + if (!chan_array) + return -ENOMEM; + + for_each_set_bit(bit, &st->channels_mask, st->num_channels) { + struct iio_chan_spec *chan = chan_array + idx; + + chan->type = IIO_VOLTAGE; + chan->indexed = 1; + chan->channel = bit; + chan->scan_index = idx; + chan->scan_type.sign = 'u'; + chan->scan_type.realbits = 10; + chan->scan_type.storagebits = 16; + chan->info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_RAW_SEPARATE_BIT; + idx++; + } + timestamp = chan_array + idx; + + timestamp->type = IIO_TIMESTAMP; + timestamp->channel = -1; + timestamp->scan_index = idx; + timestamp->scan_type.sign = 's'; + timestamp->scan_type.realbits = 64; + timestamp->scan_type.storagebits = 64; + + idev->channels = chan_array; + return idev->num_channels; +} + +static u8 at91_adc_get_trigger_value_by_name(struct iio_dev *idev, + struct at91_adc_trigger *triggers, + const char *trigger_name) +{ + struct at91_adc_state *st = iio_priv(idev); + u8 value = 0; + int i; + + for (i = 0; i < st->trigger_number; i++) { + char *name = kasprintf(GFP_KERNEL, + "%s-dev%d-%s", + idev->name, + idev->id, + triggers[i].name); + if (!name) + return -ENOMEM; + + if (strcmp(trigger_name, name) == 0) { + value = triggers[i].value; + kfree(name); + break; + } + + kfree(name); + } + + return value; +} + +static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state) +{ + struct iio_dev *idev = trig->private_data; + struct at91_adc_state *st = iio_priv(idev); + struct iio_buffer *buffer = idev->buffer; + struct at91_adc_reg_desc *reg = st->registers; + u32 status = at91_adc_readl(st, reg->trigger_register); + u8 value; + u8 bit; + + value = at91_adc_get_trigger_value_by_name(idev, + st->trigger_list, + idev->trig->name); + if (value == 0) + return -EINVAL; + + if (state) { + st->buffer = kmalloc(idev->scan_bytes, GFP_KERNEL); + if (st->buffer == NULL) + return -ENOMEM; + + at91_adc_writel(st, reg->trigger_register, + status | value); + + for_each_set_bit(bit, buffer->scan_mask, + st->num_channels) { + struct iio_chan_spec const *chan = idev->channels + bit; + at91_adc_writel(st, AT91_ADC_CHER, + AT91_ADC_CH(chan->channel)); + } + + at91_adc_writel(st, AT91_ADC_IER, reg->drdy_mask); + + } else { + at91_adc_writel(st, AT91_ADC_IDR, reg->drdy_mask); + + at91_adc_writel(st, reg->trigger_register, + status & ~value); + + for_each_set_bit(bit, buffer->scan_mask, + st->num_channels) { + struct iio_chan_spec const *chan = idev->channels + bit; + at91_adc_writel(st, AT91_ADC_CHDR, + AT91_ADC_CH(chan->channel)); + } + kfree(st->buffer); + } + + return 0; +} + +static const struct iio_trigger_ops at91_adc_trigger_ops = { + .owner = THIS_MODULE, + .set_trigger_state = &at91_adc_configure_trigger, +}; + +static struct iio_trigger *at91_adc_allocate_trigger(struct iio_dev *idev, + struct at91_adc_trigger *trigger) +{ + struct iio_trigger *trig; + int ret; + + trig = iio_trigger_alloc("%s-dev%d-%s", idev->name, + idev->id, trigger->name); + if (trig == NULL) + return NULL; + + trig->dev.parent = idev->dev.parent; + trig->private_data = idev; + trig->ops = &at91_adc_trigger_ops; + + ret = iio_trigger_register(trig); + if (ret) + return NULL; + + return trig; +} + +static int at91_adc_trigger_init(struct iio_dev *idev) +{ + struct at91_adc_state *st = iio_priv(idev); + int i, ret; + + st->trig = devm_kzalloc(&idev->dev, + st->trigger_number * sizeof(st->trig), + GFP_KERNEL); + + if (st->trig == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + for (i = 0; i < st->trigger_number; i++) { + if (st->trigger_list[i].is_external && !(st->use_external)) + continue; + + st->trig[i] = at91_adc_allocate_trigger(idev, + st->trigger_list + i); + if (st->trig[i] == NULL) { + dev_err(&idev->dev, + "Could not allocate trigger %d\n", i); + ret = -ENOMEM; + goto error_trigger; + } + } + + return 0; + +error_trigger: + for (i--; i >= 0; i--) { + iio_trigger_unregister(st->trig[i]); + iio_trigger_free(st->trig[i]); + } +error_ret: + return ret; +} + +static void at91_adc_trigger_remove(struct iio_dev *idev) +{ + struct at91_adc_state *st = iio_priv(idev); + int i; + + for (i = 0; i < st->trigger_number; i++) { + iio_trigger_unregister(st->trig[i]); + iio_trigger_free(st->trig[i]); + } +} + +static const struct iio_buffer_setup_ops at91_adc_buffer_ops = { + .preenable = &iio_sw_buffer_preenable, + .postenable = &iio_triggered_buffer_postenable, + .predisable = &iio_triggered_buffer_predisable, +}; + +static int at91_adc_buffer_init(struct iio_dev *idev) +{ + int ret; + + idev->buffer = iio_kfifo_allocate(idev); + if (!idev->buffer) { + ret = -ENOMEM; + goto error_ret; + } + + idev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, + &at91_adc_trigger_handler, + IRQF_ONESHOT, + idev, + "%s-consumer%d", + idev->name, + idev->id); + if (idev->pollfunc == NULL) { + ret = -ENOMEM; + goto error_pollfunc; + } + + idev->setup_ops = &at91_adc_buffer_ops; + idev->modes |= INDIO_BUFFER_TRIGGERED; + + ret = iio_buffer_register(idev, + idev->channels, + idev->num_channels); + if (ret) + goto error_register; + + return 0; + +error_register: + iio_dealloc_pollfunc(idev->pollfunc); +error_pollfunc: + iio_kfifo_free(idev->buffer); +error_ret: + return ret; +} + +static void at91_adc_buffer_remove(struct iio_dev *idev) +{ + iio_buffer_unregister(idev); + iio_dealloc_pollfunc(idev->pollfunc); + iio_kfifo_free(idev->buffer); +} + +static int at91_adc_read_raw(struct iio_dev *idev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct at91_adc_state *st = iio_priv(idev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + mutex_lock(&st->lock); + + at91_adc_writel(st, AT91_ADC_CHER, + AT91_ADC_CH(chan->channel)); + at91_adc_writel(st, AT91_ADC_IER, st->registers->drdy_mask); + at91_adc_writel(st, AT91_ADC_CR, AT91_ADC_START); + + ret = wait_event_interruptible_timeout(st->wq_data_avail, + st->done, + msecs_to_jiffies(1000)); + if (ret == 0) + return -ETIMEDOUT; + else if (ret < 0) + return ret; + + *val = st->last_value; + + at91_adc_writel(st, AT91_ADC_CHDR, + AT91_ADC_CH(chan->channel)); + at91_adc_writel(st, AT91_ADC_IDR, st->registers->drdy_mask); + + st->last_value = 0; + st->done = false; + mutex_unlock(&st->lock); + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + *val = (st->vref_mv * 1000) >> chan->scan_type.realbits; + *val2 = 0; + return IIO_VAL_INT_PLUS_MICRO; + default: + break; + } + return -EINVAL; +} + +static int at91_adc_probe_pdata(struct at91_adc_state *st, + struct platform_device *pdev) +{ + struct at91_adc_data *pdata = pdev->dev.platform_data; + + if (!pdata) + return -EINVAL; + + st->use_external = pdata->use_external_triggers; + st->vref_mv = pdata->vref; + st->channels_mask = pdata->channels_used; + st->num_channels = pdata->num_channels; + st->startup_time = pdata->startup_time; + st->trigger_number = pdata->trigger_number; + st->trigger_list = pdata->trigger_list; + st->registers = pdata->registers; + + return 0; +} + +static const struct iio_info at91_adc_info = { + .driver_module = THIS_MODULE, + .read_raw = &at91_adc_read_raw, +}; + +static int __devinit at91_adc_probe(struct platform_device *pdev) +{ + unsigned int prsc, mstrclk, ticks, adc_clk; + int ret; + struct iio_dev *idev; + struct at91_adc_state *st; + struct resource *res; + + idev = iio_device_alloc(sizeof(struct at91_adc_state)); + if (idev == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + st = iio_priv(idev); + + ret = at91_adc_probe_pdata(st, pdev); + if (ret) { + dev_err(&pdev->dev, "No platform data available.\n"); + ret = -EINVAL; + goto error_free_device; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "No resource defined\n"); + ret = -ENXIO; + goto error_ret; + } + + platform_set_drvdata(pdev, idev); + + idev->dev.parent = &pdev->dev; + idev->name = dev_name(&pdev->dev); + idev->modes = INDIO_DIRECT_MODE; + idev->info = &at91_adc_info; + + st->irq = platform_get_irq(pdev, 0); + if (st->irq < 0) { + dev_err(&pdev->dev, "No IRQ ID is designated\n"); + ret = -ENODEV; + goto error_free_device; + } + + if (!request_mem_region(res->start, resource_size(res), + "AT91 adc registers")) { + dev_err(&pdev->dev, "Resources are unavailable.\n"); + ret = -EBUSY; + goto error_free_device; + } + + st->reg_base = ioremap(res->start, resource_size(res)); + if (!st->reg_base) { + dev_err(&pdev->dev, "Failed to map registers.\n"); + ret = -ENOMEM; + goto error_release_mem; + } + + /* + * Disable all IRQs before setting up the handler + */ + at91_adc_writel(st, AT91_ADC_CR, AT91_ADC_SWRST); + at91_adc_writel(st, AT91_ADC_IDR, 0xFFFFFFFF); + ret = request_irq(st->irq, + at91_adc_eoc_trigger, + 0, + pdev->dev.driver->name, + idev); + if (ret) { + dev_err(&pdev->dev, "Failed to allocate IRQ.\n"); + goto error_unmap_reg; + } + + st->clk = clk_get(&pdev->dev, "adc_clk"); + if (IS_ERR(st->clk)) { + dev_err(&pdev->dev, "Failed to get the clock.\n"); + ret = PTR_ERR(st->clk); + goto error_free_irq; + } + + ret = clk_prepare(st->clk); + if (ret) { + dev_err(&pdev->dev, "Could not prepare the clock.\n"); + goto error_free_clk; + } + + ret = clk_enable(st->clk); + if (ret) { + dev_err(&pdev->dev, "Could not enable the clock.\n"); + goto error_unprepare_clk; + } + + st->adc_clk = clk_get(&pdev->dev, "adc_op_clk"); + if (IS_ERR(st->adc_clk)) { + dev_err(&pdev->dev, "Failed to get the ADC clock.\n"); + ret = PTR_ERR(st->clk); + goto error_disable_clk; + } + + ret = clk_prepare(st->adc_clk); + if (ret) { + dev_err(&pdev->dev, "Could not prepare the ADC clock.\n"); + goto error_free_adc_clk; + } + + ret = clk_enable(st->adc_clk); + if (ret) { + dev_err(&pdev->dev, "Could not enable the ADC clock.\n"); + goto error_unprepare_adc_clk; + } + + /* + * Prescaler rate computation using the formula from the Atmel's + * datasheet : ADC Clock = MCK / ((Prescaler + 1) * 2), ADC Clock being + * specified by the electrical characteristics of the board. + */ + mstrclk = clk_get_rate(st->clk); + adc_clk = clk_get_rate(st->adc_clk); + prsc = (mstrclk / (2 * adc_clk)) - 1; + + if (!st->startup_time) { + dev_err(&pdev->dev, "No startup time available.\n"); + ret = -EINVAL; + goto error_disable_adc_clk; + } + + /* + * Number of ticks needed to cover the startup time of the ADC as + * defined in the electrical characteristics of the board, divided by 8. + * The formula thus is : Startup Time = (ticks + 1) * 8 / ADC Clock + */ + ticks = round_up((st->startup_time * adc_clk / + 1000000) - 1, 8) / 8; + at91_adc_writel(st, AT91_ADC_MR, + (AT91_ADC_PRESCAL_(prsc) & AT91_ADC_PRESCAL) | + (AT91_ADC_STARTUP_(ticks) & AT91_ADC_STARTUP)); + + /* Setup the ADC channels available on the board */ + ret = at91_adc_channel_init(idev); + if (ret < 0) { + dev_err(&pdev->dev, "Couldn't initialize the channels.\n"); + goto error_disable_adc_clk; + } + + init_waitqueue_head(&st->wq_data_avail); + mutex_init(&st->lock); + + ret = at91_adc_buffer_init(idev); + if (ret < 0) { + dev_err(&pdev->dev, "Couldn't initialize the buffer.\n"); + goto error_disable_adc_clk; + } + + ret = at91_adc_trigger_init(idev); + if (ret < 0) { + dev_err(&pdev->dev, "Couldn't setup the triggers.\n"); + goto error_unregister_buffer; + } + + ret = iio_device_register(idev); + if (ret < 0) { + dev_err(&pdev->dev, "Couldn't register the device.\n"); + goto error_remove_triggers; + } + + return 0; + +error_remove_triggers: + at91_adc_trigger_remove(idev); +error_unregister_buffer: + at91_adc_buffer_remove(idev); +error_disable_adc_clk: + clk_disable(st->adc_clk); +error_unprepare_adc_clk: + clk_unprepare(st->adc_clk); +error_free_adc_clk: + clk_put(st->adc_clk); +error_disable_clk: + clk_disable(st->clk); +error_unprepare_clk: + clk_unprepare(st->clk); +error_free_clk: + clk_put(st->clk); +error_free_irq: + free_irq(st->irq, idev); +error_unmap_reg: + iounmap(st->reg_base); +error_release_mem: + release_mem_region(res->start, resource_size(res)); +error_free_device: + iio_device_free(idev); +error_ret: + return ret; +} + +static int __devexit at91_adc_remove(struct platform_device *pdev) +{ + struct iio_dev *idev = platform_get_drvdata(pdev); + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + struct at91_adc_state *st = iio_priv(idev); + + iio_device_unregister(idev); + at91_adc_trigger_remove(idev); + at91_adc_buffer_remove(idev); + clk_disable_unprepare(st->adc_clk); + clk_put(st->adc_clk); + clk_disable(st->clk); + clk_unprepare(st->clk); + clk_put(st->clk); + free_irq(st->irq, idev); + iounmap(st->reg_base); + release_mem_region(res->start, resource_size(res)); + iio_device_free(idev); + + return 0; +} + +static struct platform_driver at91_adc_driver = { + .probe = at91_adc_probe, + .remove = __devexit_p(at91_adc_remove), + .driver = { + .name = "at91_adc", + }, +}; + +module_platform_driver(at91_adc_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Atmel AT91 ADC Driver"); +MODULE_AUTHOR("Maxime Ripard "); -- cgit v0.10.2 From 67b5d7b3e2ce01c091c8adb120b9fffcb2dddc0a Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Fri, 11 May 2012 15:35:34 +0200 Subject: ARM: AT91: Add the ADC to the sam9g20ek board This patch adds platform data for the AT91 ADC driver support for the AT91SAM9G20-EK board. Signed-off-by: Maxime Ripard Acked-by: Nicolas Ferre Acked-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index 46f7742..63d4432 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -55,6 +55,13 @@ static struct clk adc_clk = { .pmc_mask = 1 << AT91SAM9260_ID_ADC, .type = CLK_TYPE_PERIPHERAL, }; + +static struct clk adc_op_clk = { + .name = "adc_op_clk", + .type = CLK_TYPE_PERIPHERAL, + .rate_hz = 5000000, +}; + static struct clk usart0_clk = { .name = "usart0_clk", .pmc_mask = 1 << AT91SAM9260_ID_US0, @@ -166,6 +173,7 @@ static struct clk *periph_clocks[] __initdata = { &pioB_clk, &pioC_clk, &adc_clk, + &adc_op_clk, &usart0_clk, &usart1_clk, &usart2_clk, diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 5652dde..be0eb26 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -17,12 +17,15 @@ #include #include +#include + #include #include #include #include #include #include +#include #include "generic.h" @@ -1369,6 +1372,93 @@ void __init at91_add_device_cf(struct at91_cf_data *data) void __init at91_add_device_cf(struct at91_cf_data * data) {} #endif +/* -------------------------------------------------------------------- + * ADCs + * -------------------------------------------------------------------- */ + +#if IS_ENABLED(CONFIG_AT91_ADC) +static struct at91_adc_data adc_data; + +static struct resource adc_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_ADC, + .end = AT91SAM9260_BASE_ADC + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_ADC, + .end = AT91SAM9260_ID_ADC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91_adc_device = { + .name = "at91_adc", + .id = -1, + .dev = { + .platform_data = &adc_data, + }, + .resource = adc_resources, + .num_resources = ARRAY_SIZE(adc_resources), +}; + +static struct at91_adc_trigger at91_adc_triggers[] = { + [0] = { + .name = "timer-counter-0", + .value = AT91_ADC_TRGSEL_TC0 | AT91_ADC_TRGEN, + }, + [1] = { + .name = "timer-counter-1", + .value = AT91_ADC_TRGSEL_TC1 | AT91_ADC_TRGEN, + }, + [2] = { + .name = "timer-counter-2", + .value = AT91_ADC_TRGSEL_TC2 | AT91_ADC_TRGEN, + }, + [3] = { + .name = "external", + .value = AT91_ADC_TRGSEL_EXTERNAL | AT91_ADC_TRGEN, + .is_external = true, + }, +}; + +static struct at91_adc_reg_desc at91_adc_register_g20 = { + .channel_base = AT91_ADC_CHR(0), + .drdy_mask = AT91_ADC_DRDY, + .status_register = AT91_ADC_SR, + .trigger_register = AT91_ADC_MR, +}; + +void __init at91_add_device_adc(struct at91_adc_data *data) +{ + if (!data) + return; + + if (test_bit(0, &data->channels_used)) + at91_set_A_periph(AT91_PIN_PC0, 0); + if (test_bit(1, &data->channels_used)) + at91_set_A_periph(AT91_PIN_PC1, 0); + if (test_bit(2, &data->channels_used)) + at91_set_A_periph(AT91_PIN_PC2, 0); + if (test_bit(3, &data->channels_used)) + at91_set_A_periph(AT91_PIN_PC3, 0); + + if (data->use_external_triggers) + at91_set_A_periph(AT91_PIN_PA22, 0); + + data->num_channels = 4; + data->startup_time = 10; + data->registers = &at91_adc_register_g20; + data->trigger_number = 4; + data->trigger_list = at91_adc_triggers; + + adc_data = *data; + platform_device_register(&at91_adc_device); +} +#else +void __init at91_add_device_adc(struct at91_adc_data *data) {} +#endif + /* -------------------------------------------------------------------- */ /* * These devices are always present and don't need any board-specific diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c index 8923ec9..291b0fe 100644 --- a/arch/arm/mach-at91/board-sam9g20ek.c +++ b/arch/arm/mach-at91/board-sam9g20ek.c @@ -32,6 +32,8 @@ #include #include +#include + #include #include #include @@ -318,6 +320,16 @@ static void __init ek_add_device_buttons(void) static void __init ek_add_device_buttons(void) {} #endif +/* + * ADCs + */ + +static struct at91_adc_data ek_adc_data = { + .channels_used = BIT(0) | BIT(1) | BIT(2) | BIT(3), + .use_external_triggers = true, + .vref = 3300, +}; + #if defined(CONFIG_REGULATOR_FIXED_VOLTAGE) || defined(CONFIG_REGULATOR_FIXED_VOLTAGE_MODULE) static struct regulator_consumer_supply ek_audio_consumer_supplies[] = { REGULATOR_SUPPLY("AVDD", "0-001b"), @@ -393,6 +405,8 @@ static void __init ek_board_init(void) ek_add_device_gpio_leds(); /* Push Buttons */ ek_add_device_buttons(); + /* ADCs */ + at91_add_device_adc(&ek_adc_data); /* PCK0 provides MCLK to the WM8731 */ at91_set_B_periph(AT91_PIN_PC1, 0); /* SSC (for WM8731) */ -- cgit v0.10.2 From 4a5920e848173dafd3907c8789fdb6ec89d0d621 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Fri, 11 May 2012 15:35:35 +0200 Subject: ARM: AT91: ADC: Add support for the AT91SAM9M10G45-EK board This patch adds platform data for the AT91 ADC driver support for the AT91SAM9M10G45-EK board. Signed-off-by: Maxime Ripard Acked-by: Nicolas Ferre Acked-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index d222f83..30865c6 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -176,6 +176,12 @@ static struct clk vdec_clk = { .type = CLK_TYPE_PERIPHERAL, }; +static struct clk adc_op_clk = { + .name = "adc_op_clk", + .type = CLK_TYPE_PERIPHERAL, + .rate_hz = 13200000, +}; + static struct clk *periph_clocks[] __initdata = { &pioA_clk, &pioB_clk, @@ -204,6 +210,7 @@ static struct clk *periph_clocks[] __initdata = { &isi_clk, &udphs_clk, &mmc1_clk, + &adc_op_clk, // irq0 }; @@ -242,6 +249,8 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_ID("pioC", &pioC_clk), CLKDEV_CON_ID("pioD", &pioDE_clk), CLKDEV_CON_ID("pioE", &pioDE_clk), + /* Fake adc clock */ + CLKDEV_CON_ID("adc_clk", &tsc_clk), }; static struct clk_lookup usart_clocks_lookups[] = { diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 6b008ae..0c6d9fe 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -19,9 +19,12 @@ #include #include +#include + #include #include