From: Sreedhara DS <[email protected]>
PATCH RESEND 1/1 From: Sreedhara DS <[email protected]>
intel_scu_ipc: Resync with development branch
- Add support for Medfield (different message format)
- Use the mrst_platform_id to autodetect the correct type of message
- delete unused interfaces
- fix reversing of command/sub argments in simple_command
- fix a crash if the i2c interface is called before the device is found
- new PCI identifier
---
drivers/platform/x86/intel_scu_ipc.c | 164 ++++++++++------------------------ 1 files changed, 47 insertions(+), 117 deletions(-)
drivers/platform/x86/intel_scu_ipc.c +47 -117
@@ -23,7 +23,8 @@#include <linux/pm.h> #include <linux/pci.h> #include <linux/interrupt.h> -#include <asm/setup.h> +#include <linux/sfi.h> +#include <asm/mrst.h> #include <asm/intel_scu_ipc.h> /* IPC defines the following message types */
@@ -38,10 +39,6 @@#define IPC_CMD_PCNTRL_R 1/* Register read */ #define IPC_CMD_PCNTRL_M 2/* Register read-modify-write */ -/* Miscelaneous Command ids */ -#define IPC_CMD_INDIRECT_RD 2/* 32bit indirect read */ -#define IPC_CMD_INDIRECT_WR 5/* 32bit indirect write */ -/* * IPC register summary *
@@ -78,12 +75,7 @@ struct intel_scu_ipc_dev {static struct intel_scu_ipc_dev ipcdev;/* Only one for now */ -static int platform =1 ; -module_param (platform, int,0 ); -MODULE_PARM_DESC (platform,"1 for moorestown platform" ); - - - +static int platform;/* Platform type */ /* * IPC Read Buffer (Read Only):
@@ -119,24 +111,6 @@ static inline void ipc_data_writel(u32 data, u32 offset) /* Write ipc data */ }/* -* IPC destination Pointer (Write Only): -* Use content as pointer for destination write -*/ -static inline void ipc_write_dptr (u32 data)/* Write dptr data */ -{ -writel (data, ipcdev.ipc_base +0x0C ); -} - -/* -* IPC Source Pointer (Write Only): -* Use content as pointer for read location -*/ -static inline void ipc_write_sptr (u32 data)/* Write dptr data */ -{ -writel (data, ipcdev.ipc_base +0x08 ); -} - -/* * Status Register (Read Only): * Driver will read this register to get the ready/busy status of the IPC * block and error status of the IPC command that was just processed by SCU
@@ -154,7 +128,7 @@ static inline u8 ipc_data_readb(u32 offset) /* Read ipc byte data */return readb (ipcdev.ipc_base +IPC_READ_BUFFER + offset); } -static inline u8 ipc_data_readl (u32 offset)/* Read ipc u32 data */ +static inline u32 ipc_data_readl (u32 offset)/* Read ipc u32 data */ {return readl (ipcdev.ipc_base +IPC_READ_BUFFER + offset); }
@@ -184,18 +158,19 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)int nc;u32 offset =0 ;u32 err =0 ; -u8 cbuf[IPC_WWBUF_SIZE ] = {'\0' }; +u8 cbuf[IPC_WWBUF_SIZE ] = { };u32 *wbuf = (u32 *)&cbuf;mutex_lock (&ipclock); +if (ipcdev.pdev ==NULL ) {mutex_unlock (&ipclock);return -ENODEV ; } -if (platform ==1 ) { +if (platform !=MRST_CPU_CHIP_PENWELL ) {/* Entry is 4 bytes for read/write, 5 bytes for read modify */ -for (nc =0 ; nc < count; nc++) { +for (nc =0 ; nc < count; nc++, offset +=3 ) { cbuf[offset] = addr[nc]; cbuf[offset +1 ] = addr[nc] >>8 ;if (id !=IPC_CMD_PCNTRL_R )
@@ -204,33 +179,44 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id) cbuf[offset +3 ] = data[nc +1 ]; offset +=1 ; } - offset +=3 ; }for (nc =0 , offset =0 ; nc < count; nc++, offset +=4 )ipc_data_writel (wbuf[nc], offset);/* Write wbuff */ +if (id !=IPC_CMD_PCNTRL_M ) +ipc_command ((count*4 ) <<16 | id <<12 |0 <<8 | op); +else +ipc_command ((count*5 ) <<16 | id <<12 |0 <<8 | op); + }else { -for (nc =0 , offset =0 ; nc < count; nc++, offset +=2 ) -ipc_data_writel (addr[nc], offset);/* Write addresses */ -if (id !=IPC_CMD_PCNTRL_R ) { -for (nc =0 ; nc < count; nc++, offset++) -ipc_data_writel (data[nc], offset);/* Write data */ -if (id ==IPC_CMD_PCNTRL_M ) -ipc_data_writel (data[nc +1 ], offset);/* Mask value*/ +for (nc =0 ; nc < count; nc++, offset +=2 ) { + cbuf[offset] = addr[nc]; + cbuf[offset +1 ] = addr[nc] >>8 ; } - } -if (id !=IPC_CMD_PCNTRL_M ) -ipc_command ((count *3 ) <<16 | id <<12 |0 <<8 | op); -else -ipc_command ((count *4 ) <<16 | id <<12 |0 <<8 | op); +if (id ==IPC_CMD_PCNTRL_R ) { +for (nc =0 , offset =0 ; nc < count; nc++, offset +=4 ) +ipc_data_writel (wbuf[nc], offset); +ipc_command ((count*2 ) <<16 | id <<12 |0 <<8 | op); + }else if (id ==IPC_CMD_PCNTRL_W ) { +for (nc =0 ; nc < count; nc++, offset +=1 ) + cbuf[offset] = data[nc]; +for (nc =0 , offset =0 ; nc < count; nc++, offset +=4 ) +ipc_data_writel (wbuf[nc], offset); +ipc_command ((count*3 ) <<16 | id <<12 |0 <<8 | op); + }else if (id ==IPC_CMD_PCNTRL_M ) { + cbuf[offset] = data[0 ]; + cbuf[offset +1 ] = data[1 ]; +ipc_data_writel (wbuf[0 ],0 );/* Write wbuff */ +ipc_command (4 <<16 | id <<12 |0 <<8 | op); + } + } err =busy_loop (); -if (id ==IPC_CMD_PCNTRL_R ) {/* Read rbuf */ /* Workaround: values are read as 0 without memcpy_fromio */ -memcpy_fromio (cbuf, ipcdev.ipc_base +IPC_READ_BUFFER ,16 ); -if (platform ==1 ) { +memcpy_fromio (cbuf, ipcdev.ipc_base +0x90 ,16 ); +if (platform !=MRST_CPU_CHIP_PENWELL ) {for (nc =0 , offset =2 ; nc < count; nc++, offset +=3 ) data[nc] =ipc_data_readb (offset); }else {
@@ -405,70 +391,6 @@ int intel_scu_ipc_update_register(u16 addr, u8 bits, u8 mask)EXPORT_SYMBOL (intel_scu_ipc_update_register);/** -* intel_scu_ipc_register_read - 32bit indirect read -* @addr: register address -* @value: 32bit value return -* -* Performs IA 32 bit indirect read, returns 0 on success, or an -* error code. -* -* Can be used when SCCB(System Controller Configuration Block) register -* HRIM(Honor Restricted IPC Messages) is set (bit 23) -* -* This function may sleep. Locking for SCU accesses is handled for -* the caller. -*/ -int intel_scu_ipc_register_read (u32 addr,u32 *value) -{ -u32 err =0 ; - -mutex_lock (&ipclock); -if (ipcdev.pdev ==NULL ) { -mutex_unlock (&ipclock); -return -ENODEV ; - } -ipc_write_sptr (addr); -ipc_command (4 <<16 |IPC_CMD_INDIRECT_RD ); - err =busy_loop (); - *value =ipc_data_readl (0 ); -mutex_unlock (&ipclock); -return err; -} -EXPORT_SYMBOL (intel_scu_ipc_register_read); - -/** -* intel_scu_ipc_register_write - 32bit indirect write -* @addr: register address -* @value: 32bit value to write -* -* Performs IA 32 bit indirect write, returns 0 on success, or an -* error code. -* -* Can be used when SCCB(System Controller Configuration Block) register -* HRIM(Honor Restricted IPC Messages) is set (bit 23) -* -* This function may sleep. Locking for SCU accesses is handled for -* the caller. -*/ -int intel_scu_ipc_register_write (u32 addr,u32 value) -{ -u32 err =0 ; - -mutex_lock (&ipclock); -if (ipcdev.pdev ==NULL ) { -mutex_unlock (&ipclock); -return -ENODEV ; - } -ipc_write_dptr (addr); -ipc_data_writel (value,0 ); -ipc_command (4 <<16 |IPC_CMD_INDIRECT_WR ); - err =busy_loop (); -mutex_unlock (&ipclock); -return err; -} -EXPORT_SYMBOL (intel_scu_ipc_register_write); - -/** * intel_scu_ipc_simple_command - send a simple command * @cmd: command * @sub: sub type
@@ -489,7 +411,7 @@ int intel_scu_ipc_simple_command(int cmd, int sub)mutex_unlock (&ipclock);return -ENODEV ; } -ipc_command (cmd <<12 | sub); +ipc_command (sub <<12 | cmd); err =busy_loop ();mutex_unlock (&ipclock);return err;
@@ -501,9 +423,9 @@ EXPORT_SYMBOL(intel_scu_ipc_simple_command);* @cmd: command * @sub: sub type * @in: input data -* @inlen: input length +* @inlen: input length in dwords * @out: output data -* @outlein: output length +* @outlein: output length in dwords * * Issue a command to the SCU which involves data transfers. Do the * data copies under the lock but leave it for the caller to interpret
@@ -524,7 +446,7 @@ int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,for (i =0 ; i < inlen; i++)ipc_data_writel (*in++,4 * i); -ipc_command ((cmd <<12 ) | sub | (inlen <<18 )); +ipc_command ((sub <<12 ) | cmd | (inlen <<18 )); err =busy_loop ();for (i =0 ; i < outlen; i++)
@@ -556,6 +478,10 @@ int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data)u32 cmd =0 ;mutex_lock (&ipclock); +if (ipcdev.pdev ==NULL ) { +mutex_unlock (&ipclock); +return -ENODEV ; + } cmd = (addr >>24 ) &0xFF ;if (cmd ==IPC_I2C_READ ) {writel (addr, ipcdev.i2c_base +IPC_I2C_CNTRL_ADDR );
@@ -799,6 +725,7 @@ static void ipc_remove(struct pci_dev *pdev)static const struct pci_device_id pci_ids[] = { {PCI_DEVICE (PCI_VENDOR_ID_INTEL ,0x080e )}, + {PCI_DEVICE (PCI_VENDOR_ID_INTEL ,0x082a )}, {0 ,} };MODULE_DEVICE_TABLE (pci, pci_ids);
@@ -813,6 +740,9 @@ static struct pci_driver ipc_driver = {static int __init intel_scu_ipc_init (void ) { + platform =mrst_identify_cpu (); +if (platform ==0 ) +return -ENODEV ;return pci_register_driver (&ipc_driver); }
Quoted 8 lines · Alan Cox
intel_scu_ipc: Resync with development branch- Add support for Medfield (different message format)
- Use themrst_platform_idto autodetect the correct type of message
- delete unused interfaces
- fix reversing of command/sub argments insimple_command
- fix a crash if the i2c interface is called before the device is found
- new PCI identifier
This doesn't apply against the -next tree. Have I missed an intermediate patch?
Signature · 1 line
Matthew Garrett | [email protected]
Quoted 11 lines · On Thu, 22 Jul 2010 16:03:10 +0100 Matthew Garrett <[email protected]> wrote:
Quoted 9 lines · Alan Cox
intel_scu_ipc: Resync with development branch- Add support for Medfield (different message format)
- Use themrst_platform_idto autodetect the correct type of message
- delete unused interfaces
- fix reversing of command/sub argments insimple_command
- fix a crash if the i2c interface is called before the device is found
- new PCI identifier
Quoted 2 lines
This doesn't apply against the -next tree. Have I missed an intermediate patch?
I sent a couple of more urgent bits direct to Linus. I'll resync and send you the other bits.