Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c70c5fb2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'pwm/for-4.2-rc1' of...

Merge tag 'pwm/for-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm

Pull pwm updates from Thierry Reding:
 "This has a couple of fixes for Atmel, Samsung and Broadcom drivers.

  Some preparatory patches for more upcoming Intel work is included as
  well"

* tag 'pwm/for-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm:
  pwm: lpss: pci: Add support for Broxton platform
  pwm: bcm-kona: Don't set polarity in probe
  pwm: Add pwmchip_add_with_polarity() API
  pwm: atmel: Fix incorrect CDTY value after disabling
  pwm: atmel: Fix incorrect CDTY value after enabling
  pwm: samsung: Use MODULE_DEVICE_TABLE() to include OF modalias
  pwm: Add support to remove registered consumer lookup tables
parents 44d21c3f 361c1066
Loading
Loading
Loading
Loading
+37 −3
Original line number Diff line number Diff line
@@ -223,13 +223,16 @@ void *pwm_get_chip_data(struct pwm_device *pwm)
EXPORT_SYMBOL_GPL(pwm_get_chip_data);

/**
 * pwmchip_add() - register a new PWM chip
 * pwmchip_add_with_polarity() - register a new PWM chip
 * @chip: the PWM chip to add
 * @polarity: initial polarity of PWM channels
 *
 * Register a new PWM chip. If chip->base < 0 then a dynamically assigned base
 * will be used.
 * will be used. The initial polarity for all channels is specified by the
 * @polarity parameter.
 */
int pwmchip_add(struct pwm_chip *chip)
int pwmchip_add_with_polarity(struct pwm_chip *chip,
			      enum pwm_polarity polarity)
{
	struct pwm_device *pwm;
	unsigned int i;
@@ -259,6 +262,7 @@ int pwmchip_add(struct pwm_chip *chip)
		pwm->chip = chip;
		pwm->pwm = chip->base + i;
		pwm->hwpwm = i;
		pwm->polarity = polarity;

		radix_tree_insert(&pwm_tree, pwm->pwm, pwm);
	}
@@ -279,6 +283,19 @@ int pwmchip_add(struct pwm_chip *chip)
	mutex_unlock(&pwm_lock);
	return ret;
}
EXPORT_SYMBOL_GPL(pwmchip_add_with_polarity);

/**
 * pwmchip_add() - register a new PWM chip
 * @chip: the PWM chip to add
 *
 * Register a new PWM chip. If chip->base < 0 then a dynamically assigned base
 * will be used. The initial polarity for all channels is normal.
 */
int pwmchip_add(struct pwm_chip *chip)
{
	return pwmchip_add_with_polarity(chip, PWM_POLARITY_NORMAL);
}
EXPORT_SYMBOL_GPL(pwmchip_add);

/**
@@ -585,6 +602,23 @@ void pwm_add_table(struct pwm_lookup *table, size_t num)
	mutex_unlock(&pwm_lookup_lock);
}

/**
 * pwm_remove_table() - unregister PWM device consumers
 * @table: array of consumers to unregister
 * @num: number of consumers in table
 */
void pwm_remove_table(struct pwm_lookup *table, size_t num)
{
	mutex_lock(&pwm_lookup_lock);

	while (num--) {
		list_del(&table->list);
		table++;
	}

	mutex_unlock(&pwm_lookup_lock);
}

/**
 * pwm_get() - look up and request a PWM device
 * @dev: device for PWM consumer
+46 −17
Original line number Diff line number Diff line
@@ -8,9 +8,11 @@
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
@@ -21,6 +23,7 @@
#define PWM_ENA			0x04
#define PWM_DIS			0x08
#define PWM_SR			0x0C
#define PWM_ISR			0x1C
/* Bit field in SR */
#define PWM_SR_ALL_CH_ON	0x0F

@@ -60,6 +63,9 @@ struct atmel_pwm_chip {
	struct clk *clk;
	void __iomem *base;

	unsigned int updated_pwms;
	struct mutex isr_lock; /* ISR is cleared when read, ensure only one thread does that */

	void (*config)(struct pwm_chip *chip, struct pwm_device *pwm,
		       unsigned long dty, unsigned long prd);
};
@@ -144,6 +150,10 @@ static int atmel_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
	val = (val & ~PWM_CMR_CPRE_MSK) | (pres & PWM_CMR_CPRE_MSK);
	atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val);
	atmel_pwm->config(chip, pwm, dty, prd);
	mutex_lock(&atmel_pwm->isr_lock);
	atmel_pwm->updated_pwms |= atmel_pwm_readl(atmel_pwm, PWM_ISR);
	atmel_pwm->updated_pwms &= ~(1 << pwm->hwpwm);
	mutex_unlock(&atmel_pwm->isr_lock);

	clk_disable(atmel_pwm->clk);
	return ret;
