Loading drivers/gpio/gpiolib-of.c +27 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,29 @@ #include "gpiolib.h" #include "gpiolib-of.h" /** * of_gpio_spi_cs_get_count() - special GPIO counting for SPI * Some elder GPIO controllers need special quirks. Currently we handle * the Freescale GPIO controller with bindings that doesn't use the * established "cs-gpios" for chip selects but instead rely on * "gpios" for the chip select lines. If we detect this, we redirect * the counting of "cs-gpios" to count "gpios" transparent to the * driver. */ static int of_gpio_spi_cs_get_count(struct device *dev, const char *con_id) { struct device_node *np = dev->of_node; if (!IS_ENABLED(CONFIG_SPI_MASTER)) return 0; if (!con_id || strcmp(con_id, "cs")) return 0; if (!of_device_is_compatible(np, "fsl,spi") && !of_device_is_compatible(np, "aeroflexgaisler,spictrl")) return 0; return of_gpio_named_count(np, "gpios"); } /* * This is used by external users of of_gpio_count() from <linux/of_gpio.h> * Loading @@ -35,6 +58,10 @@ int of_gpio_get_count(struct device *dev, const char *con_id) char propname[32]; unsigned int i; ret = of_gpio_spi_cs_get_count(dev, con_id); if (ret > 0) return ret; for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { if (con_id) snprintf(propname, sizeof(propname), "%s-%s", Loading drivers/spi/spi-cadence.c +3 −3 Original line number Diff line number Diff line Loading @@ -168,16 +168,16 @@ static void cdns_spi_init_hw(struct cdns_spi *xspi) /** * cdns_spi_chipselect - Select or deselect the chip select line * @spi: Pointer to the spi_device structure * @enable: Select (1) or deselect (0) the chip select line * @is_high: Select(0) or deselect (1) the chip select line */ static void cdns_spi_chipselect(struct spi_device *spi, bool enable) static void cdns_spi_chipselect(struct spi_device *spi, bool is_high) { struct cdns_spi *xspi = spi_master_get_devdata(spi->master); u32 ctrl_reg; ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR); if (!enable) { if (is_high) { /* Deselect the slave */ ctrl_reg |= CDNS_SPI_CR_SSCTRL; } else { Loading drivers/spi/spi-cavium-thunderx.c +2 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ static int thunderx_spi_probe(struct pci_dev *pdev, error: clk_disable_unprepare(p->clk); pci_release_regions(pdev); spi_master_put(master); return ret; } Loading @@ -96,6 +97,7 @@ static void thunderx_spi_remove(struct pci_dev *pdev) return; clk_disable_unprepare(p->clk); pci_release_regions(pdev); /* Put everything in a known state. */ writeq(0, p->register_base + OCTEON_SPI_CFG(p)); } Loading drivers/spi/spi-dw.c +3 −2 Original line number Diff line number Diff line Loading @@ -129,10 +129,11 @@ void dw_spi_set_cs(struct spi_device *spi, bool enable) struct dw_spi *dws = spi_controller_get_devdata(spi->controller); struct chip_data *chip = spi_get_ctldata(spi); /* Chip select logic is inverted from spi_set_cs() */ if (chip && chip->cs_control) chip->cs_control(enable); chip->cs_control(!enable); if (enable) if (!enable) dw_writel(dws, DW_SPI_SER, BIT(spi->chip_select)); else if (dws->cs_override) dw_writel(dws, DW_SPI_SER, 0); Loading drivers/spi/spi-fsl-spi.c +16 −6 Original line number Diff line number Diff line Loading @@ -611,6 +611,7 @@ static struct spi_master * fsl_spi_probe(struct device *dev, master->setup = fsl_spi_setup; master->cleanup = fsl_spi_cleanup; master->transfer_one_message = fsl_spi_do_one_msg; master->use_gpio_descriptors = true; mpc8xxx_spi = spi_master_get_devdata(master); mpc8xxx_spi->max_bits_per_word = 32; Loading Loading @@ -727,7 +728,17 @@ static int of_fsl_spi_probe(struct platform_device *ofdev) } } #endif /* * Handle the case where we have one hardwired (always selected) * device on the first "chipselect". Else we let the core code * handle any GPIOs or native chip selects and assign the * appropriate callback for dealing with the CS lines. This isn't * supported on the GRLIB variant. */ ret = gpiod_count(dev, "cs"); if (ret <= 0) pdata->max_chipselect = 1; else pdata->cs_control = fsl_spi_cs_control; } Loading @@ -735,9 +746,9 @@ static int of_fsl_spi_probe(struct platform_device *ofdev) if (ret) goto err; irq = irq_of_parse_and_map(np, 0); if (!irq) { ret = -EINVAL; irq = platform_get_irq(ofdev, 0); if (irq < 0) { ret = irq; goto err; } Loading @@ -750,7 +761,6 @@ static int of_fsl_spi_probe(struct platform_device *ofdev) return 0; err: irq_dispose_mapping(irq); return ret; } Loading Loading
drivers/gpio/gpiolib-of.c +27 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,29 @@ #include "gpiolib.h" #include "gpiolib-of.h" /** * of_gpio_spi_cs_get_count() - special GPIO counting for SPI * Some elder GPIO controllers need special quirks. Currently we handle * the Freescale GPIO controller with bindings that doesn't use the * established "cs-gpios" for chip selects but instead rely on * "gpios" for the chip select lines. If we detect this, we redirect * the counting of "cs-gpios" to count "gpios" transparent to the * driver. */ static int of_gpio_spi_cs_get_count(struct device *dev, const char *con_id) { struct device_node *np = dev->of_node; if (!IS_ENABLED(CONFIG_SPI_MASTER)) return 0; if (!con_id || strcmp(con_id, "cs")) return 0; if (!of_device_is_compatible(np, "fsl,spi") && !of_device_is_compatible(np, "aeroflexgaisler,spictrl")) return 0; return of_gpio_named_count(np, "gpios"); } /* * This is used by external users of of_gpio_count() from <linux/of_gpio.h> * Loading @@ -35,6 +58,10 @@ int of_gpio_get_count(struct device *dev, const char *con_id) char propname[32]; unsigned int i; ret = of_gpio_spi_cs_get_count(dev, con_id); if (ret > 0) return ret; for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { if (con_id) snprintf(propname, sizeof(propname), "%s-%s", Loading
drivers/spi/spi-cadence.c +3 −3 Original line number Diff line number Diff line Loading @@ -168,16 +168,16 @@ static void cdns_spi_init_hw(struct cdns_spi *xspi) /** * cdns_spi_chipselect - Select or deselect the chip select line * @spi: Pointer to the spi_device structure * @enable: Select (1) or deselect (0) the chip select line * @is_high: Select(0) or deselect (1) the chip select line */ static void cdns_spi_chipselect(struct spi_device *spi, bool enable) static void cdns_spi_chipselect(struct spi_device *spi, bool is_high) { struct cdns_spi *xspi = spi_master_get_devdata(spi->master); u32 ctrl_reg; ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR); if (!enable) { if (is_high) { /* Deselect the slave */ ctrl_reg |= CDNS_SPI_CR_SSCTRL; } else { Loading
drivers/spi/spi-cavium-thunderx.c +2 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ static int thunderx_spi_probe(struct pci_dev *pdev, error: clk_disable_unprepare(p->clk); pci_release_regions(pdev); spi_master_put(master); return ret; } Loading @@ -96,6 +97,7 @@ static void thunderx_spi_remove(struct pci_dev *pdev) return; clk_disable_unprepare(p->clk); pci_release_regions(pdev); /* Put everything in a known state. */ writeq(0, p->register_base + OCTEON_SPI_CFG(p)); } Loading
drivers/spi/spi-dw.c +3 −2 Original line number Diff line number Diff line Loading @@ -129,10 +129,11 @@ void dw_spi_set_cs(struct spi_device *spi, bool enable) struct dw_spi *dws = spi_controller_get_devdata(spi->controller); struct chip_data *chip = spi_get_ctldata(spi); /* Chip select logic is inverted from spi_set_cs() */ if (chip && chip->cs_control) chip->cs_control(enable); chip->cs_control(!enable); if (enable) if (!enable) dw_writel(dws, DW_SPI_SER, BIT(spi->chip_select)); else if (dws->cs_override) dw_writel(dws, DW_SPI_SER, 0); Loading
drivers/spi/spi-fsl-spi.c +16 −6 Original line number Diff line number Diff line Loading @@ -611,6 +611,7 @@ static struct spi_master * fsl_spi_probe(struct device *dev, master->setup = fsl_spi_setup; master->cleanup = fsl_spi_cleanup; master->transfer_one_message = fsl_spi_do_one_msg; master->use_gpio_descriptors = true; mpc8xxx_spi = spi_master_get_devdata(master); mpc8xxx_spi->max_bits_per_word = 32; Loading Loading @@ -727,7 +728,17 @@ static int of_fsl_spi_probe(struct platform_device *ofdev) } } #endif /* * Handle the case where we have one hardwired (always selected) * device on the first "chipselect". Else we let the core code * handle any GPIOs or native chip selects and assign the * appropriate callback for dealing with the CS lines. This isn't * supported on the GRLIB variant. */ ret = gpiod_count(dev, "cs"); if (ret <= 0) pdata->max_chipselect = 1; else pdata->cs_control = fsl_spi_cs_control; } Loading @@ -735,9 +746,9 @@ static int of_fsl_spi_probe(struct platform_device *ofdev) if (ret) goto err; irq = irq_of_parse_and_map(np, 0); if (!irq) { ret = -EINVAL; irq = platform_get_irq(ofdev, 0); if (irq < 0) { ret = irq; goto err; } Loading @@ -750,7 +761,6 @@ static int of_fsl_spi_probe(struct platform_device *ofdev) return 0; err: irq_dispose_mapping(irq); return ret; } Loading