1313#include <linux/kernel.h>
1414#include <linux/module.h>
1515#include <linux/of.h>
16+ #include <linux/of_address.h>
1617#include <linux/of_irq.h>
1718#include <linux/platform_device.h>
1819#include <linux/slab.h>
@@ -95,6 +96,8 @@ enum pmic_arb_channel {
9596 PMIC_ARB_CHANNEL_OBS ,
9697};
9798
99+ #define PMIC_ARB_MAX_BUSES 2
100+
98101/* Maximum number of support PMIC peripherals */
99102#define PMIC_ARB_MAX_PERIPHS 512
100103#define PMIC_ARB_MAX_PERIPHS_V7 1024
@@ -149,6 +152,7 @@ struct spmi_pmic_arb;
149152 * @min_apid: minimum APID (used for bounding IRQ search)
150153 * @max_apid: maximum APID
151154 * @irq: PMIC ARB interrupt.
155+ * @id: unique ID of the bus
152156 */
153157struct spmi_pmic_arb_bus {
154158 struct spmi_pmic_arb * pmic_arb ;
@@ -167,6 +171,7 @@ struct spmi_pmic_arb_bus {
167171 u16 min_apid ;
168172 u16 max_apid ;
169173 int irq ;
174+ u8 id ;
170175};
171176
172177/**
@@ -180,7 +185,8 @@ struct spmi_pmic_arb_bus {
180185 * @ee: the current Execution Environment
181186 * @ver_ops: version dependent operations.
182187 * @max_periphs: Number of elements in apid_data[]
183- * @bus: per arbiter bus instance
188+ * @buses: per arbiter buses instances
189+ * @buses_available: number of buses registered
184190 */
185191struct spmi_pmic_arb {
186192 void __iomem * rd_base ;
@@ -191,7 +197,8 @@ struct spmi_pmic_arb {
191197 u8 ee ;
192198 const struct pmic_arb_ver_ops * ver_ops ;
193199 int max_periphs ;
194- struct spmi_pmic_arb_bus * bus ;
200+ struct spmi_pmic_arb_bus * buses [PMIC_ARB_MAX_BUSES ];
201+ int buses_available ;
195202};
196203
197204/**
@@ -220,7 +227,7 @@ struct spmi_pmic_arb {
220227struct pmic_arb_ver_ops {
221228 const char * ver_str ;
222229 int (* get_core_resources )(struct platform_device * pdev , void __iomem * core );
223- int (* init_apid )(struct spmi_pmic_arb_bus * bus );
230+ int (* init_apid )(struct spmi_pmic_arb_bus * bus , int index );
224231 int (* ppid_to_apid )(struct spmi_pmic_arb_bus * bus , u16 ppid );
225232 /* spmi commands (read_cmd, write_cmd, cmd) functionality */
226233 int (* offset )(struct spmi_pmic_arb_bus * bus , u8 sid , u16 addr ,
@@ -309,8 +316,8 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
309316 }
310317
311318 if (status & PMIC_ARB_STATUS_FAILURE ) {
312- dev_err (& ctrl -> dev , "%s: %#x %#x: transaction failed (%#x)\n" ,
313- __func__ , sid , addr , status );
319+ dev_err (& ctrl -> dev , "%s: %#x %#x: transaction failed (%#x) reg: 0x%x \n" ,
320+ __func__ , sid , addr , status , offset );
314321 WARN_ON (1 );
315322 return - EIO ;
316323 }
@@ -326,8 +333,8 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
326333 udelay (1 );
327334 }
328335
329- dev_err (& ctrl -> dev , "%s: %#x %#x: timeout, status %#x\n" ,
330- __func__ , sid , addr , status );
336+ dev_err (& ctrl -> dev , "%s: %#x %#x %#x : timeout, status %#x\n" ,
337+ __func__ , bus -> id , sid , addr , status );
331338 return - ETIMEDOUT ;
332339}
333340
@@ -1003,11 +1010,17 @@ static int pmic_arb_get_core_resources_v1(struct platform_device *pdev,
10031010 return 0 ;
10041011}
10051012
1006- static int pmic_arb_init_apid_v1 (struct spmi_pmic_arb_bus * bus )
1013+ static int pmic_arb_init_apid_v1 (struct spmi_pmic_arb_bus * bus , int index )
10071014{
10081015 struct spmi_pmic_arb * pmic_arb = bus -> pmic_arb ;
10091016 u32 * mapping_table ;
10101017
1018+ if (index ) {
1019+ dev_err (& bus -> spmic -> dev , "Unsupported buses count %d detected\n" ,
1020+ index );
1021+ return - EINVAL ;
1022+ }
1023+
10111024 mapping_table = devm_kcalloc (& bus -> spmic -> dev , pmic_arb -> max_periphs ,
10121025 sizeof (* mapping_table ), GFP_KERNEL );
10131026 if (!mapping_table )
@@ -1250,11 +1263,17 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
12501263 return 0x1000 * pmic_arb -> ee + 0x8000 * apid ;
12511264}
12521265
1253- static int pmic_arb_init_apid_v5 (struct spmi_pmic_arb_bus * bus )
1266+ static int pmic_arb_init_apid_v5 (struct spmi_pmic_arb_bus * bus , int index )
12541267{
12551268 struct spmi_pmic_arb * pmic_arb = bus -> pmic_arb ;
12561269 int ret ;
12571270
1271+ if (index ) {
1272+ dev_err (& bus -> spmic -> dev , "Unsupported buses count %d detected\n" ,
1273+ index );
1274+ return - EINVAL ;
1275+ }
1276+
12581277 bus -> base_apid = 0 ;
12591278 bus -> apid_count = readl_relaxed (pmic_arb -> core + PMIC_ARB_FEATURES ) &
12601279 PMIC_ARB_FEATURES_PERIPH_MASK ;
@@ -1326,6 +1345,50 @@ static int pmic_arb_get_core_resources_v7(struct platform_device *pdev,
13261345 return pmic_arb_get_obsrvr_chnls_v2 (pdev );
13271346}
13281347
1348+ /*
1349+ * Only v7 supports 2 buses. Each bus will get a different apid count, read
1350+ * from different registers.
1351+ */
1352+ static int pmic_arb_init_apid_v7 (struct spmi_pmic_arb_bus * bus , int index )
1353+ {
1354+ struct spmi_pmic_arb * pmic_arb = bus -> pmic_arb ;
1355+ int ret ;
1356+
1357+ if (index == 0 ) {
1358+ bus -> base_apid = 0 ;
1359+ bus -> apid_count = readl_relaxed (pmic_arb -> core + PMIC_ARB_FEATURES ) &
1360+ PMIC_ARB_FEATURES_PERIPH_MASK ;
1361+ } else if (index == 1 ) {
1362+ bus -> base_apid = readl_relaxed (pmic_arb -> core + PMIC_ARB_FEATURES ) &
1363+ PMIC_ARB_FEATURES_PERIPH_MASK ;
1364+ bus -> apid_count = readl_relaxed (pmic_arb -> core + PMIC_ARB_FEATURES1 ) &
1365+ PMIC_ARB_FEATURES_PERIPH_MASK ;
1366+ } else {
1367+ dev_err (& bus -> spmic -> dev , "Unsupported buses count %d detected\n" ,
1368+ bus -> id );
1369+ return - EINVAL ;
1370+ }
1371+
1372+ if (bus -> base_apid + bus -> apid_count > pmic_arb -> max_periphs ) {
1373+ dev_err (& bus -> spmic -> dev , "Unsupported APID count %d detected\n" ,
1374+ bus -> base_apid + bus -> apid_count );
1375+ return - EINVAL ;
1376+ }
1377+
1378+ ret = pmic_arb_init_apid_min_max (bus );
1379+ if (ret )
1380+ return ret ;
1381+
1382+ ret = pmic_arb_read_apid_map_v5 (bus );
1383+ if (ret ) {
1384+ dev_err (& bus -> spmic -> dev , "could not read APID->PPID mapping table, rc= %d\n" ,
1385+ ret );
1386+ return ret ;
1387+ }
1388+
1389+ return 0 ;
1390+ }
1391+
13291392/*
13301393 * v7 offset per ee and per apid for observer channels and per apid for
13311394 * read/write channels.
@@ -1578,7 +1641,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = {
15781641static const struct pmic_arb_ver_ops pmic_arb_v7 = {
15791642 .ver_str = "v7" ,
15801643 .get_core_resources = pmic_arb_get_core_resources_v7 ,
1581- .init_apid = pmic_arb_init_apid_v5 ,
1644+ .init_apid = pmic_arb_init_apid_v7 ,
15821645 .ppid_to_apid = pmic_arb_ppid_to_apid_v5 ,
15831646 .non_data_cmd = pmic_arb_non_data_cmd_v2 ,
15841647 .offset = pmic_arb_offset_v7 ,
@@ -1602,6 +1665,7 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev,
16021665 struct device_node * node ,
16031666 struct spmi_pmic_arb * pmic_arb )
16041667{
1668+ int bus_index = pmic_arb -> buses_available ;
16051669 struct spmi_pmic_arb_bus * bus ;
16061670 struct device * dev = & pdev -> dev ;
16071671 struct spmi_controller * ctrl ;
@@ -1620,7 +1684,7 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev,
16201684
16211685 bus = spmi_controller_get_drvdata (ctrl );
16221686
1623- pmic_arb -> bus = bus ;
1687+ pmic_arb -> buses [ bus_index ] = bus ;
16241688
16251689 raw_spin_lock_init (& bus -> lock );
16261690
@@ -1665,12 +1729,13 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev,
16651729 bus -> cnfg = cnfg ;
16661730 bus -> irq = irq ;
16671731 bus -> spmic = ctrl ;
1732+ bus -> id = bus_index ;
16681733
1669- ret = pmic_arb -> ver_ops -> init_apid (bus );
1734+ ret = pmic_arb -> ver_ops -> init_apid (bus , bus_index );
16701735 if (ret )
16711736 return ret ;
16721737
1673- dev_dbg (& pdev -> dev , "adding irq domain\n" );
1738+ dev_dbg (& pdev -> dev , "adding irq domain for bus %d \n" , bus_index );
16741739
16751740 bus -> domain = irq_domain_add_tree (dev -> of_node ,
16761741 & pmic_arb_irq_domain_ops , bus );
@@ -1683,14 +1748,53 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev,
16831748 pmic_arb_chained_irq , bus );
16841749
16851750 ctrl -> dev .of_node = node ;
1751+ dev_set_name (& ctrl -> dev , "spmi-%d" , bus_index );
16861752
16871753 ret = devm_spmi_controller_add (dev , ctrl );
16881754 if (ret )
16891755 return ret ;
16901756
1757+ pmic_arb -> buses_available ++ ;
1758+
16911759 return 0 ;
16921760}
16931761
1762+ static int spmi_pmic_arb_register_buses (struct spmi_pmic_arb * pmic_arb ,
1763+ struct platform_device * pdev )
1764+ {
1765+ struct device * dev = & pdev -> dev ;
1766+ struct device_node * node = dev -> of_node ;
1767+ struct device_node * child ;
1768+ int ret ;
1769+
1770+ /* legacy mode doesn't provide child node for the bus */
1771+ if (of_device_is_compatible (node , "qcom,spmi-pmic-arb" ))
1772+ return spmi_pmic_arb_bus_init (pdev , node , pmic_arb );
1773+
1774+ for_each_available_child_of_node (node , child ) {
1775+ if (of_node_name_eq (child , "spmi" )) {
1776+ ret = spmi_pmic_arb_bus_init (pdev , child , pmic_arb );
1777+ if (ret )
1778+ return ret ;
1779+ }
1780+ }
1781+
1782+ return ret ;
1783+ }
1784+
1785+ static void spmi_pmic_arb_deregister_buses (struct spmi_pmic_arb * pmic_arb )
1786+ {
1787+ int i ;
1788+
1789+ for (i = 0 ; i < pmic_arb -> buses_available ; i ++ ) {
1790+ struct spmi_pmic_arb_bus * bus = pmic_arb -> buses [i ];
1791+
1792+ irq_set_chained_handler_and_data (bus -> irq ,
1793+ NULL , NULL );
1794+ irq_domain_remove (bus -> domain );
1795+ }
1796+ }
1797+
16941798static int spmi_pmic_arb_probe (struct platform_device * pdev )
16951799{
16961800 struct spmi_pmic_arb * pmic_arb ;
@@ -1760,21 +1864,19 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
17601864
17611865 pmic_arb -> ee = ee ;
17621866
1763- return spmi_pmic_arb_bus_init ( pdev , dev -> of_node , pmic_arb );
1867+ return spmi_pmic_arb_register_buses ( pmic_arb , pdev );
17641868}
17651869
17661870static void spmi_pmic_arb_remove (struct platform_device * pdev )
17671871{
17681872 struct spmi_pmic_arb * pmic_arb = platform_get_drvdata (pdev );
1769- struct spmi_pmic_arb_bus * bus = pmic_arb -> bus ;
17701873
1771- irq_set_chained_handler_and_data (bus -> irq ,
1772- NULL , NULL );
1773- irq_domain_remove (bus -> domain );
1874+ spmi_pmic_arb_deregister_buses (pmic_arb );
17741875}
17751876
17761877static const struct of_device_id spmi_pmic_arb_match_table [] = {
17771878 { .compatible = "qcom,spmi-pmic-arb" , },
1879+ { .compatible = "qcom,x1e80100-spmi-pmic-arb" , },
17781880 {},
17791881};
17801882MODULE_DEVICE_TABLE (of , spmi_pmic_arb_match_table );
0 commit comments