@@ -155,25 +165,26 @@ static void atmel_pwm_config_v1(struct pwm_chip *chip, struct pwm_device *pwm,
	struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
	unsigned int val;

	if (test_bit(PWMF_ENABLED, &pwm->flags)) {
		/*
		 * If the PWM channel is enabled, using the update register,
		 * it needs to set bit 10 of CMR to 0
		 */

	atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWMV1_CUPD, dty);

	val = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);
	val &= ~PWM_CMR_UPD_CDTY;
	atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val);
	} else {

	/*
		 * If the PWM channel is disabled, write value to duty and
		 * period registers directly.
	 * If the PWM channel is enabled, only update CDTY by using the update
	 * register, it needs to set bit 10 of CMR to 0
	 */
	if (test_bit(PWMF_ENABLED, &pwm->flags))
		return;
	/*
	 * If the PWM channel is disabled, write value to duty and period
	 * registers directly.
	 */
	atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWMV1_CDTY, dty);
	atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWMV1_CPRD, prd);
}
}

static void atmel_pwm_config_v2(struct pwm_chip *chip, struct pwm_device *pwm,
				unsigned long dty, unsigned long prd)
@@ -242,7 +253,22 @@ static int atmel_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
static void atmel_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
	unsigned long timeout = jiffies + 2 * HZ;

	/*
	 * Wait for at least a complete period to have passed before disabling a
	 * channel to be sure that CDTY has been updated
	 */
	mutex_lock(&atmel_pwm->isr_lock);
	atmel_pwm->updated_pwms |= atmel_pwm_readl(atmel_pwm, PWM_ISR);

	while (!(atmel_pwm->updated_pwms & (1 << pwm->hwpwm)) &&
	       time_before(jiffies, timeout)) {
		usleep_range(10, 100);
		atmel_pwm->updated_pwms |= atmel_pwm_readl(atmel_pwm, PWM_ISR);
	}

	mutex_unlock(&atmel_pwm->isr_lock);
	atmel_pwm_writel(atmel_pwm, PWM_DIS, 1 << pwm->hwpwm);

	clk_disable(atmel_pwm->clk);
@@ -357,6 +383,8 @@ static int atmel_pwm_probe(struct platform_device *pdev)
	atmel_pwm->chip.npwm = 4;
	atmel_pwm->chip.can_sleep = true;
	atmel_pwm->config = data->config;
	atmel_pwm->updated_pwms = 0;
	mutex_init(&atmel_pwm->isr_lock);

	ret = pwmchip_add(&atmel_pwm->chip);
	if (ret < 0) {
@@ -378,6 +406,7 @@ static int atmel_pwm_remove(struct platform_device *pdev)
	struct atmel_pwm_chip *atmel_pwm = platform_get_drvdata(pdev);

	clk_unprepare(atmel_pwm->clk);
	mutex_destroy(&atmel_pwm->isr_lock);

	return pwmchip_remove(&atmel_pwm->chip);
}
+3 −6
Original line number Diff line number Diff line
@@ -266,18 +266,15 @@ static int kona_pwmc_probe(struct platform_device *pdev)
		return ret;
	}

	/* Set smooth mode, push/pull, and normal polarity for all channels */
	for (chan = 0; chan < kp->chip.npwm; chan++) {
		value |= (1 << PWM_CONTROL_SMOOTH_SHIFT(chan));
	/* Set push/pull for all channels */
	for (chan = 0; chan < kp->chip.npwm; chan++)
		value |= (1 << PWM_CONTROL_TYPE_SHIFT(chan));
		value |= (1 << PWM_CONTROL_POLARITY_SHIFT(chan));
	}

	writel(value, kp->base + PWM_CONTROL_OFFSET);

	clk_disable_unprepare(kp->clk);

	ret = pwmchip_add(&kp->chip);
	ret = pwmchip_add_with_polarity(&kp->chip, PWM_POLARITY_INVERSED);
	if (ret < 0)
		dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);

+2 −0
Original line number Diff line number Diff line
@@ -44,8 +44,10 @@ static void pwm_lpss_remove_pci(struct pci_dev *pdev)
}

static const struct pci_device_id pwm_lpss_pci_ids[] = {
	{ PCI_VDEVICE(INTEL, 0x0ac8), (unsigned long)&pwm_lpss_bsw_info},
	{ PCI_VDEVICE(INTEL, 0x0f08), (unsigned long)&pwm_lpss_byt_info},
	{ PCI_VDEVICE(INTEL, 0x0f09), (unsigned long)&pwm_lpss_byt_info},
	{ PCI_VDEVICE(INTEL, 0x1ac8), (unsigned long)&pwm_lpss_bsw_info},
	{ PCI_VDEVICE(INTEL, 0x2288), (unsigned long)&pwm_lpss_bsw_info},
	{ PCI_VDEVICE(INTEL, 0x2289), (unsigned long)&pwm_lpss_bsw_info},
	{ },
+1 −0
Original line number Diff line number Diff line
@@ -456,6 +456,7 @@ static const struct of_device_id samsung_pwm_matches[] = {
	{ .compatible = "samsung,exynos4210-pwm", .data = &s5p64x0_variant },
	{},
};
MODULE_DEVICE_TABLE(of, samsung_pwm_matches);

static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip)
{
Loading