Merge branch 'ib-qcom-ssbi' into devel
This commit is contained in:
Коммит
3dda927fdb
|
@ -93,9 +93,8 @@
|
||||||
vdd-supply = <&pm8058_l14>; // 2.85V
|
vdd-supply = <&pm8058_l14>; // 2.85V
|
||||||
aset-gpios = <&pm8058_gpio 35 GPIO_ACTIVE_LOW>;
|
aset-gpios = <&pm8058_gpio 35 GPIO_ACTIVE_LOW>;
|
||||||
capella,aset-resistance-ohms = <100000>;
|
capella,aset-resistance-ohms = <100000>;
|
||||||
/* GPIO34 has interrupt 225 on the PM8058 */
|
|
||||||
/* Trig on both edges - getting close or far away */
|
/* Trig on both edges - getting close or far away */
|
||||||
interrupts-extended = <&pm8058 225 IRQ_TYPE_EDGE_BOTH>;
|
interrupts-extended = <&pm8058_gpio 34 IRQ_TYPE_EDGE_BOTH>;
|
||||||
/* MPP05 analog input to the XOADC */
|
/* MPP05 analog input to the XOADC */
|
||||||
io-channels = <&xoadc 0x00 0x05>;
|
io-channels = <&xoadc 0x00 0x05>;
|
||||||
io-channel-names = "aout";
|
io-channel-names = "aout";
|
||||||
|
@ -515,9 +514,8 @@
|
||||||
ak8975@c {
|
ak8975@c {
|
||||||
compatible = "asahi-kasei,ak8975";
|
compatible = "asahi-kasei,ak8975";
|
||||||
reg = <0x0c>;
|
reg = <0x0c>;
|
||||||
/* FIXME: GPIO33 has interrupt 224 on the PM8058 */
|
interrupt-parent = <&pm8058_gpio>;
|
||||||
interrupt-parent = <&pm8058>;
|
interrupts = <33 IRQ_TYPE_EDGE_RISING>;
|
||||||
interrupts = <224 IRQ_TYPE_EDGE_RISING>;
|
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
pinctrl-0 = <&dragon_ak8975_gpios>;
|
pinctrl-0 = <&dragon_ak8975_gpios>;
|
||||||
vid-supply = <&pm8058_lvs0>; // 1.8V
|
vid-supply = <&pm8058_lvs0>; // 1.8V
|
||||||
|
@ -526,9 +524,8 @@
|
||||||
bmp085@77 {
|
bmp085@77 {
|
||||||
compatible = "bosch,bmp085";
|
compatible = "bosch,bmp085";
|
||||||
reg = <0x77>;
|
reg = <0x77>;
|
||||||
/* FIXME: GPIO16 has interrupt 207 on the PM8058 */
|
interrupt-parent = <&pm8058_gpio>;
|
||||||
interrupt-parent = <&pm8058>;
|
interrupts = <16 IRQ_TYPE_EDGE_RISING>;
|
||||||
interrupts = <207 IRQ_TYPE_EDGE_RISING>;
|
|
||||||
reset-gpios = <&tlmm 86 GPIO_ACTIVE_LOW>;
|
reset-gpios = <&tlmm 86 GPIO_ACTIVE_LOW>;
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
pinctrl-0 = <&dragon_bmp085_gpios>;
|
pinctrl-0 = <&dragon_bmp085_gpios>;
|
||||||
|
@ -539,12 +536,11 @@
|
||||||
compatible = "invensense,mpu3050";
|
compatible = "invensense,mpu3050";
|
||||||
reg = <0x68>;
|
reg = <0x68>;
|
||||||
/*
|
/*
|
||||||
* GPIO17 has interrupt 208 on the
|
* GPIO17 is pulled high by a 10k
|
||||||
* PM8058, it is pulled high by a 10k
|
|
||||||
* resistor to VLOGIC so needs to be
|
* resistor to VLOGIC so needs to be
|
||||||
* active low/falling edge.
|
* active low/falling edge.
|
||||||
*/
|
*/
|
||||||
interrupts-extended = <&pm8058 208 IRQ_TYPE_EDGE_FALLING>;
|
interrupts-extended = <&pm8058_gpio 17 IRQ_TYPE_EDGE_FALLING>;
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
pinctrl-0 = <&dragon_mpu3050_gpios>;
|
pinctrl-0 = <&dragon_mpu3050_gpios>;
|
||||||
vlogic-supply = <&pm8058_lvs0>; // 1.8V
|
vlogic-supply = <&pm8058_lvs0>; // 1.8V
|
||||||
|
@ -589,11 +585,10 @@
|
||||||
compatible = "smsc,lan9221", "smsc,lan9115";
|
compatible = "smsc,lan9221", "smsc,lan9115";
|
||||||
reg = <2 0x0 0x100>;
|
reg = <2 0x0 0x100>;
|
||||||
/*
|
/*
|
||||||
* GPIO7 has interrupt 198 on the PM8058
|
|
||||||
* The second interrupt is the PME interrupt
|
* The second interrupt is the PME interrupt
|
||||||
* for network wakeup, connected to the TLMM.
|
* for network wakeup, connected to the TLMM.
|
||||||
*/
|
*/
|
||||||
interrupts-extended = <&pm8058 198 IRQ_TYPE_EDGE_FALLING>,
|
interrupts-extended = <&pm8058_gpio 7 IRQ_TYPE_EDGE_FALLING>,
|
||||||
<&tlmm 29 IRQ_TYPE_EDGE_RISING>;
|
<&tlmm 29 IRQ_TYPE_EDGE_RISING>;
|
||||||
reset-gpios = <&tlmm 30 GPIO_ACTIVE_LOW>;
|
reset-gpios = <&tlmm 30 GPIO_ACTIVE_LOW>;
|
||||||
vdd33a-supply = <&dragon_veth>;
|
vdd33a-supply = <&dragon_veth>;
|
||||||
|
|
|
@ -705,50 +705,8 @@
|
||||||
compatible = "qcom,pm8921-gpio",
|
compatible = "qcom,pm8921-gpio",
|
||||||
"qcom,ssbi-gpio";
|
"qcom,ssbi-gpio";
|
||||||
reg = <0x150>;
|
reg = <0x150>;
|
||||||
interrupts = <192 IRQ_TYPE_NONE>,
|
interrupt-controller;
|
||||||
<193 IRQ_TYPE_NONE>,
|
#interrupt-cells = <2>;
|
||||||
<194 IRQ_TYPE_NONE>,
|
|
||||||
<195 IRQ_TYPE_NONE>,
|
|
||||||
<196 IRQ_TYPE_NONE>,
|
|
||||||
<197 IRQ_TYPE_NONE>,
|
|
||||||
<198 IRQ_TYPE_NONE>,
|
|
||||||
<199 IRQ_TYPE_NONE>,
|
|
||||||
<200 IRQ_TYPE_NONE>,
|
|
||||||
<201 IRQ_TYPE_NONE>,
|
|
||||||
<202 IRQ_TYPE_NONE>,
|
|
||||||
<203 IRQ_TYPE_NONE>,
|
|
||||||
<204 IRQ_TYPE_NONE>,
|
|
||||||
<205 IRQ_TYPE_NONE>,
|
|
||||||
<206 IRQ_TYPE_NONE>,
|
|
||||||
<207 IRQ_TYPE_NONE>,
|
|
||||||
<208 IRQ_TYPE_NONE>,
|
|
||||||
<209 IRQ_TYPE_NONE>,
|
|
||||||
<210 IRQ_TYPE_NONE>,
|
|
||||||
<211 IRQ_TYPE_NONE>,
|
|
||||||
<212 IRQ_TYPE_NONE>,
|
|
||||||
<213 IRQ_TYPE_NONE>,
|
|
||||||
<214 IRQ_TYPE_NONE>,
|
|
||||||
<215 IRQ_TYPE_NONE>,
|
|
||||||
<216 IRQ_TYPE_NONE>,
|
|
||||||
<217 IRQ_TYPE_NONE>,
|
|
||||||
<218 IRQ_TYPE_NONE>,
|
|
||||||
<219 IRQ_TYPE_NONE>,
|
|
||||||
<220 IRQ_TYPE_NONE>,
|
|
||||||
<221 IRQ_TYPE_NONE>,
|
|
||||||
<222 IRQ_TYPE_NONE>,
|
|
||||||
<223 IRQ_TYPE_NONE>,
|
|
||||||
<224 IRQ_TYPE_NONE>,
|
|
||||||
<225 IRQ_TYPE_NONE>,
|
|
||||||
<226 IRQ_TYPE_NONE>,
|
|
||||||
<227 IRQ_TYPE_NONE>,
|
|
||||||
<228 IRQ_TYPE_NONE>,
|
|
||||||
<229 IRQ_TYPE_NONE>,
|
|
||||||
<230 IRQ_TYPE_NONE>,
|
|
||||||
<231 IRQ_TYPE_NONE>,
|
|
||||||
<232 IRQ_TYPE_NONE>,
|
|
||||||
<233 IRQ_TYPE_NONE>,
|
|
||||||
<234 IRQ_TYPE_NONE>,
|
|
||||||
<235 IRQ_TYPE_NONE>;
|
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <2>;
|
#gpio-cells = <2>;
|
||||||
|
|
||||||
|
|
|
@ -323,13 +323,8 @@
|
||||||
|
|
||||||
pmicgpio: gpio@150 {
|
pmicgpio: gpio@150 {
|
||||||
compatible = "qcom,pm8018-gpio", "qcom,ssbi-gpio";
|
compatible = "qcom,pm8018-gpio", "qcom,ssbi-gpio";
|
||||||
interrupt-parent = <&pmicintc>;
|
interrupt-controller;
|
||||||
interrupts = <24 IRQ_TYPE_NONE>,
|
#interrupt-cells = <2>;
|
||||||
<25 IRQ_TYPE_NONE>,
|
|
||||||
<26 IRQ_TYPE_NONE>,
|
|
||||||
<27 IRQ_TYPE_NONE>,
|
|
||||||
<28 IRQ_TYPE_NONE>,
|
|
||||||
<29 IRQ_TYPE_NONE>;
|
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <2>;
|
#gpio-cells = <2>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -285,51 +285,8 @@
|
||||||
compatible = "qcom,pm8058-gpio",
|
compatible = "qcom,pm8058-gpio",
|
||||||
"qcom,ssbi-gpio";
|
"qcom,ssbi-gpio";
|
||||||
reg = <0x150>;
|
reg = <0x150>;
|
||||||
interrupt-parent = <&pm8058>;
|
interrupt-controller;
|
||||||
interrupts = <192 IRQ_TYPE_NONE>,
|
#interrupt-cells = <2>;
|
||||||
<193 IRQ_TYPE_NONE>,
|
|
||||||
<194 IRQ_TYPE_NONE>,
|
|
||||||
<195 IRQ_TYPE_NONE>,
|
|
||||||
<196 IRQ_TYPE_NONE>,
|
|
||||||
<197 IRQ_TYPE_NONE>,
|
|
||||||
<198 IRQ_TYPE_NONE>,
|
|
||||||
<199 IRQ_TYPE_NONE>,
|
|
||||||
<200 IRQ_TYPE_NONE>,
|
|
||||||
<201 IRQ_TYPE_NONE>,
|
|
||||||
<202 IRQ_TYPE_NONE>,
|
|
||||||
<203 IRQ_TYPE_NONE>,
|
|
||||||
<204 IRQ_TYPE_NONE>,
|
|
||||||
<205 IRQ_TYPE_NONE>,
|
|
||||||
<206 IRQ_TYPE_NONE>,
|
|
||||||
<207 IRQ_TYPE_NONE>,
|
|
||||||
<208 IRQ_TYPE_NONE>,
|
|
||||||
<209 IRQ_TYPE_NONE>,
|
|
||||||
<210 IRQ_TYPE_NONE>,
|
|
||||||
<211 IRQ_TYPE_NONE>,
|
|
||||||
<212 IRQ_TYPE_NONE>,
|
|
||||||
<213 IRQ_TYPE_NONE>,
|
|
||||||
<214 IRQ_TYPE_NONE>,
|
|
||||||
<215 IRQ_TYPE_NONE>,
|
|
||||||
<216 IRQ_TYPE_NONE>,
|
|
||||||
<217 IRQ_TYPE_NONE>,
|
|
||||||
<218 IRQ_TYPE_NONE>,
|
|
||||||
<219 IRQ_TYPE_NONE>,
|
|
||||||
<220 IRQ_TYPE_NONE>,
|
|
||||||
<221 IRQ_TYPE_NONE>,
|
|
||||||
<222 IRQ_TYPE_NONE>,
|
|
||||||
<223 IRQ_TYPE_NONE>,
|
|
||||||
<224 IRQ_TYPE_NONE>,
|
|
||||||
<225 IRQ_TYPE_NONE>,
|
|
||||||
<226 IRQ_TYPE_NONE>,
|
|
||||||
<227 IRQ_TYPE_NONE>,
|
|
||||||
<228 IRQ_TYPE_NONE>,
|
|
||||||
<229 IRQ_TYPE_NONE>,
|
|
||||||
<230 IRQ_TYPE_NONE>,
|
|
||||||
<231 IRQ_TYPE_NONE>,
|
|
||||||
<232 IRQ_TYPE_NONE>,
|
|
||||||
<233 IRQ_TYPE_NONE>,
|
|
||||||
<234 IRQ_TYPE_NONE>,
|
|
||||||
<235 IRQ_TYPE_NONE>;
|
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <2>;
|
#gpio-cells = <2>;
|
||||||
|
|
||||||
|
|
|
@ -928,7 +928,7 @@ config UCB1400_CORE
|
||||||
config MFD_PM8XXX
|
config MFD_PM8XXX
|
||||||
tristate "Qualcomm PM8xxx PMIC chips driver"
|
tristate "Qualcomm PM8xxx PMIC chips driver"
|
||||||
depends on (ARM || HEXAGON || COMPILE_TEST)
|
depends on (ARM || HEXAGON || COMPILE_TEST)
|
||||||
select IRQ_DOMAIN
|
select IRQ_DOMAIN_HIERARCHY
|
||||||
select MFD_CORE
|
select MFD_CORE
|
||||||
select REGMAP
|
select REGMAP
|
||||||
help
|
help
|
||||||
|
|
|
@ -70,22 +70,23 @@
|
||||||
#define PM8XXX_NR_IRQS 256
|
#define PM8XXX_NR_IRQS 256
|
||||||
#define PM8821_NR_IRQS 112
|
#define PM8821_NR_IRQS 112
|
||||||
|
|
||||||
|
struct pm_irq_data {
|
||||||
|
int num_irqs;
|
||||||
|
struct irq_chip *irq_chip;
|
||||||
|
void (*irq_handler)(struct irq_desc *desc);
|
||||||
|
};
|
||||||
|
|
||||||
struct pm_irq_chip {
|
struct pm_irq_chip {
|
||||||
struct regmap *regmap;
|
struct regmap *regmap;
|
||||||
spinlock_t pm_irq_lock;
|
spinlock_t pm_irq_lock;
|
||||||
struct irq_domain *irqdomain;
|
struct irq_domain *irqdomain;
|
||||||
unsigned int num_irqs;
|
|
||||||
unsigned int num_blocks;
|
unsigned int num_blocks;
|
||||||
unsigned int num_masters;
|
unsigned int num_masters;
|
||||||
|
const struct pm_irq_data *pm_irq_data;
|
||||||
|
/* MUST BE AT THE END OF THIS STRUCT */
|
||||||
u8 config[0];
|
u8 config[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pm_irq_data {
|
|
||||||
int num_irqs;
|
|
||||||
const struct irq_domain_ops *irq_domain_ops;
|
|
||||||
void (*irq_handler)(struct irq_desc *desc);
|
|
||||||
};
|
|
||||||
|
|
||||||
static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, unsigned int bp,
|
static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, unsigned int bp,
|
||||||
unsigned int *ip)
|
unsigned int *ip)
|
||||||
{
|
{
|
||||||
|
@ -375,21 +376,38 @@ static struct irq_chip pm8xxx_irq_chip = {
|
||||||
.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
|
.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int pm8xxx_irq_domain_map(struct irq_domain *d, unsigned int irq,
|
static void pm8xxx_irq_domain_map(struct pm_irq_chip *chip,
|
||||||
irq_hw_number_t hwirq)
|
struct irq_domain *domain, unsigned int irq,
|
||||||
|
irq_hw_number_t hwirq, unsigned int type)
|
||||||
{
|
{
|
||||||
struct pm_irq_chip *chip = d->host_data;
|
irq_domain_set_info(domain, irq, hwirq, chip->pm_irq_data->irq_chip,
|
||||||
|
chip, handle_level_irq, NULL, NULL);
|
||||||
irq_set_chip_and_handler(irq, &pm8xxx_irq_chip, handle_level_irq);
|
|
||||||
irq_set_chip_data(irq, chip);
|
|
||||||
irq_set_noprobe(irq);
|
irq_set_noprobe(irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pm8xxx_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
|
||||||
|
unsigned int nr_irqs, void *data)
|
||||||
|
{
|
||||||
|
struct pm_irq_chip *chip = domain->host_data;
|
||||||
|
struct irq_fwspec *fwspec = data;
|
||||||
|
irq_hw_number_t hwirq;
|
||||||
|
unsigned int type;
|
||||||
|
int ret, i;
|
||||||
|
|
||||||
|
ret = irq_domain_translate_twocell(domain, fwspec, &hwirq, &type);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
for (i = 0; i < nr_irqs; i++)
|
||||||
|
pm8xxx_irq_domain_map(chip, domain, virq + i, hwirq + i, type);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct irq_domain_ops pm8xxx_irq_domain_ops = {
|
static const struct irq_domain_ops pm8xxx_irq_domain_ops = {
|
||||||
.xlate = irq_domain_xlate_twocell,
|
.alloc = pm8xxx_irq_domain_alloc,
|
||||||
.map = pm8xxx_irq_domain_map,
|
.free = irq_domain_free_irqs_common,
|
||||||
|
.translate = irq_domain_translate_twocell,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pm8821_irq_mask_ack(struct irq_data *d)
|
static void pm8821_irq_mask_ack(struct irq_data *d)
|
||||||
|
@ -473,23 +491,6 @@ static struct irq_chip pm8821_irq_chip = {
|
||||||
.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
|
.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int pm8821_irq_domain_map(struct irq_domain *d, unsigned int irq,
|
|
||||||
irq_hw_number_t hwirq)
|
|
||||||
{
|
|
||||||
struct pm_irq_chip *chip = d->host_data;
|
|
||||||
|
|
||||||
irq_set_chip_and_handler(irq, &pm8821_irq_chip, handle_level_irq);
|
|
||||||
irq_set_chip_data(irq, chip);
|
|
||||||
irq_set_noprobe(irq);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct irq_domain_ops pm8821_irq_domain_ops = {
|
|
||||||
.xlate = irq_domain_xlate_twocell,
|
|
||||||
.map = pm8821_irq_domain_map,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct regmap_config ssbi_regmap_config = {
|
static const struct regmap_config ssbi_regmap_config = {
|
||||||
.reg_bits = 16,
|
.reg_bits = 16,
|
||||||
.val_bits = 8,
|
.val_bits = 8,
|
||||||
|
@ -501,13 +502,13 @@ static const struct regmap_config ssbi_regmap_config = {
|
||||||
|
|
||||||
static const struct pm_irq_data pm8xxx_data = {
|
static const struct pm_irq_data pm8xxx_data = {
|
||||||
.num_irqs = PM8XXX_NR_IRQS,
|
.num_irqs = PM8XXX_NR_IRQS,
|
||||||
.irq_domain_ops = &pm8xxx_irq_domain_ops,
|
.irq_chip = &pm8xxx_irq_chip,
|
||||||
.irq_handler = pm8xxx_irq_handler,
|
.irq_handler = pm8xxx_irq_handler,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pm_irq_data pm8821_data = {
|
static const struct pm_irq_data pm8821_data = {
|
||||||
.num_irqs = PM8821_NR_IRQS,
|
.num_irqs = PM8821_NR_IRQS,
|
||||||
.irq_domain_ops = &pm8821_irq_domain_ops,
|
.irq_chip = &pm8821_irq_chip,
|
||||||
.irq_handler = pm8821_irq_handler,
|
.irq_handler = pm8821_irq_handler,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -571,14 +572,14 @@ static int pm8xxx_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
platform_set_drvdata(pdev, chip);
|
platform_set_drvdata(pdev, chip);
|
||||||
chip->regmap = regmap;
|
chip->regmap = regmap;
|
||||||
chip->num_irqs = data->num_irqs;
|
chip->num_blocks = DIV_ROUND_UP(data->num_irqs, 8);
|
||||||
chip->num_blocks = DIV_ROUND_UP(chip->num_irqs, 8);
|
|
||||||
chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8);
|
chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8);
|
||||||
|
chip->pm_irq_data = data;
|
||||||
spin_lock_init(&chip->pm_irq_lock);
|
spin_lock_init(&chip->pm_irq_lock);
|
||||||
|
|
||||||
chip->irqdomain = irq_domain_add_linear(pdev->dev.of_node,
|
chip->irqdomain = irq_domain_add_linear(pdev->dev.of_node,
|
||||||
data->num_irqs,
|
data->num_irqs,
|
||||||
data->irq_domain_ops,
|
&pm8xxx_irq_domain_ops,
|
||||||
chip);
|
chip);
|
||||||
if (!chip->irqdomain)
|
if (!chip->irqdomain)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
|
@ -150,6 +150,7 @@ config PINCTRL_QCOM_SSBI_PMIC
|
||||||
select PINMUX
|
select PINMUX
|
||||||
select PINCONF
|
select PINCONF
|
||||||
select GENERIC_PINCONF
|
select GENERIC_PINCONF
|
||||||
|
select IRQ_DOMAIN_HIERARCHY
|
||||||
help
|
help
|
||||||
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
|
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
|
||||||
Qualcomm GPIO and MPP blocks found in the Qualcomm PMIC's chips,
|
Qualcomm GPIO and MPP blocks found in the Qualcomm PMIC's chips,
|
||||||
|
|
|
@ -55,6 +55,8 @@
|
||||||
|
|
||||||
#define PM8XXX_MAX_GPIOS 44
|
#define PM8XXX_MAX_GPIOS 44
|
||||||
|
|
||||||
|
#define PM8XXX_GPIO_PHYSICAL_OFFSET 1
|
||||||
|
|
||||||
/* custom pinconf parameters */
|
/* custom pinconf parameters */
|
||||||
#define PM8XXX_QCOM_DRIVE_STRENGH (PIN_CONFIG_END + 1)
|
#define PM8XXX_QCOM_DRIVE_STRENGH (PIN_CONFIG_END + 1)
|
||||||
#define PM8XXX_QCOM_PULL_UP_STRENGTH (PIN_CONFIG_END + 2)
|
#define PM8XXX_QCOM_PULL_UP_STRENGTH (PIN_CONFIG_END + 2)
|
||||||
|
@ -99,6 +101,9 @@ struct pm8xxx_gpio {
|
||||||
|
|
||||||
struct pinctrl_desc desc;
|
struct pinctrl_desc desc;
|
||||||
unsigned npins;
|
unsigned npins;
|
||||||
|
|
||||||
|
struct fwnode_handle *fwnode;
|
||||||
|
struct irq_domain *domain;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pinconf_generic_params pm8xxx_gpio_bindings[] = {
|
static const struct pinconf_generic_params pm8xxx_gpio_bindings[] = {
|
||||||
|
@ -499,11 +504,12 @@ static int pm8xxx_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||||
|
|
||||||
if (pin->mode == PM8XXX_GPIO_MODE_OUTPUT) {
|
if (pin->mode == PM8XXX_GPIO_MODE_OUTPUT) {
|
||||||
ret = pin->output_value;
|
ret = pin->output_value;
|
||||||
} else {
|
} else if (pin->irq >= 0) {
|
||||||
ret = irq_get_irqchip_state(pin->irq, IRQCHIP_STATE_LINE_LEVEL, &state);
|
ret = irq_get_irqchip_state(pin->irq, IRQCHIP_STATE_LINE_LEVEL, &state);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = !!state;
|
ret = !!state;
|
||||||
}
|
} else
|
||||||
|
ret = -EINVAL;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -533,7 +539,7 @@ static int pm8xxx_gpio_of_xlate(struct gpio_chip *chip,
|
||||||
if (flags)
|
if (flags)
|
||||||
*flags = gpio_desc->args[1];
|
*flags = gpio_desc->args[1];
|
||||||
|
|
||||||
return gpio_desc->args[0] - 1;
|
return gpio_desc->args[0] - PM8XXX_GPIO_PHYSICAL_OFFSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -541,8 +547,31 @@ static int pm8xxx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
|
||||||
{
|
{
|
||||||
struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);
|
struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);
|
||||||
struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
|
struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
|
||||||
|
struct irq_fwspec fwspec;
|
||||||
|
int ret;
|
||||||
|
|
||||||
return pin->irq;
|
fwspec.fwnode = pctrl->fwnode;
|
||||||
|
fwspec.param_count = 2;
|
||||||
|
fwspec.param[0] = offset + PM8XXX_GPIO_PHYSICAL_OFFSET;
|
||||||
|
fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
|
||||||
|
|
||||||
|
ret = irq_create_fwspec_mapping(&fwspec);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cache the IRQ since pm8xxx_gpio_get() needs this to get determine the
|
||||||
|
* line level.
|
||||||
|
*/
|
||||||
|
pin->irq = ret;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pm8xxx_gpio_free(struct gpio_chip *chip, unsigned int offset)
|
||||||
|
{
|
||||||
|
struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);
|
||||||
|
struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
|
||||||
|
|
||||||
|
pin->irq = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
|
@ -571,7 +600,7 @@ static void pm8xxx_gpio_dbg_show_one(struct seq_file *s,
|
||||||
"no", "high", "medium", "low"
|
"no", "high", "medium", "low"
|
||||||
};
|
};
|
||||||
|
|
||||||
seq_printf(s, " gpio%-2d:", offset + 1);
|
seq_printf(s, " gpio%-2d:", offset + PM8XXX_GPIO_PHYSICAL_OFFSET);
|
||||||
if (pin->disable) {
|
if (pin->disable) {
|
||||||
seq_puts(s, " ---");
|
seq_puts(s, " ---");
|
||||||
} else {
|
} else {
|
||||||
|
@ -603,6 +632,7 @@ static void pm8xxx_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const struct gpio_chip pm8xxx_gpio_template = {
|
static const struct gpio_chip pm8xxx_gpio_template = {
|
||||||
|
.free = pm8xxx_gpio_free,
|
||||||
.direction_input = pm8xxx_gpio_direction_input,
|
.direction_input = pm8xxx_gpio_direction_input,
|
||||||
.direction_output = pm8xxx_gpio_direction_output,
|
.direction_output = pm8xxx_gpio_direction_output,
|
||||||
.get = pm8xxx_gpio_get,
|
.get = pm8xxx_gpio_get,
|
||||||
|
@ -664,13 +694,75 @@ static int pm8xxx_pin_populate(struct pm8xxx_gpio *pctrl,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct irq_chip pm8xxx_irq_chip = {
|
||||||
|
.name = "ssbi-gpio",
|
||||||
|
.irq_mask_ack = irq_chip_mask_ack_parent,
|
||||||
|
.irq_unmask = irq_chip_unmask_parent,
|
||||||
|
.irq_set_type = irq_chip_set_type_parent,
|
||||||
|
.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int pm8xxx_domain_translate(struct irq_domain *domain,
|
||||||
|
struct irq_fwspec *fwspec,
|
||||||
|
unsigned long *hwirq,
|
||||||
|
unsigned int *type)
|
||||||
|
{
|
||||||
|
struct pm8xxx_gpio *pctrl = container_of(domain->host_data,
|
||||||
|
struct pm8xxx_gpio, chip);
|
||||||
|
|
||||||
|
if (fwspec->param_count != 2 || fwspec->param[0] < 1 ||
|
||||||
|
fwspec->param[0] > pctrl->chip.ngpio)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
*hwirq = fwspec->param[0] - PM8XXX_GPIO_PHYSICAL_OFFSET;
|
||||||
|
*type = fwspec->param[1];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pm8xxx_domain_alloc(struct irq_domain *domain, unsigned int virq,
|
||||||
|
unsigned int nr_irqs, void *data)
|
||||||
|
{
|
||||||
|
struct pm8xxx_gpio *pctrl = container_of(domain->host_data,
|
||||||
|
struct pm8xxx_gpio, chip);
|
||||||
|
struct irq_fwspec *fwspec = data;
|
||||||
|
struct irq_fwspec parent_fwspec;
|
||||||
|
irq_hw_number_t hwirq;
|
||||||
|
unsigned int type;
|
||||||
|
int ret, i;
|
||||||
|
|
||||||
|
ret = pm8xxx_domain_translate(domain, fwspec, &hwirq, &type);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
for (i = 0; i < nr_irqs; i++)
|
||||||
|
irq_domain_set_info(domain, virq + i, hwirq + i,
|
||||||
|
&pm8xxx_irq_chip, pctrl, handle_level_irq,
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
|
parent_fwspec.fwnode = domain->parent->fwnode;
|
||||||
|
parent_fwspec.param_count = 2;
|
||||||
|
parent_fwspec.param[0] = hwirq + 0xc0;
|
||||||
|
parent_fwspec.param[1] = fwspec->param[1];
|
||||||
|
|
||||||
|
return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
|
||||||
|
&parent_fwspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct irq_domain_ops pm8xxx_domain_ops = {
|
||||||
|
.activate = gpiochip_irq_domain_activate,
|
||||||
|
.alloc = pm8xxx_domain_alloc,
|
||||||
|
.deactivate = gpiochip_irq_domain_deactivate,
|
||||||
|
.free = irq_domain_free_irqs_common,
|
||||||
|
.translate = pm8xxx_domain_translate,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct of_device_id pm8xxx_gpio_of_match[] = {
|
static const struct of_device_id pm8xxx_gpio_of_match[] = {
|
||||||
{ .compatible = "qcom,pm8018-gpio" },
|
{ .compatible = "qcom,pm8018-gpio", .data = (void *) 6 },
|
||||||
{ .compatible = "qcom,pm8038-gpio" },
|
{ .compatible = "qcom,pm8038-gpio", .data = (void *) 12 },
|
||||||
{ .compatible = "qcom,pm8058-gpio" },
|
{ .compatible = "qcom,pm8058-gpio", .data = (void *) 44 },
|
||||||
{ .compatible = "qcom,pm8917-gpio" },
|
{ .compatible = "qcom,pm8917-gpio", .data = (void *) 38 },
|
||||||
{ .compatible = "qcom,pm8921-gpio" },
|
{ .compatible = "qcom,pm8921-gpio", .data = (void *) 44 },
|
||||||
{ .compatible = "qcom,ssbi-gpio" },
|
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, pm8xxx_gpio_of_match);
|
MODULE_DEVICE_TABLE(of, pm8xxx_gpio_of_match);
|
||||||
|
@ -678,22 +770,18 @@ MODULE_DEVICE_TABLE(of, pm8xxx_gpio_of_match);
|
||||||
static int pm8xxx_gpio_probe(struct platform_device *pdev)
|
static int pm8xxx_gpio_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct pm8xxx_pin_data *pin_data;
|
struct pm8xxx_pin_data *pin_data;
|
||||||
|
struct irq_domain *parent_domain;
|
||||||
|
struct device_node *parent_node;
|
||||||
struct pinctrl_pin_desc *pins;
|
struct pinctrl_pin_desc *pins;
|
||||||
struct pm8xxx_gpio *pctrl;
|
struct pm8xxx_gpio *pctrl;
|
||||||
int ret;
|
int ret, i;
|
||||||
int i, npins;
|
|
||||||
|
|
||||||
pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
|
pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
|
||||||
if (!pctrl)
|
if (!pctrl)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
pctrl->dev = &pdev->dev;
|
pctrl->dev = &pdev->dev;
|
||||||
npins = platform_irq_count(pdev);
|
pctrl->npins = (uintptr_t) device_get_match_data(&pdev->dev);
|
||||||
if (!npins)
|
|
||||||
return -EINVAL;
|
|
||||||
if (npins < 0)
|
|
||||||
return npins;
|
|
||||||
pctrl->npins = npins;
|
|
||||||
|
|
||||||
pctrl->regmap = dev_get_regmap(pdev->dev.parent, NULL);
|
pctrl->regmap = dev_get_regmap(pdev->dev.parent, NULL);
|
||||||
if (!pctrl->regmap) {
|
if (!pctrl->regmap) {
|
||||||
|
@ -720,12 +808,7 @@ static int pm8xxx_gpio_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
for (i = 0; i < pctrl->desc.npins; i++) {
|
for (i = 0; i < pctrl->desc.npins; i++) {
|
||||||
pin_data[i].reg = SSBI_REG_ADDR_GPIO(i);
|
pin_data[i].reg = SSBI_REG_ADDR_GPIO(i);
|
||||||
pin_data[i].irq = platform_get_irq(pdev, i);
|
pin_data[i].irq = -1;
|
||||||
if (pin_data[i].irq < 0) {
|
|
||||||
dev_err(&pdev->dev,
|
|
||||||
"missing interrupts for pin %d\n", i);
|
|
||||||
return pin_data[i].irq;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = pm8xxx_pin_populate(pctrl, &pin_data[i]);
|
ret = pm8xxx_pin_populate(pctrl, &pin_data[i]);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -756,10 +839,29 @@ static int pm8xxx_gpio_probe(struct platform_device *pdev)
|
||||||
pctrl->chip.of_gpio_n_cells = 2;
|
pctrl->chip.of_gpio_n_cells = 2;
|
||||||
pctrl->chip.label = dev_name(pctrl->dev);
|
pctrl->chip.label = dev_name(pctrl->dev);
|
||||||
pctrl->chip.ngpio = pctrl->npins;
|
pctrl->chip.ngpio = pctrl->npins;
|
||||||
|
|
||||||
|
parent_node = of_irq_find_parent(pctrl->dev->of_node);
|
||||||
|
if (!parent_node)
|
||||||
|
return -ENXIO;
|
||||||
|
|
||||||
|
parent_domain = irq_find_host(parent_node);
|
||||||
|
of_node_put(parent_node);
|
||||||
|
if (!parent_domain)
|
||||||
|
return -ENXIO;
|
||||||
|
|
||||||
|
pctrl->fwnode = of_node_to_fwnode(pctrl->dev->of_node);
|
||||||
|
pctrl->domain = irq_domain_create_hierarchy(parent_domain, 0,
|
||||||
|
pctrl->chip.ngpio,
|
||||||
|
pctrl->fwnode,
|
||||||
|
&pm8xxx_domain_ops,
|
||||||
|
&pctrl->chip);
|
||||||
|
if (!pctrl->domain)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
ret = gpiochip_add_data(&pctrl->chip, pctrl);
|
ret = gpiochip_add_data(&pctrl->chip, pctrl);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "failed register gpiochip\n");
|
dev_err(&pdev->dev, "failed register gpiochip\n");
|
||||||
return ret;
|
goto err_chip_add_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -789,6 +891,8 @@ static int pm8xxx_gpio_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
unregister_gpiochip:
|
unregister_gpiochip:
|
||||||
gpiochip_remove(&pctrl->chip);
|
gpiochip_remove(&pctrl->chip);
|
||||||
|
err_chip_add_data:
|
||||||
|
irq_domain_remove(pctrl->domain);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -798,6 +902,7 @@ static int pm8xxx_gpio_remove(struct platform_device *pdev)
|
||||||
struct pm8xxx_gpio *pctrl = platform_get_drvdata(pdev);
|
struct pm8xxx_gpio *pctrl = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
gpiochip_remove(&pctrl->chip);
|
gpiochip_remove(&pctrl->chip);
|
||||||
|
irq_domain_remove(pctrl->domain);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -605,6 +605,7 @@ extern void irq_chip_disable_parent(struct irq_data *data);
|
||||||
extern void irq_chip_ack_parent(struct irq_data *data);
|
extern void irq_chip_ack_parent(struct irq_data *data);
|
||||||
extern int irq_chip_retrigger_hierarchy(struct irq_data *data);
|
extern int irq_chip_retrigger_hierarchy(struct irq_data *data);
|
||||||
extern void irq_chip_mask_parent(struct irq_data *data);
|
extern void irq_chip_mask_parent(struct irq_data *data);
|
||||||
|
extern void irq_chip_mask_ack_parent(struct irq_data *data);
|
||||||
extern void irq_chip_unmask_parent(struct irq_data *data);
|
extern void irq_chip_unmask_parent(struct irq_data *data);
|
||||||
extern void irq_chip_eoi_parent(struct irq_data *data);
|
extern void irq_chip_eoi_parent(struct irq_data *data);
|
||||||
extern int irq_chip_set_affinity_parent(struct irq_data *data,
|
extern int irq_chip_set_affinity_parent(struct irq_data *data,
|
||||||
|
|
|
@ -419,6 +419,11 @@ int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
|
||||||
const u32 *intspec, unsigned int intsize,
|
const u32 *intspec, unsigned int intsize,
|
||||||
irq_hw_number_t *out_hwirq, unsigned int *out_type);
|
irq_hw_number_t *out_hwirq, unsigned int *out_type);
|
||||||
|
|
||||||
|
int irq_domain_translate_twocell(struct irq_domain *d,
|
||||||
|
struct irq_fwspec *fwspec,
|
||||||
|
unsigned long *out_hwirq,
|
||||||
|
unsigned int *out_type);
|
||||||
|
|
||||||
/* IPI functions */
|
/* IPI functions */
|
||||||
int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest);
|
int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest);
|
||||||
int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest);
|
int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest);
|
||||||
|
|
|
@ -1277,6 +1277,17 @@ void irq_chip_mask_parent(struct irq_data *data)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(irq_chip_mask_parent);
|
EXPORT_SYMBOL_GPL(irq_chip_mask_parent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* irq_chip_mask_ack_parent - Mask and acknowledge the parent interrupt
|
||||||
|
* @data: Pointer to interrupt specific data
|
||||||
|
*/
|
||||||
|
void irq_chip_mask_ack_parent(struct irq_data *data)
|
||||||
|
{
|
||||||
|
data = data->parent_data;
|
||||||
|
data->chip->irq_mask_ack(data);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(irq_chip_mask_ack_parent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* irq_chip_unmask_parent - Unmask the parent interrupt
|
* irq_chip_unmask_parent - Unmask the parent interrupt
|
||||||
* @data: Pointer to interrupt specific data
|
* @data: Pointer to interrupt specific data
|
||||||
|
|
|
@ -729,16 +729,17 @@ static int irq_domain_translate(struct irq_domain *d,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void of_phandle_args_to_fwspec(struct of_phandle_args *irq_data,
|
static void of_phandle_args_to_fwspec(struct device_node *np, const u32 *args,
|
||||||
|
unsigned int count,
|
||||||
struct irq_fwspec *fwspec)
|
struct irq_fwspec *fwspec)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
fwspec->fwnode = irq_data->np ? &irq_data->np->fwnode : NULL;
|
fwspec->fwnode = np ? &np->fwnode : NULL;
|
||||||
fwspec->param_count = irq_data->args_count;
|
fwspec->param_count = count;
|
||||||
|
|
||||||
for (i = 0; i < irq_data->args_count; i++)
|
for (i = 0; i < count; i++)
|
||||||
fwspec->param[i] = irq_data->args[i];
|
fwspec->param[i] = args[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec)
|
unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec)
|
||||||
|
@ -836,7 +837,9 @@ unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data)
|
||||||
{
|
{
|
||||||
struct irq_fwspec fwspec;
|
struct irq_fwspec fwspec;
|
||||||
|
|
||||||
of_phandle_args_to_fwspec(irq_data, &fwspec);
|
of_phandle_args_to_fwspec(irq_data->np, irq_data->args,
|
||||||
|
irq_data->args_count, &fwspec);
|
||||||
|
|
||||||
return irq_create_fwspec_mapping(&fwspec);
|
return irq_create_fwspec_mapping(&fwspec);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(irq_create_of_mapping);
|
EXPORT_SYMBOL_GPL(irq_create_of_mapping);
|
||||||
|
@ -928,11 +931,10 @@ int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
|
||||||
const u32 *intspec, unsigned int intsize,
|
const u32 *intspec, unsigned int intsize,
|
||||||
irq_hw_number_t *out_hwirq, unsigned int *out_type)
|
irq_hw_number_t *out_hwirq, unsigned int *out_type)
|
||||||
{
|
{
|
||||||
if (WARN_ON(intsize < 2))
|
struct irq_fwspec fwspec;
|
||||||
return -EINVAL;
|
|
||||||
*out_hwirq = intspec[0];
|
of_phandle_args_to_fwspec(ctrlr, intspec, intsize, &fwspec);
|
||||||
*out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
|
return irq_domain_translate_twocell(d, &fwspec, out_hwirq, out_type);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(irq_domain_xlate_twocell);
|
EXPORT_SYMBOL_GPL(irq_domain_xlate_twocell);
|
||||||
|
|
||||||
|
@ -968,6 +970,27 @@ const struct irq_domain_ops irq_domain_simple_ops = {
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
|
EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* irq_domain_translate_twocell() - Generic translate for direct two cell
|
||||||
|
* bindings
|
||||||
|
*
|
||||||
|
* Device Tree IRQ specifier translation function which works with two cell
|
||||||
|
* bindings where the cell values map directly to the hwirq number
|
||||||
|
* and linux irq flags.
|
||||||
|
*/
|
||||||
|
int irq_domain_translate_twocell(struct irq_domain *d,
|
||||||
|
struct irq_fwspec *fwspec,
|
||||||
|
unsigned long *out_hwirq,
|
||||||
|
unsigned int *out_type)
|
||||||
|
{
|
||||||
|
if (WARN_ON(fwspec->param_count < 2))
|
||||||
|
return -EINVAL;
|
||||||
|
*out_hwirq = fwspec->param[0];
|
||||||
|
*out_type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(irq_domain_translate_twocell);
|
||||||
|
|
||||||
int irq_domain_alloc_descs(int virq, unsigned int cnt, irq_hw_number_t hwirq,
|
int irq_domain_alloc_descs(int virq, unsigned int cnt, irq_hw_number_t hwirq,
|
||||||
int node, const struct irq_affinity_desc *affinity)
|
int node, const struct irq_affinity_desc *affinity)
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче