help
Enable support for the SPI controller on the Broadcom BCM63xx SoCs.
++++++++++config SPI_BCM63XX_HSSPI
++++++++++ tristate "Broadcom BCM63XX HS SPI controller driver"
++++++++++ depends on BCM63XX || COMPILE_TEST
++++++++++ help
++++++++++ This enables support for the High Speed SPI controller present on
++++++++++ newer Broadcom BCM63XX SoCs.
++++++++++
config SPI_BITBANG
tristate "Utilities for Bitbanging SPI masters"
help
tristate "Texas Instruments DaVinci/DA8x/OMAP-L/AM1x SoC SPI controller"
depends on ARCH_DAVINCI || ARCH_KEYSTONE
select SPI_BITBANG
---------- select TI_EDMA
help
SPI master controller for DaVinci/DA8x/OMAP-L/AM1x SPI modules.
config SPI_OMAP24XX
tristate "McSPI driver for OMAP"
++++++++ ++ depends on ARM || ARM64 || AVR32 || HEXAGON || MIPS || SH
depends on ARCH_OMAP2PLUS || COMPILE_TEST
help
SPI master controller for OMAP24XX and later Multichannel SPI
config SPI_RSPI
tristate "Renesas RSPI controller"
---------- depends on (SUPERH || ARCH_SHMOBILE) && SH_DMAE_BASE
++++++++++ depends on (SUPERH && SH_DMAE_BASE) || ARCH_SHMOBILE
help
SPI driver for Renesas RSPI blocks.
config SPI_SH_MSIOF
tristate "SuperH MSIOF SPI controller"
----- ----- depends on (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
+++++ +++++ depends on HAVE_CLK
+++++ +++++ depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST
select SPI_BITBANG
help
SPI driver for SuperH and SH Mobile MSIOF blocks.
dev_info(&pdev->dev, "found PCI SPI controller(ID: %04x:%04x)\n",
pdev->vendor, pdev->device);
---------- ret = pci_enable_device(pdev);
++++++++++ ret = pcim_enable_device(pdev);
if (ret)
return ret;
---------- dwpci = kzalloc(sizeof(struct dw_spi_pci), GFP_KERNEL);
---------- if (!dwpci) {
---------- ret = -ENOMEM;
---------- goto err_disable;
---------- }
++++++++++ dwpci = devm_kzalloc(&pdev->dev, sizeof(struct dw_spi_pci),
++++++++++ GFP_KERNEL);
++++++++++ if (!dwpci)
++++++++++ return -ENOMEM;
dwpci->pdev = pdev;
dws = &dwpci->dws;
/* Get basic io resource and map it */
dws->paddr = pci_resource_start(pdev, pci_bar);
---------- dws->iolen = pci_resource_len(pdev, pci_bar);
---------- ret = pci_request_region(pdev, pci_bar, dev_name(&pdev->dev));
++++++++++ ret = pcim_iomap_regions(pdev, 1, dev_name(&pdev->dev));
if (ret)
---------- goto err_kfree;
----------
---------- dws->regs = ioremap_nocache((unsigned long)dws->paddr,
---------- pci_resource_len(pdev, pci_bar));
---------- if (!dws->regs) {
---------- ret = -ENOMEM;
---------- goto err_release_reg;
---------- }
++++++++++ return ret;
---------- dws->parent_dev = &pdev->dev;
dws->bus_num = 0;
dws->num_cs = 4;
dws->irq = pdev->irq;
if (pdev->device == 0x0800) {
ret = dw_spi_mid_init(dws);
if (ret)
---------- goto err_unmap;
++++++++++ return ret;
}
---------- ret = dw_spi_add_host(dws);
++++++++++ ret = dw_spi_add_host(&pdev->dev, dws);
if (ret)
---------- goto err_unmap;
++++++++++ return ret;
/* PCI hook and SPI hook use the same drv data */
pci_set_drvdata(pdev, dwpci);
---------- return 0;
----------err_unmap:
---------- iounmap(dws->regs);
----------err_release_reg:
---------- pci_release_region(pdev, pci_bar);
----------err_kfree:
---------- kfree(dwpci);
----------err_disable:
---------- pci_disable_device(pdev);
---------- return ret;
++++++++++ return 0;
}
static void spi_pci_remove(struct pci_dev *pdev)
struct dw_spi_pci *dwpci = pci_get_drvdata(pdev);
dw_spi_remove_host(&dwpci->dws);
---------- iounmap(dwpci->dws.regs);
---------- pci_release_region(pdev, 0);
---------- kfree(dwpci);
---------- pci_disable_device(pdev);
}
#ifdef CONFIG_PM
#define spi_resume NULL
#endif
---------- static DEFINE_PCI_DEVICE_TABLE(pci_ids) = {
++++++++++ static const struct pci_device_id pci_ids[] = {
/* Intel MID platform SPI controller 0 */
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0800) },
{},
master->cleanup = mpc512x_psc_spi_cleanup;
master->dev.of_node = dev->of_node;
---- ------ tempp = ioremap(regaddr, size);
++++ ++++++ tempp = devm_ioremap(dev, regaddr, size);
if (!tempp) {
dev_err(dev, "could not ioremap I/O port range\n");
ret = -EFAULT;
mps->psc = tempp;
mps->fifo =
(struct mpc512x_psc_fifo *)(tempp + sizeof(struct mpc52xx_psc));
---- ------
---- ------ ret = request_irq(mps->irq, mpc512x_psc_spi_isr, IRQF_SHARED,
---- ------ "mpc512x-psc-spi", mps);
++++ ++++++ ret = devm_request_irq(dev, mps->irq, mpc512x_psc_spi_isr, IRQF_SHARED,
++++ ++++++ "mpc512x-psc-spi", mps);
if (ret)
goto free_master;
init_completion(&mps->txisrdone);
clk = devm_clk_get(dev, clk_name);
if (IS_ERR(clk)) {
ret = PTR_ERR(clk);
---- ------ goto free_irq;
++++ ++++++ goto free_master;
}
ret = clk_prepare_enable(clk);
if (ret)
---- ------ goto free_irq;
++++ ++++++ goto free_master;
mps->clk_mclk = clk;
mps->mclk_rate = clk_get_rate(clk);
free_clock:
clk_disable_unprepare(mps->clk_mclk);
---- ------free_irq:
---- ------ free_irq(mps->irq, mps);
free_master:
---- ------ if (mps->psc)
---- ------ iounmap(mps->psc);
spi_master_put(master);
return ret;
static int mpc512x_psc_spi_do_remove(struct device *dev)
{
---------- struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
++++++++++ struct spi_master *master = dev_get_drvdata(dev);
struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
clk_disable_unprepare(mps->clk_mclk);
---- ------ free_irq(mps->irq, mps);
---- ------ if (mps->psc)
---- ------ iounmap(mps->psc);
return 0;
}
hspi_write(hspi, SPTBR, tx);
--- ------- /* wait recive */
+++ +++++++ /* wait receive */
ret = hspi_status_check_timeout(hspi, 0x4, 0x4);
if (ret < 0)
break;
MODULE_DESCRIPTION("SuperH HSPI bus driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
----------MODULE_ALIAS("platform:sh_spi");
++++++++++MODULE_ALIAS("platform:sh-hspi");
size_t k;
if (!WARN_ON(!spi_hz || !parent_rate))
---------- div = parent_rate / spi_hz;
++++++++++ div = DIV_ROUND_UP(parent_rate, spi_hz);
/* TODO: make more fine grained */
static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p,
u32 cpol, u32 cpha,
----- ----- u32 tx_hi_z, u32 lsb_first)
+++++ +++++ u32 tx_hi_z, u32 lsb_first, u32 cs_high)
{
u32 tmp;
int edge;
* 1 1 11 11 1 1
*/
sh_msiof_write(p, FCTR, 0);
----- ----- sh_msiof_write(p, TMDR1, 0xe2000005 | (lsb_first << 24));
----- ----- sh_msiof_write(p, RMDR1, 0x22000005 | (lsb_first << 24));
+++++ +++++
+++++ +++++ tmp = 0;
+++++ +++++ tmp |= !cs_high << 25;
+++++ +++++ tmp |= lsb_first << 24;
+++++ +++++ sh_msiof_write(p, TMDR1, 0xe0000005 | tmp);
+++++ +++++ sh_msiof_write(p, RMDR1, 0x20000005 | tmp);
tmp = 0xa0000000;
tmp |= cpol << 30; /* TSCKIZ */
sh_msiof_spi_set_pin_regs(p, !!(spi->mode & SPI_CPOL),
!!(spi->mode & SPI_CPHA),
!!(spi->mode & SPI_3WIRE),
----- ----- !!(spi->mode & SPI_LSB_FIRST));
+++++ +++++ !!(spi->mode & SPI_LSB_FIRST),
+++++ +++++ !!(spi->mode & SPI_CS_HIGH));
}
/* use spi->controller data for CS (same strategy as spi_gpio) */
----- ----- gpio_set_value((unsigned)spi->controller_data, value);
+++++ +++++ gpio_set_value((uintptr_t)spi->controller_data, value);
if (is_on == BITBANG_CS_INACTIVE) {
if (test_and_clear_bit(0, &p->flags)) {
master = spi_alloc_master(&pdev->dev, sizeof(struct sh_msiof_spi_priv));
if (master == NULL) {
dev_err(&pdev->dev, "failed to allocate spi master\n");
----- ----- ret = -ENOMEM;
----- ----- goto err0;
+++++ +++++ return -ENOMEM;
}
p = spi_master_get_devdata(master);
init_completion(&p->done);
----- ----- p->clk = clk_get(&pdev->dev, NULL);
+++++ +++++ p->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(p->clk)) {
dev_err(&pdev->dev, "cannot get clock\n");
ret = PTR_ERR(p->clk);
goto err1;
}
----- ----- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
i = platform_get_irq(pdev, 0);
----- ----- if (!r || i < 0) {
----- ----- dev_err(&pdev->dev, "cannot get platform resources\n");
+++++ +++++ if (i < 0) {
+++++ +++++ dev_err(&pdev->dev, "cannot get platform IRQ\n");
ret = -ENOENT;
----- ----- goto err2;
+++++ +++++ goto err1;
}
----- ----- p->mapbase = ioremap_nocache(r->start, resource_size(r));
----- ----- if (!p->mapbase) {
----- ----- dev_err(&pdev->dev, "unable to ioremap\n");
----- ----- ret = -ENXIO;
----- ----- goto err2;
+++++ +++++
+++++ +++++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+++++ +++++ p->mapbase = devm_ioremap_resource(&pdev->dev, r);
+++++ +++++ if (IS_ERR(p->mapbase)) {
+++++ +++++ ret = PTR_ERR(p->mapbase);
+++++ +++++ goto err1;
}
----- ----- ret = request_irq(i, sh_msiof_spi_irq, 0,
----- ----- dev_name(&pdev->dev), p);
+++++ +++++ ret = devm_request_irq(&pdev->dev, i, sh_msiof_spi_irq, 0,
+++++ +++++ dev_name(&pdev->dev), p);
if (ret) {
dev_err(&pdev->dev, "unable to request irq\n");
----- ----- goto err3;
+++++ +++++ goto err1;
+++++ +++++ }
+++++ +++++
+++++ +++++ ret = clk_prepare(p->clk);
+++++ +++++ if (ret < 0) {
+++++ +++++ dev_err(&pdev->dev, "unable to prepare clock\n");
+++++ +++++ goto err1;
}
p->pdev = pdev;
return 0;
pm_runtime_disable(&pdev->dev);
----- ----- err3:
----- ----- iounmap(p->mapbase);
----- ----- err2:
----- ----- clk_put(p->clk);
+++++ +++++ clk_unprepare(p->clk);
err1:
spi_master_put(master);
----- ----- err0:
return ret;
}
ret = spi_bitbang_stop(&p->bitbang);
if (!ret) {
pm_runtime_disable(&pdev->dev);
----- ----- free_irq(platform_get_irq(pdev, 0), p);
----- ----- iounmap(p->mapbase);
----- ----- clk_put(p->clk);
+++++ +++++ clk_unprepare(p->clk);
spi_master_put(p->bitbang.master);
}
return ret;
struct pch_spi_board_data *board_dat;
};
---------- static DEFINE_PCI_DEVICE_TABLE(pch_spi_pcidev_id) = {
++++++++++ static const struct pci_device_id pch_spi_pcidev_id[] = {
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_GE_SPI), 1, },
{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_SPI), 2, },
{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_SPI), 1, },
static int pch_spi_setup(struct spi_device *pspi)
{
---------- /* check bits per word */
---------- if (pspi->bits_per_word == 0) {
---------- pspi->bits_per_word = 8;
---------- dev_dbg(&pspi->dev, "%s 8 bits per word\n", __func__);
---------- }
----------
/* Check baud rate setting */
/* if baud rate of chip is greater than
max we can support,return error */