diff options
Diffstat (limited to 'kernel/drivers/pinctrl/bcm')
-rw-r--r-- | kernel/drivers/pinctrl/bcm/pinctrl-bcm281xx.c | 4 | ||||
-rw-r--r-- | kernel/drivers/pinctrl/bcm/pinctrl-bcm2835.c | 38 | ||||
-rw-r--r-- | kernel/drivers/pinctrl/bcm/pinctrl-cygnus-gpio.c | 141 | ||||
-rw-r--r-- | kernel/drivers/pinctrl/bcm/pinctrl-cygnus-mux.c | 4 |
4 files changed, 27 insertions, 160 deletions
diff --git a/kernel/drivers/pinctrl/bcm/pinctrl-bcm281xx.c b/kernel/drivers/pinctrl/bcm/pinctrl-bcm281xx.c index 9641f1c76..c3c692e50 100644 --- a/kernel/drivers/pinctrl/bcm/pinctrl-bcm281xx.c +++ b/kernel/drivers/pinctrl/bcm/pinctrl-bcm281xx.c @@ -1425,9 +1425,9 @@ static int __init bcm281xx_pinctrl_probe(struct platform_device *pdev) pctl = pinctrl_register(&bcm281xx_pinctrl_desc, &pdev->dev, pdata); - if (!pctl) { + if (IS_ERR(pctl)) { dev_err(&pdev->dev, "Failed to register pinctrl\n"); - return -ENODEV; + return PTR_ERR(pctl); } platform_set_drvdata(pdev, pdata); diff --git a/kernel/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/kernel/drivers/pinctrl/bcm/pinctrl-bcm2835.c index 8d908e3f4..2e6ca6963 100644 --- a/kernel/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/kernel/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -330,16 +330,6 @@ static inline void bcm2835_pinctrl_fsel_set( bcm2835_gpio_wr(pc, FSEL_REG(pin), val); } -static int bcm2835_gpio_request(struct gpio_chip *chip, unsigned offset) -{ - return pinctrl_request_gpio(chip->base + offset); -} - -static void bcm2835_gpio_free(struct gpio_chip *chip, unsigned offset) -{ - pinctrl_free_gpio(chip->base + offset); -} - static int bcm2835_gpio_direction_input(struct gpio_chip *chip, unsigned offset) { return pinctrl_gpio_direction_input(chip->base + offset); @@ -352,12 +342,6 @@ static int bcm2835_gpio_get(struct gpio_chip *chip, unsigned offset) return bcm2835_gpio_get_bit(pc, GPLEV0, offset); } -static int bcm2835_gpio_direction_output(struct gpio_chip *chip, - unsigned offset, int value) -{ - return pinctrl_gpio_direction_output(chip->base + offset); -} - static void bcm2835_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { struct bcm2835_pinctrl *pc = dev_get_drvdata(chip->dev); @@ -365,6 +349,13 @@ static void bcm2835_gpio_set(struct gpio_chip *chip, unsigned offset, int value) bcm2835_gpio_set_bit(pc, value ? GPSET0 : GPCLR0, offset); } +static int bcm2835_gpio_direction_output(struct gpio_chip *chip, + unsigned offset, int value) +{ + bcm2835_gpio_set(chip, offset, value); + return pinctrl_gpio_direction_output(chip->base + offset); +} + static int bcm2835_gpio_to_irq(struct gpio_chip *chip, unsigned offset) { struct bcm2835_pinctrl *pc = dev_get_drvdata(chip->dev); @@ -375,8 +366,8 @@ static int bcm2835_gpio_to_irq(struct gpio_chip *chip, unsigned offset) static struct gpio_chip bcm2835_gpio_chip = { .label = MODULE_NAME, .owner = THIS_MODULE, - .request = bcm2835_gpio_request, - .free = bcm2835_gpio_free, + .request = gpiochip_generic_request, + .free = gpiochip_generic_free, .direction_input = bcm2835_gpio_direction_input, .direction_output = bcm2835_gpio_direction_output, .get = bcm2835_gpio_get, @@ -473,6 +464,8 @@ static void bcm2835_gpio_irq_disable(struct irq_data *data) spin_lock_irqsave(&pc->irq_lock[bank], flags); bcm2835_gpio_irq_config(pc, gpio, false); + /* Clear events that were latched prior to clearing event sources */ + bcm2835_gpio_set_bit(pc, GPEDS0, gpio); clear_bit(offset, &pc->enabled_irq_map[bank]); spin_unlock_irqrestore(&pc->irq_lock[bank], flags); } @@ -584,9 +577,9 @@ static int bcm2835_gpio_irq_set_type(struct irq_data *data, unsigned int type) ret = __bcm2835_gpio_irq_set_type_disabled(pc, gpio, type); if (type & IRQ_TYPE_EDGE_BOTH) - __irq_set_handler_locked(data->irq, handle_edge_irq); + irq_set_handler_locked(data, handle_edge_irq); else - __irq_set_handler_locked(data->irq, handle_level_irq); + irq_set_handler_locked(data, handle_level_irq); spin_unlock_irqrestore(&pc->irq_lock[bank], flags); @@ -987,7 +980,6 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) irq_set_chip_and_handler(irq, &bcm2835_gpio_irq_chip, handle_level_irq); irq_set_chip_data(irq, pc); - set_irq_flags(irq, IRQF_VALID); } for (i = 0; i < BCM2835_NUM_BANKS; i++) { @@ -1036,9 +1028,9 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) } pc->pctl_dev = pinctrl_register(&bcm2835_pinctrl_desc, dev, pc); - if (!pc->pctl_dev) { + if (IS_ERR(pc->pctl_dev)) { gpiochip_remove(&pc->gpio_chip); - return -EINVAL; + return PTR_ERR(pc->pctl_dev); } pc->gpio_range = bcm2835_pinctrl_gpio_range; diff --git a/kernel/drivers/pinctrl/bcm/pinctrl-cygnus-gpio.c b/kernel/drivers/pinctrl/bcm/pinctrl-cygnus-gpio.c index e406e3d8c..12a48f498 100644 --- a/kernel/drivers/pinctrl/bcm/pinctrl-cygnus-gpio.c +++ b/kernel/drivers/pinctrl/bcm/pinctrl-cygnus-gpio.c @@ -29,7 +29,6 @@ #include <linux/of_device.h> #include <linux/of_irq.h> #include <linux/pinctrl/pinctrl.h> -#include <linux/pinctrl/pinmux.h> #include <linux/pinctrl/pinconf.h> #include <linux/pinctrl/pinconf-generic.h> @@ -38,7 +37,7 @@ #define CYGNUS_GPIO_DATA_IN_OFFSET 0x00 #define CYGNUS_GPIO_DATA_OUT_OFFSET 0x04 #define CYGNUS_GPIO_OUT_EN_OFFSET 0x08 -#define CYGNUS_GPIO_IN_TYPE_OFFSET 0x0c +#define CYGNUS_GPIO_INT_TYPE_OFFSET 0x0c #define CYGNUS_GPIO_INT_DE_OFFSET 0x10 #define CYGNUS_GPIO_INT_EDGE_OFFSET 0x14 #define CYGNUS_GPIO_INT_MSK_OFFSET 0x18 @@ -143,7 +142,7 @@ static inline bool cygnus_get_bit(struct cygnus_gpio *chip, unsigned int reg, return !!(readl(chip->base + offset) & BIT(shift)); } -static void cygnus_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) +static void cygnus_gpio_irq_handler(struct irq_desc *desc) { struct gpio_chip *gc = irq_desc_get_handler_data(desc); struct cygnus_gpio *chip = to_cygnus_gpio(gc); @@ -264,7 +263,7 @@ static int cygnus_gpio_irq_set_type(struct irq_data *d, unsigned int type) } spin_lock_irqsave(&chip->lock, flags); - cygnus_set_bit(chip, CYGNUS_GPIO_IN_TYPE_OFFSET, gpio, + cygnus_set_bit(chip, CYGNUS_GPIO_INT_TYPE_OFFSET, gpio, level_triggered); cygnus_set_bit(chip, CYGNUS_GPIO_INT_DE_OFFSET, gpio, dual_edge); cygnus_set_bit(chip, CYGNUS_GPIO_INT_EDGE_OFFSET, gpio, @@ -597,127 +596,6 @@ static const struct pinconf_ops cygnus_pconf_ops = { }; /* - * Map a GPIO in the local gpio_chip pin space to a pin in the Cygnus IOMUX - * pinctrl pin space - */ -struct cygnus_gpio_pin_range { - unsigned offset; - unsigned pin_base; - unsigned num_pins; -}; - -#define CYGNUS_PINRANGE(o, p, n) { .offset = o, .pin_base = p, .num_pins = n } - -/* - * Pin mapping table for mapping local GPIO pins to Cygnus IOMUX pinctrl pins - */ -static const struct cygnus_gpio_pin_range cygnus_gpio_pintable[] = { - CYGNUS_PINRANGE(0, 42, 1), - CYGNUS_PINRANGE(1, 44, 3), - CYGNUS_PINRANGE(4, 48, 1), - CYGNUS_PINRANGE(5, 50, 3), - CYGNUS_PINRANGE(8, 126, 1), - CYGNUS_PINRANGE(9, 155, 1), - CYGNUS_PINRANGE(10, 152, 1), - CYGNUS_PINRANGE(11, 154, 1), - CYGNUS_PINRANGE(12, 153, 1), - CYGNUS_PINRANGE(13, 127, 3), - CYGNUS_PINRANGE(16, 140, 1), - CYGNUS_PINRANGE(17, 145, 7), - CYGNUS_PINRANGE(24, 130, 10), - CYGNUS_PINRANGE(34, 141, 4), - CYGNUS_PINRANGE(38, 54, 1), - CYGNUS_PINRANGE(39, 56, 3), - CYGNUS_PINRANGE(42, 60, 3), - CYGNUS_PINRANGE(45, 64, 3), - CYGNUS_PINRANGE(48, 68, 2), - CYGNUS_PINRANGE(50, 84, 6), - CYGNUS_PINRANGE(56, 94, 6), - CYGNUS_PINRANGE(62, 72, 1), - CYGNUS_PINRANGE(63, 70, 1), - CYGNUS_PINRANGE(64, 80, 1), - CYGNUS_PINRANGE(65, 74, 3), - CYGNUS_PINRANGE(68, 78, 1), - CYGNUS_PINRANGE(69, 82, 1), - CYGNUS_PINRANGE(70, 156, 17), - CYGNUS_PINRANGE(87, 104, 12), - CYGNUS_PINRANGE(99, 102, 2), - CYGNUS_PINRANGE(101, 90, 4), - CYGNUS_PINRANGE(105, 116, 6), - CYGNUS_PINRANGE(111, 100, 2), - CYGNUS_PINRANGE(113, 122, 4), - CYGNUS_PINRANGE(123, 11, 1), - CYGNUS_PINRANGE(124, 38, 4), - CYGNUS_PINRANGE(128, 43, 1), - CYGNUS_PINRANGE(129, 47, 1), - CYGNUS_PINRANGE(130, 49, 1), - CYGNUS_PINRANGE(131, 53, 1), - CYGNUS_PINRANGE(132, 55, 1), - CYGNUS_PINRANGE(133, 59, 1), - CYGNUS_PINRANGE(134, 63, 1), - CYGNUS_PINRANGE(135, 67, 1), - CYGNUS_PINRANGE(136, 71, 1), - CYGNUS_PINRANGE(137, 73, 1), - CYGNUS_PINRANGE(138, 77, 1), - CYGNUS_PINRANGE(139, 79, 1), - CYGNUS_PINRANGE(140, 81, 1), - CYGNUS_PINRANGE(141, 83, 1), - CYGNUS_PINRANGE(142, 10, 1) -}; - -/* - * The Cygnus IOMUX controller mainly supports group based mux configuration, - * but certain pins can be muxed to GPIO individually. Only the ASIU GPIO - * controller can support this, so it's an optional configuration - * - * Return -ENODEV means no support and that's fine - */ -static int cygnus_gpio_pinmux_add_range(struct cygnus_gpio *chip) -{ - struct device_node *node = chip->dev->of_node; - struct device_node *pinmux_node; - struct platform_device *pinmux_pdev; - struct gpio_chip *gc = &chip->gc; - int i, ret = 0; - - /* parse DT to find the phandle to the pinmux controller */ - pinmux_node = of_parse_phandle(node, "pinmux", 0); - if (!pinmux_node) - return -ENODEV; - - pinmux_pdev = of_find_device_by_node(pinmux_node); - /* no longer need the pinmux node */ - of_node_put(pinmux_node); - if (!pinmux_pdev) { - dev_err(chip->dev, "failed to get pinmux device\n"); - return -EINVAL; - } - - /* now need to create the mapping between local GPIO and PINMUX pins */ - for (i = 0; i < ARRAY_SIZE(cygnus_gpio_pintable); i++) { - ret = gpiochip_add_pin_range(gc, dev_name(&pinmux_pdev->dev), - cygnus_gpio_pintable[i].offset, - cygnus_gpio_pintable[i].pin_base, - cygnus_gpio_pintable[i].num_pins); - if (ret) { - dev_err(chip->dev, "unable to add GPIO pin range\n"); - goto err_put_device; - } - } - - chip->pinmux_is_supported = true; - - /* no need for pinmux_pdev device reference anymore */ - put_device(&pinmux_pdev->dev); - return 0; - -err_put_device: - put_device(&pinmux_pdev->dev); - gpiochip_remove_pin_ranges(gc); - return ret; -} - -/* * Cygnus GPIO controller supports some PINCONF related configurations such as * pull up, pull down, and drive strength, when the pin is configured to GPIO * @@ -750,9 +628,9 @@ static int cygnus_gpio_register_pinconf(struct cygnus_gpio *chip) pctldesc->confops = &cygnus_pconf_ops; chip->pctl = pinctrl_register(pctldesc, chip->dev, chip); - if (!chip->pctl) { + if (IS_ERR(chip->pctl)) { dev_err(chip->dev, "unable to register pinctrl device\n"); - return -EINVAL; + return PTR_ERR(chip->pctl); } return 0; @@ -851,18 +729,15 @@ static int cygnus_gpio_probe(struct platform_device *pdev) gc->set = cygnus_gpio_set; gc->get = cygnus_gpio_get; + chip->pinmux_is_supported = of_property_read_bool(dev->of_node, + "gpio-ranges"); + ret = gpiochip_add(gc); if (ret < 0) { dev_err(dev, "unable to add GPIO chip\n"); return ret; } - ret = cygnus_gpio_pinmux_add_range(chip); - if (ret && ret != -ENODEV) { - dev_err(dev, "unable to add GPIO pin range\n"); - goto err_rm_gpiochip; - } - ret = cygnus_gpio_register_pinconf(chip); if (ret) { dev_err(dev, "unable to register pinconf\n"); diff --git a/kernel/drivers/pinctrl/bcm/pinctrl-cygnus-mux.c b/kernel/drivers/pinctrl/bcm/pinctrl-cygnus-mux.c index f9a9283ca..9728f3db9 100644 --- a/kernel/drivers/pinctrl/bcm/pinctrl-cygnus-mux.c +++ b/kernel/drivers/pinctrl/bcm/pinctrl-cygnus-mux.c @@ -989,9 +989,9 @@ static int cygnus_pinmux_probe(struct platform_device *pdev) pinctrl->pctl = pinctrl_register(&cygnus_pinctrl_desc, &pdev->dev, pinctrl); - if (!pinctrl->pctl) { + if (IS_ERR(pinctrl->pctl)) { dev_err(&pdev->dev, "unable to register Cygnus IOMUX pinctrl\n"); - return -EINVAL; + return PTR_ERR(pinctrl->pctl); } return 0; |