2019-05-27 09:55:01 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2010-04-30 17:21:27 +04:00
/*
* MPC512x PSC in SPI mode driver .
*
* Copyright ( C ) 2007 , 2008 Freescale Semiconductor Inc .
* Original port from 52 xx driver :
* Hongjun Chen < hong - jun . chen @ freescale . com >
*
* Fork of mpc52xx_psc_spi . c :
* Copyright ( C ) 2006 TOPTICA Photonics AG . , Dragos Carp
*/
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/errno.h>
# include <linux/interrupt.h>
# include <linux/completion.h>
# include <linux/io.h>
2023-02-17 23:45:42 +03:00
# include <linux/platform_device.h>
2023-03-06 21:31:14 +03:00
# include <linux/property.h>
2010-04-30 17:21:27 +04:00
# include <linux/delay.h>
# include <linux/clk.h>
# include <linux/spi/spi.h>
# include <asm/mpc52xx_psc.h>
2015-07-14 12:19:56 +03:00
enum {
TYPE_MPC5121 ,
TYPE_MPC5125 ,
} ;
/*
* This macro abstracts the differences in the PSC register layout between
* MPC5121 ( which uses a struct mpc52xx_psc ) and MPC5125 ( using mpc5125_psc ) .
*/
# define psc_addr(mps, regname) ({ \
2015-07-21 11:30:42 +03:00
void * __ret = NULL ; \
switch ( mps - > type ) { \
2015-07-14 12:19:56 +03:00
case TYPE_MPC5121 : { \
struct mpc52xx_psc __iomem * psc = mps - > psc ; \
__ret = & psc - > regname ; \
} ; \
break ; \
case TYPE_MPC5125 : { \
struct mpc5125_psc __iomem * psc = mps - > psc ; \
__ret = & psc - > regname ; \
} ; \
break ; \
} \
__ret ; } )
2010-04-30 17:21:27 +04:00
struct mpc512x_psc_spi {
/* driver internal data */
2015-07-14 12:19:56 +03:00
int type ;
void __iomem * psc ;
2010-04-30 17:21:27 +04:00
struct mpc512x_psc_fifo __iomem * fifo ;
2023-08-03 16:48:05 +03:00
int irq ;
2010-04-30 17:21:27 +04:00
u8 bits_per_word ;
2013-08-07 00:43:41 +04:00
u32 mclk_rate ;
2010-04-30 17:21:27 +04:00
2013-06-03 16:03:49 +04:00
struct completion txisrdone ;
2010-04-30 17:21:27 +04:00
} ;
/* controller state */
struct mpc512x_psc_spi_cs {
int bits_per_word ;
int speed_hz ;
} ;
/* set clock freq, clock ramp, bits per work
* if t is NULL then reset the values to the default values
*/
static int mpc512x_psc_spi_transfer_setup ( struct spi_device * spi ,
struct spi_transfer * t )
{
struct mpc512x_psc_spi_cs * cs = spi - > controller_state ;
cs - > speed_hz = ( t & & t - > speed_hz )
? t - > speed_hz : spi - > max_speed_hz ;
cs - > bits_per_word = ( t & & t - > bits_per_word )
? t - > bits_per_word : spi - > bits_per_word ;
cs - > bits_per_word = ( ( cs - > bits_per_word + 7 ) / 8 ) * 8 ;
return 0 ;
}
static void mpc512x_psc_spi_activate_cs ( struct spi_device * spi )
{
struct mpc512x_psc_spi_cs * cs = spi - > controller_state ;
2023-08-23 06:29:49 +03:00
struct mpc512x_psc_spi * mps = spi_controller_get_devdata ( spi - > controller ) ;
2010-04-30 17:21:27 +04:00
u32 sicr ;
u32 ccr ;
2013-08-07 00:43:41 +04:00
int speed ;
2010-04-30 17:21:27 +04:00
u16 bclkdiv ;
2015-07-14 12:19:56 +03:00
sicr = in_be32 ( psc_addr ( mps , sicr ) ) ;
2010-04-30 17:21:27 +04:00
/* Set clock phase and polarity */
if ( spi - > mode & SPI_CPHA )
sicr | = 0x00001000 ;
else
sicr & = ~ 0x00001000 ;
if ( spi - > mode & SPI_CPOL )
sicr | = 0x00002000 ;
else
sicr & = ~ 0x00002000 ;
if ( spi - > mode & SPI_LSB_FIRST )
sicr | = 0x10000000 ;
else
sicr & = ~ 0x10000000 ;
2015-07-14 12:19:56 +03:00
out_be32 ( psc_addr ( mps , sicr ) , sicr ) ;
2010-04-30 17:21:27 +04:00
2015-07-14 12:19:56 +03:00
ccr = in_be32 ( psc_addr ( mps , ccr ) ) ;
2010-04-30 17:21:27 +04:00
ccr & = 0xFF000000 ;
2013-08-07 00:43:41 +04:00
speed = cs - > speed_hz ;
if ( ! speed )
speed = 1000000 ; /* default 1MHz */
bclkdiv = ( mps - > mclk_rate / speed ) - 1 ;
2010-04-30 17:21:27 +04:00
ccr | = ( ( ( bclkdiv & 0xff ) < < 16 ) | ( ( ( bclkdiv > > 8 ) & 0xff ) < < 8 ) ) ;
2015-07-14 12:19:56 +03:00
out_be32 ( psc_addr ( mps , ccr ) , ccr ) ;
2010-04-30 17:21:27 +04:00
mps - > bits_per_word = cs - > bits_per_word ;
2023-03-10 20:32:03 +03:00
if ( spi_get_csgpiod ( spi , 0 ) ) {
2023-02-17 23:45:40 +03:00
/* gpiolib will deal with the inversion */
2023-03-10 20:32:03 +03:00
gpiod_set_value ( spi_get_csgpiod ( spi , 0 ) , 1 ) ;
2022-01-20 03:26:00 +03:00
}
2010-04-30 17:21:27 +04:00
}
static void mpc512x_psc_spi_deactivate_cs ( struct spi_device * spi )
{
2023-03-10 20:32:03 +03:00
if ( spi_get_csgpiod ( spi , 0 ) ) {
2023-02-17 23:45:40 +03:00
/* gpiolib will deal with the inversion */
2023-03-10 20:32:03 +03:00
gpiod_set_value ( spi_get_csgpiod ( spi , 0 ) , 0 ) ;
2022-01-20 03:26:00 +03:00
}
2010-04-30 17:21:27 +04:00
}
/* extract and scale size field in txsz or rxsz */
# define MPC512x_PSC_FIFO_SZ(sz) ((sz & 0x7ff) << 2);
# define EOFBYTE 1
static int mpc512x_psc_spi_transfer_rxtx ( struct spi_device * spi ,
struct spi_transfer * t )
{
2023-08-23 06:29:49 +03:00
struct mpc512x_psc_spi * mps = spi_controller_get_devdata ( spi - > controller ) ;
2010-04-30 17:21:27 +04:00
struct mpc512x_psc_fifo __iomem * fifo = mps - > fifo ;
2013-06-03 16:03:49 +04:00
size_t tx_len = t - > len ;
2013-06-03 16:03:50 +04:00
size_t rx_len = t - > len ;
2010-04-30 17:21:27 +04:00
u8 * tx_buf = ( u8 * ) t - > tx_buf ;
u8 * rx_buf = ( u8 * ) t - > rx_buf ;
if ( ! tx_buf & & ! rx_buf & & t - > len )
return - EINVAL ;
2013-06-03 16:03:50 +04:00
while ( rx_len | | tx_len ) {
2013-06-03 16:03:49 +04:00
size_t txcount ;
2010-04-30 17:21:27 +04:00
u8 data ;
size_t fifosz ;
2013-06-03 16:03:49 +04:00
size_t rxcount ;
2013-06-03 16:03:50 +04:00
int rxtries ;
2010-04-30 17:21:27 +04:00
/*
2013-06-03 16:03:50 +04:00
* send the TX bytes in as large a chunk as possible
* but neither exceed the TX nor the RX FIFOs
2010-04-30 17:21:27 +04:00
*/
fifosz = MPC512x_PSC_FIFO_SZ ( in_be32 ( & fifo - > txsz ) ) ;
2013-06-03 16:03:49 +04:00
txcount = min ( fifosz , tx_len ) ;
2013-06-03 16:03:50 +04:00
fifosz = MPC512x_PSC_FIFO_SZ ( in_be32 ( & fifo - > rxsz ) ) ;
fifosz - = in_be32 ( & fifo - > rxcnt ) + 1 ;
txcount = min ( fifosz , txcount ) ;
if ( txcount ) {
/* fill the TX FIFO */
while ( txcount - - > 0 ) {
data = tx_buf ? * tx_buf + + : 0 ;
if ( tx_len = = EOFBYTE & & t - > cs_change )
setbits32 ( & fifo - > txcmd ,
MPC512x_PSC_FIFO_EOF ) ;
out_8 ( & fifo - > txdata_8 , data ) ;
tx_len - - ;
}
2010-04-30 17:21:27 +04:00
2013-06-03 16:03:50 +04:00
/* have the ISR trigger when the TX FIFO is empty */
2013-11-15 02:32:02 +04:00
reinit_completion ( & mps - > txisrdone ) ;
2013-06-03 16:03:50 +04:00
out_be32 ( & fifo - > txisr , MPC512x_PSC_FIFO_EMPTY ) ;
out_be32 ( & fifo - > tximr , MPC512x_PSC_FIFO_EMPTY ) ;
wait_for_completion ( & mps - > txisrdone ) ;
2010-04-30 17:21:27 +04:00
}
2013-06-03 16:03:50 +04:00
/*
* consume as much RX data as the FIFO holds , while we
* iterate over the transfer ' s TX data length
*
* only insist in draining all the remaining RX bytes
* when the TX bytes were exhausted ( that ' s at the very
* end of this transfer , not when still iterating over
* the transfer ' s chunks )
*/
rxtries = 50 ;
do {
/*
* grab whatever was in the FIFO when we started
* looking , don ' t bother fetching what was added to
* the FIFO while we read from it - - we ' ll return
* here eventually and prefer sending out remaining
* TX data
*/
fifosz = in_be32 ( & fifo - > rxcnt ) ;
rxcount = min ( fifosz , rx_len ) ;
while ( rxcount - - > 0 ) {
data = in_8 ( & fifo - > rxdata_8 ) ;
if ( rx_buf )
* rx_buf + + = data ;
rx_len - - ;
}
2010-04-30 17:21:27 +04:00
2013-06-03 16:03:50 +04:00
/*
* come back later if there still is TX data to send ,
* bail out of the RX drain loop if all of the TX data
* was sent and all of the RX data was received ( i . e .
* when the transmission has completed )
*/
if ( tx_len )
break ;
if ( ! rx_len )
break ;
/*
* TX data transmission has completed while RX data
* is still pending - - that ' s a transient situation
* which depends on wire speed and specific
* hardware implementation details ( buffering ) yet
* should resolve very quickly
*
* just yield for a moment to not hog the CPU for
* too long when running SPI at low speed
*
* the timeout range is rather arbitrary and tries
* to balance throughput against system load ; the
* chosen values result in a minimal timeout of 50
* times 10u s and thus work at speeds as low as
* some 20 kbps , while the maximum timeout at the
* transfer ' s end could be 5 ms _if_ nothing else
* ticks in the system _and_ RX data still wasn ' t
* received , which only occurs in situations that
* are exceptional ; removing the unpredictability
* of the timeout either decreases throughput
* ( longer timeouts ) , or puts more load on the
* system ( fixed short timeouts ) or requires the
* use of a timeout API instead of a counter and an
* unknown inner delay
*/
usleep_range ( 10 , 100 ) ;
} while ( - - rxtries > 0 ) ;
if ( ! tx_len & & rx_len & & ! rxtries ) {
/*
* not enough RX bytes even after several retries
* and the resulting rather long timeout ?
*/
rxcount = in_be32 ( & fifo - > rxcnt ) ;
dev_warn ( & spi - > dev ,
" short xfer, missing %zd RX bytes, FIFO level %zd \n " ,
rx_len , rxcount ) ;
2010-04-30 17:21:27 +04:00
}
2013-06-03 16:03:50 +04:00
/*
* drain and drop RX data which " should not be there " in
* the first place , for undisturbed transmission this turns
* into a NOP ( except for the FIFO level fetch )
*/
if ( ! tx_len & & ! rx_len ) {
while ( in_be32 ( & fifo - > rxcnt ) )
in_8 ( & fifo - > rxdata_8 ) ;
2010-04-30 17:21:27 +04:00
}
2013-06-03 16:03:50 +04:00
2010-04-30 17:21:27 +04:00
}
return 0 ;
}
2023-08-23 06:29:49 +03:00
static int mpc512x_psc_spi_msg_xfer ( struct spi_controller * host ,
2013-06-03 16:03:51 +04:00
struct spi_message * m )
2010-04-30 17:21:27 +04:00
{
2013-06-03 16:03:51 +04:00
struct spi_device * spi ;
unsigned cs_change ;
int status ;
struct spi_transfer * t ;
spi = m - > spi ;
cs_change = 1 ;
status = 0 ;
list_for_each_entry ( t , & m - > transfers , transfer_list ) {
2015-09-15 16:26:19 +03:00
status = mpc512x_psc_spi_transfer_setup ( spi , t ) ;
if ( status < 0 )
break ;
2010-04-30 17:21:27 +04:00
2013-06-03 16:03:51 +04:00
if ( cs_change )
mpc512x_psc_spi_activate_cs ( spi ) ;
cs_change = t - > cs_change ;
2010-04-30 17:21:27 +04:00
2013-06-03 16:03:51 +04:00
status = mpc512x_psc_spi_transfer_rxtx ( spi , t ) ;
if ( status )
break ;
m - > actual_length + = t - > len ;
2010-04-30 17:21:27 +04:00
2019-09-26 13:51:37 +03:00
spi_transfer_delay_exec ( t ) ;
2010-04-30 17:21:27 +04:00
2013-06-03 16:03:51 +04:00
if ( cs_change )
2010-04-30 17:21:27 +04:00
mpc512x_psc_spi_deactivate_cs ( spi ) ;
2013-06-03 16:03:51 +04:00
}
2010-04-30 17:21:27 +04:00
2013-06-03 16:03:51 +04:00
m - > status = status ;
2014-04-02 18:21:04 +04:00
if ( m - > complete )
m - > complete ( m - > context ) ;
2010-04-30 17:21:27 +04:00
2013-06-03 16:03:51 +04:00
if ( status | | ! cs_change )
mpc512x_psc_spi_deactivate_cs ( spi ) ;
mpc512x_psc_spi_transfer_setup ( spi , NULL ) ;
2023-08-23 06:29:49 +03:00
spi_finalize_current_message ( host ) ;
2013-06-03 16:03:51 +04:00
return status ;
}
2023-08-23 06:29:49 +03:00
static int mpc512x_psc_spi_prep_xfer_hw ( struct spi_controller * host )
2013-06-03 16:03:51 +04:00
{
2023-08-23 06:29:49 +03:00
struct mpc512x_psc_spi * mps = spi_controller_get_devdata ( host ) ;
2013-06-03 16:03:51 +04:00
2023-08-23 06:29:49 +03:00
dev_dbg ( & host - > dev , " %s() \n " , __func__ ) ;
2013-06-03 16:03:51 +04:00
/* Zero MR2 */
2015-07-14 12:19:56 +03:00
in_8 ( psc_addr ( mps , mr2 ) ) ;
out_8 ( psc_addr ( mps , mr2 ) , 0x0 ) ;
2013-06-03 16:03:51 +04:00
/* enable transmitter/receiver */
2015-07-14 12:19:56 +03:00
out_8 ( psc_addr ( mps , command ) , MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE ) ;
2013-06-03 16:03:51 +04:00
return 0 ;
}
2023-08-23 06:29:49 +03:00
static int mpc512x_psc_spi_unprep_xfer_hw ( struct spi_controller * host )
2013-06-03 16:03:51 +04:00
{
2023-08-23 06:29:49 +03:00
struct mpc512x_psc_spi * mps = spi_controller_get_devdata ( host ) ;
2013-06-03 16:03:51 +04:00
struct mpc512x_psc_fifo __iomem * fifo = mps - > fifo ;
2023-08-23 06:29:49 +03:00
dev_dbg ( & host - > dev , " %s() \n " , __func__ ) ;
2013-06-03 16:03:51 +04:00
/* disable transmitter/receiver and fifo interrupt */
2015-07-14 12:19:56 +03:00
out_8 ( psc_addr ( mps , command ) , MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE ) ;
2013-06-03 16:03:51 +04:00
out_be32 ( & fifo - > tximr , 0 ) ;
return 0 ;
2010-04-30 17:21:27 +04:00
}
static int mpc512x_psc_spi_setup ( struct spi_device * spi )
{
struct mpc512x_psc_spi_cs * cs = spi - > controller_state ;
if ( spi - > bits_per_word % 8 )
return - EINVAL ;
if ( ! cs ) {
2021-05-18 04:38:17 +03:00
cs = kzalloc ( sizeof ( * cs ) , GFP_KERNEL ) ;
2010-04-30 17:21:27 +04:00
if ( ! cs )
return - ENOMEM ;
2013-04-01 19:29:21 +04:00
2010-04-30 17:21:27 +04:00
spi - > controller_state = cs ;
}
cs - > bits_per_word = spi - > bits_per_word ;
cs - > speed_hz = spi - > max_speed_hz ;
return 0 ;
}
static void mpc512x_psc_spi_cleanup ( struct spi_device * spi )
{
kfree ( spi - > controller_state ) ;
}
2023-08-23 06:29:49 +03:00
static int mpc512x_psc_spi_port_config ( struct spi_controller * host ,
2010-04-30 17:21:27 +04:00
struct mpc512x_psc_spi * mps )
{
struct mpc512x_psc_fifo __iomem * fifo = mps - > fifo ;
u32 sicr ;
u32 ccr ;
2013-08-07 00:43:41 +04:00
int speed ;
2010-04-30 17:21:27 +04:00
u16 bclkdiv ;
/* Reset the PSC into a known state */
2015-07-14 12:19:56 +03:00
out_8 ( psc_addr ( mps , command ) , MPC52xx_PSC_RST_RX ) ;
out_8 ( psc_addr ( mps , command ) , MPC52xx_PSC_RST_TX ) ;
out_8 ( psc_addr ( mps , command ) , MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE ) ;
2010-04-30 17:21:27 +04:00
/* Disable psc interrupts all useful interrupts are in fifo */
2015-07-14 12:19:56 +03:00
out_be16 ( psc_addr ( mps , isr_imr . imr ) , 0 ) ;
2010-04-30 17:21:27 +04:00
/* Disable fifo interrupts, will be enabled later */
out_be32 ( & fifo - > tximr , 0 ) ;
out_be32 ( & fifo - > rximr , 0 ) ;
/* Setup fifo slice address and size */
/*out_be32(&fifo->txsz, 0x0fe00004);*/
/*out_be32(&fifo->rxsz, 0x0ff00004);*/
sicr = 0x01000000 | /* SIM = 0001 -- 8 bit */
0x00800000 | /* GenClk = 1 -- internal clk */
0x00008000 | /* SPI = 1 */
2023-08-23 06:29:49 +03:00
0x00004000 | /* MSTR = 1 -- SPI host */
2010-04-30 17:21:27 +04:00
0x00000800 ; /* UseEOF = 1 -- SS low until EOF */
2015-07-14 12:19:56 +03:00
out_be32 ( psc_addr ( mps , sicr ) , sicr ) ;
2010-04-30 17:21:27 +04:00
2015-07-14 12:19:56 +03:00
ccr = in_be32 ( psc_addr ( mps , ccr ) ) ;
2010-04-30 17:21:27 +04:00
ccr & = 0xFF000000 ;
2013-08-07 00:43:41 +04:00
speed = 1000000 ; /* default 1MHz */
bclkdiv = ( mps - > mclk_rate / speed ) - 1 ;
2010-04-30 17:21:27 +04:00
ccr | = ( ( ( bclkdiv & 0xff ) < < 16 ) | ( ( ( bclkdiv > > 8 ) & 0xff ) < < 8 ) ) ;
2015-07-14 12:19:56 +03:00
out_be32 ( psc_addr ( mps , ccr ) , ccr ) ;
2010-04-30 17:21:27 +04:00
/* Set 2ms DTL delay */
2015-07-14 12:19:56 +03:00
out_8 ( psc_addr ( mps , ctur ) , 0x00 ) ;
out_8 ( psc_addr ( mps , ctlr ) , 0x82 ) ;
2010-04-30 17:21:27 +04:00
/* we don't use the alarms */
out_be32 ( & fifo - > rxalarm , 0xfff ) ;
out_be32 ( & fifo - > txalarm , 0 ) ;
/* Enable FIFO slices for Rx/Tx */
out_be32 ( & fifo - > rxcmd ,
MPC512x_PSC_FIFO_ENABLE_SLICE | MPC512x_PSC_FIFO_ENABLE_DMA ) ;
out_be32 ( & fifo - > txcmd ,
MPC512x_PSC_FIFO_ENABLE_SLICE | MPC512x_PSC_FIFO_ENABLE_DMA ) ;
mps - > bits_per_word = 8 ;
2013-08-07 00:43:41 +04:00
return 0 ;
2010-04-30 17:21:27 +04:00
}
static irqreturn_t mpc512x_psc_spi_isr ( int irq , void * dev_id )
{
struct mpc512x_psc_spi * mps = ( struct mpc512x_psc_spi * ) dev_id ;
struct mpc512x_psc_fifo __iomem * fifo = mps - > fifo ;
2013-06-03 16:03:51 +04:00
/* clear interrupt and wake up the rx/tx routine */
2010-04-30 17:21:27 +04:00
if ( in_be32 ( & fifo - > txisr ) &
in_be32 ( & fifo - > tximr ) & MPC512x_PSC_FIFO_EMPTY ) {
out_be32 ( & fifo - > txisr , MPC512x_PSC_FIFO_EMPTY ) ;
out_be32 ( & fifo - > tximr , 0 ) ;
2013-06-03 16:03:49 +04:00
complete ( & mps - > txisrdone ) ;
2010-04-30 17:21:27 +04:00
return IRQ_HANDLED ;
}
return IRQ_NONE ;
}
2023-02-17 23:45:42 +03:00
static int mpc512x_psc_spi_of_probe ( struct platform_device * pdev )
2010-04-30 17:21:27 +04:00
{
2023-02-17 23:45:42 +03:00
struct device * dev = & pdev - > dev ;
2010-04-30 17:21:27 +04:00
struct mpc512x_psc_spi * mps ;
2023-08-23 06:29:49 +03:00
struct spi_controller * host ;
2010-04-30 17:21:27 +04:00
int ret ;
void * tempp ;
2013-08-07 00:43:41 +04:00
struct clk * clk ;
2010-04-30 17:21:27 +04:00
2023-08-23 06:29:49 +03:00
host = devm_spi_alloc_host ( dev , sizeof ( * mps ) ) ;
if ( host = = NULL )
2010-04-30 17:21:27 +04:00
return - ENOMEM ;
2023-08-23 06:29:49 +03:00
dev_set_drvdata ( dev , host ) ;
mps = spi_controller_get_devdata ( host ) ;
2023-02-17 23:45:42 +03:00
mps - > type = ( int ) device_get_match_data ( dev ) ;
2010-04-30 17:21:27 +04:00
2023-08-23 06:29:49 +03:00
host - > mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST ;
host - > setup = mpc512x_psc_spi_setup ;
host - > prepare_transfer_hardware = mpc512x_psc_spi_prep_xfer_hw ;
host - > transfer_one_message = mpc512x_psc_spi_msg_xfer ;
host - > unprepare_transfer_hardware = mpc512x_psc_spi_unprep_xfer_hw ;
host - > use_gpio_descriptors = true ;
host - > cleanup = mpc512x_psc_spi_cleanup ;
2023-03-06 21:31:14 +03:00
2023-08-23 06:29:49 +03:00
device_set_node ( & host - > dev , dev_fwnode ( dev ) ) ;
2010-04-30 17:21:27 +04:00
2023-02-17 23:45:42 +03:00
tempp = devm_platform_get_and_ioremap_resource ( pdev , 0 , NULL ) ;
2023-03-06 21:31:11 +03:00
if ( IS_ERR ( tempp ) )
return dev_err_probe ( dev , PTR_ERR ( tempp ) , " could not ioremap I/O port range \n " ) ;
2010-04-30 17:21:27 +04:00
mps - > psc = tempp ;
mps - > fifo =
( struct mpc512x_psc_fifo * ) ( tempp + sizeof ( struct mpc52xx_psc ) ) ;
2023-02-17 23:45:42 +03:00
mps - > irq = platform_get_irq ( pdev , 0 ) ;
2023-03-06 21:31:12 +03:00
if ( mps - > irq < 0 )
return mps - > irq ;
2013-12-18 05:31:15 +04:00
ret = devm_request_irq ( dev , mps - > irq , mpc512x_psc_spi_isr , IRQF_SHARED ,
" mpc512x-psc-spi " , mps ) ;
2010-04-30 17:21:27 +04:00
if ( ret )
2023-02-17 23:45:41 +03:00
return ret ;
2013-06-03 16:03:51 +04:00
init_completion ( & mps - > txisrdone ) ;
2010-04-30 17:21:27 +04:00
2023-03-06 21:31:13 +03:00
clk = devm_clk_get_enabled ( dev , " mclk " ) ;
2023-02-17 23:45:41 +03:00
if ( IS_ERR ( clk ) )
return PTR_ERR ( clk ) ;
2013-08-07 00:43:41 +04:00
mps - > mclk_rate = clk_get_rate ( clk ) ;
2023-03-06 21:31:13 +03:00
clk = devm_clk_get_enabled ( dev , " ipg " ) ;
if ( IS_ERR ( clk ) )
return PTR_ERR ( clk ) ;
2013-12-01 02:51:28 +04:00
2023-08-23 06:29:49 +03:00
ret = mpc512x_psc_spi_port_config ( host , mps ) ;
2010-04-30 17:21:27 +04:00
if ( ret < 0 )
2023-03-10 14:15:44 +03:00
return ret ;
2010-04-30 17:21:27 +04:00
2023-08-23 06:29:49 +03:00
return devm_spi_register_controller ( dev , host ) ;
2010-04-30 17:21:27 +04:00
}
2015-03-16 22:20:31 +03:00
static const struct of_device_id mpc512x_psc_spi_of_match [ ] = {
2015-07-14 12:19:56 +03:00
{ . compatible = " fsl,mpc5121-psc-spi " , . data = ( void * ) TYPE_MPC5121 } ,
{ . compatible = " fsl,mpc5125-psc-spi " , . data = ( void * ) TYPE_MPC5125 } ,
2010-04-30 17:21:27 +04:00
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , mpc512x_psc_spi_of_match ) ;
2011-02-23 07:02:43 +03:00
static struct platform_driver mpc512x_psc_spi_of_driver = {
2010-04-30 17:21:27 +04:00
. probe = mpc512x_psc_spi_of_probe ,
. driver = {
. name = " mpc512x-psc-spi " ,
2010-05-31 20:34:54 +04:00
. of_match_table = mpc512x_psc_spi_of_match ,
2010-04-30 17:21:27 +04:00
} ,
} ;
2011-10-05 21:29:49 +04:00
module_platform_driver ( mpc512x_psc_spi_of_driver ) ;
2010-04-30 17:21:27 +04:00
MODULE_AUTHOR ( " John Rigby " ) ;
MODULE_DESCRIPTION ( " MPC512x PSC SPI Driver " ) ;
MODULE_LICENSE ( " GPL " ) ;